Module 将公共块转换为模块

Module 将公共块转换为模块,module,fortran,fortran90,double-precision,fortran-common-block,Module,Fortran,Fortran90,Double Precision,Fortran Common Block,我是一名研究人员,使用Fortran编写的程序。我有非常基本的编码技能,所以我需要一些帮助来正确编译一些代码 在显示代码之前,我将提供一些背景知识。我正在处理大量数据,这将需要64位编译和大于2GB的内存。我在代码中注意到的第一件事是,许多变量都写为“实”,但在我的研究中,我发现“双精度”允许更大的变量,并且是一个更灵活的选择,因此我将所有“实”变量改为“双精度”变量 fortran编译文件“dist.f”中包含的一个文件名为“geocord.inc”。我发现变量被保存到一个公共块中,但再一次,

我是一名研究人员,使用Fortran编写的程序。我有非常基本的编码技能,所以我需要一些帮助来正确编译一些代码

在显示代码之前,我将提供一些背景知识。我正在处理大量数据,这将需要64位编译和大于2GB的内存。我在代码中注意到的第一件事是,许多变量都写为“实”,但在我的研究中,我发现“双精度”允许更大的变量,并且是一个更灵活的选择,因此我将所有“实”变量改为“双精度”变量

fortran编译文件“dist.f”中包含的一个文件名为“geocord.inc”。我发现变量被保存到一个公共块中,但再一次,我需要一些能够保存大量数据的东西。正如我被引导相信的那样,模块将是一个更好的程序。我需要一些建议,在转换这个包括文件,以正常工作的模块程序,我将列出下面

f区:

c Convert latitude and longitude to kilometers relative
c to center of coordinates by short distance conversion.

subroutine dist(xlat, xlon, xkm, ykm)

implicit none

c   Parameters:
double precision    xlat, xlon  ! (input)
double precision        xkm, ykm    ! (output)

c   Local variables:
double precision lat1, lat2, lat3
double precision    q
double precision    xx
double precision    yp

include "geocoord.inc"

c Set up short distance conversion by subr. SETORG
  q=60*xlat-olat
  yp=q+olat
  lat1=datan(rlatc*dtan(RAD*yp/60.0))
  lat2=datan(rlatc*dtan(RAD*OLAT/60.0))
  LAT3=(LAT2+LAT1)/2.
  xx=60*xlon-olon  !  - wegen LON E
  q=q*aa
  xx = xx*bb*dcos(LAT3)
  IF(rotate.ne.0.) then
c** rotate coordinate system anticlockwise
    yp=cost*q+sint*xx
    xx=cost*xx-sint*q
    q=yp
  ENDIF

  xkm=xx
  ykm=q

  return
  end
Geocoord.inc:

double precision rearth
double precision ellip
double precision rlatc
double precision rad
double precision olat, olon
double precision aa, bb, bc
double precision sint, cost
double precision rotate
integer icoordsystem

common /GEO_COORSYSTEM/ rearth, ellip, rlatc, rad,
&    olat, olon, aa, bb, bc, sint, cost, rotate,
&    icoordsystem

我非常感谢您提供的任何建议,并为我对所有Fortran语言的相对无知道歉

使旧代码现代化通常不是一件容易的任务。至少对初学者来说是这样。从
real
double-precision
的转变并不符合现代Fortran的精神,但在引入模块之前,这是可以的。当您有模块时,最好执行以下操作:

module precisions
  integer, parameter :: rp = kind(1.d0) !if you insist on double, otherwise use selected_real_kind()
end module
在任何地方都使用表示实际精度的新类型常数:

  use precisions

      real(rp) :: variables
对于公共块,您显示的是:

module geo_coordsystem
  use precisions

  implicit none

  real(rp) :: rearth
  real(rp) ::  ellip
  real(rp) ::  rlatc
  real(rp) ::  rad
  real(rp) ::  olat, olon
  real(rp) ::  aa, bb, bc
  real(rp) ::  sint, cost
  real(rp) ::  rotate
  integer icoordsystem

end module
然后你使用它:

subroutine dist(xlat, xlon, xkm, ykm)
  use precisions
  use geo_coordsystem

  implicit none

您还可以不断地将子例程移动到模块中。分小步进行,并始终检查没有引入错误。

使旧代码现代化通常不是一件容易的任务。至少对初学者来说是这样。从
real
double-precision
的转变并不符合现代Fortran的精神,但在引入模块之前,这是可以的。当您有模块时,最好执行以下操作:

module precisions
  integer, parameter :: rp = kind(1.d0) !if you insist on double, otherwise use selected_real_kind()
end module
在任何地方都使用表示实际精度的新类型常数:

  use precisions

      real(rp) :: variables
对于公共块,您显示的是:

module geo_coordsystem
  use precisions

  implicit none

  real(rp) :: rearth
  real(rp) ::  ellip
  real(rp) ::  rlatc
  real(rp) ::  rad
  real(rp) ::  olat, olon
  real(rp) ::  aa, bb, bc
  real(rp) ::  sint, cost
  real(rp) ::  rotate
  integer icoordsystem

end module
然后你使用它:

subroutine dist(xlat, xlon, xkm, ykm)
  use precisions
  use geo_coordsystem

  implicit none

您还可以不断地将子例程移动到模块中。分小步进行,并始终检查是否引入了一些错误。

一些Fortran编译器可以选择将实变量提升到双精度。在gfortran中,选项为-fdefault-real-8,如中所述。从长远来看,最好按照Vladimir F的建议使用种类。

一些Fortran编译器可以选择将实变量提升到双精度。在gfortran中,选项为-fdefault-real-8,如中所述。从长远来看,最好使用Vladimir F建议的种类。

建议在小步骤和测试中进行更改是非常明智的!您可能想要创建一组回归测试。建议在小步骤和测试中进行更改是非常明智的!您可能需要创建一组回归测试。