0

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

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

还有一个包含在 fortran 构建文件“dist.f”的编译中的文件,称为“geocoord.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 的所有事情的相对无知表示歉意!

4

2 回答 2

5

对旧代码进行现代化改造通常不是一件容易的事。至少对于初学者来说。从realto的转变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

您还可以不断地将子例程移动到模块中。以小步骤执行此操作,并始终检查您是否没有引入一些错误。

于 2014-05-05T21:11:30.763 回答
0

一些 Fortran 编译器可以选择将实变量提升为双精度。在 gfortran 中,选项是 -fdefault-real-8 ,如http://gcc.gnu.org/onlinedocs/gfortran/Fortran-Dialect-Options.html中所述。从长远来看,最好使用 Vladimir F 建议的种类。

于 2014-05-06T02:11:17.680 回答