在程序开始时进行系统计算/初始化的正确方法

Proper way of doing the systematic computations / initializations at the beginning of a program

我正在编写一个程序,我将在两个主要情况下使用:1D 和 2D。维度 ndim 是通过外部文件的 read 加载的,这个 read 我想在模块 param.

中做

我有各种大小取决于维度的向量声明。所以很明显,我必须在主程序开始时计算这些大小。这样做的正确方法是什么?我想使用一个模块,但我失败了。

module dimensions
  use prec
  use param
  implicit none
  integer ( int32 ), parameter :: nip = 49   ! Number of interior points
contains
subroutine calc_neqn ( )
  use prec
  implicit none
  integer ( int32 ) :: nup                   ! Number of unknown points
  integer ( int32 ) :: neqn                  ! Number of equations

! compute number of unknown points
  nup = (nip+2)**ndim
! compute number of equations
  neqn = 2*nup

end subroutine calc_neqn
! systematic computations
  call calc_neqn ( )
end module dimensions

我收到以下 - 非常清楚 - 错误消息:

Error: Unexpected CALL statement in CONTAINS section at (1)

也就是说,模块可以调用子程序吗?正确的语法是什么?

不,模块本身不能执行任何可执行代码。有些编程语言允许在使用模块时进行默认初始化,但 Fortran 不是其中之一。

您应该将初始化代码放在子例程中,并且您必须记住从主程序或其他一些过程中调用该子例程。

面向对象的方法是使用对象而不是模块,并在对象初始化程序中包含初始化代码。

如果您的 ndim 是一个参数,您可以在编译时计算常量精度。如果不是,您必须在自己获得 ndim 时调用 calc_neqn。然后你可以根据需要分配你的向量(你没有显示)。

模块无法自行执行代码

您可能想要做的是这样的事情:

module my_module
    implicit none
    integer :: ndims
    real, dimension(:), allocatable :: my_data
contains
    subroutine initialize()
        ndims = ...
        allocate(my_data(ndims))
    end subroutine initialize
end module my_module

program my_program
    use my_module
    implicit none
    call initialize()
    ....
end program my_program

这将为模块和主程序同时提供 ndim 变量和 my_data 数组。只要确保您没有在子例程中再次定义任何一个,因为那样只会在 initialize.

的范围内创建新变量