将通用块转换为模块

Jes*_*seH 0 fortran module double-precision fortran90 fortran-common-block

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

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

fortran构建文件“ dist.f”的编译中还包含一个文件,称为“ geocoord.inc”。我发现变量已保存到一个公共块中,但是再一次,我需要一些可以容纳大量数据的东西。正如我一直相信的那样,模块将是一个更好的程序。在转换此包含文件以使其与模块程序正常工作时,我需要一些建议,我将在下面列出。

Dist.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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

感谢您提供的任何建议,对于Fortran在所有方面的相对无知我深表歉意!

Vla*_*r F 5

现代化旧代码通常不是一件容易的事。至少对于初学者来说。从过渡realdouble precision不是现代Fortran的精神,但是在介绍模块之前,还可以。当您有模块时,最好这样做:

module precisions
  integer, parameter :: rp = kind(1.d0) !if you insist on double, otherwise use selected_real_kind()
end module
Run Code Online (Sandbox Code Playgroud)

到处都使用新的种类常量来表示您的实际精度:

  use precisions

      real(rp) :: variables
Run Code Online (Sandbox Code Playgroud)

使用常见的块,您显示的块将是:

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
Run Code Online (Sandbox Code Playgroud)

然后使用它:

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

  implicit none
Run Code Online (Sandbox Code Playgroud)

您也可以将子例程连续移动到模块中。一步一步做,并始终检查您没有引入一些错误。