将公共块转换为模块

时间:2014-05-05 20:29:17

标签: module fortran fortran90 double-precision 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

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所有事情上的相对无知而道歉!

2 个答案:

答案 0 :(得分:4)

现代化旧代码通常不是一件容易的事。至少对初学者来说。从realdouble 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

您还可以不断将子程序移动到模块。这样做很小,总是检查你没有引入一些错误。

答案 1 :(得分:0)

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