我有一个包含大量模型的计算机程序(Fortran)。这些模型在相关性中包含常数系数。目前,这些常数系数都是模型所在的例程的私有和局部。然而,我希望对这些相关系数中的许多进行敏感性研究,这意味着我需要能够从他们的默认通过用户输入。我还需要这种能力来改变这些参数,以便随着代码的进一步发展而保持最新状态。
最明显的解决方案是将所有这些参数打到自己的模块中,使它们全局化,然后创建一个例程来读取用户输入并相应地修改这些参数。但这绝对会破坏代码的模块性。包含依赖于这些参数的模型的所有例程将依赖于包含所有全局变量的那个模块。
另一个更加劳动密集的解决方案是创建" setter"每个模块中具有需要修改的模型参数的例程。参数在模块中保持私有,但可以通过可从我的灵敏度分析模块调用的setter例程进行修改。
还有什么我想念的吗?更优雅的解决方案?
答案 0 :(得分:1)
这很大程度上取决于程序的结构,但我喜欢的方法是使用带有默认参数的模块init / finalize子程序:
module paramcalculation
implicit none
real :: param1
integer :: param2
real, parameter :: defaultParam1 = 1.0
integer, parameter :: defaultParam2 = 2
contains
subroutine paramCalcInit( p1, p2 )
real, optional, intent(in) :: p1
integer, optional, intent(in) :: p2
if (present(p1)) then
! do any checking needed
param1 = p1
else
param1 = defaultParam1
end if
if (present(p2)) then
! do any checking needed
param2 = p2
else
param2 = defaultParam2
end if
end subroutine paramCalcInit
subroutine paramCalcFinalize
! clean up any module stuff that needs cleaning up
end subroutine paramCalcFinalize
elemental function doParamCalc(x, y)
real, intent(in) :: x
real, intent(in) :: y
real :: doParamCalc
doParamCalc = param1*x + param2*y
end function doParamCalc
end module paramcalculation
program testCalc
use paramcalculation
implicit none
real, dimension(5) :: x
real, dimension(5) :: y
real, dimension(5) :: z
x = 10
y = 2
call paramCalcInit( p2 = 0 )
z = doParamCalc(x, y)
print *, 'Input: ', x
print *, 'Output: ', z
call paramCalcFinalize
end program testCalc
跑步给出
$ gfortran -o params params.f90
$ ./params
Input: 10.000000 10.000000 10.000000 10.000000 10.000000
Output: 10.000000 10.000000 10.000000 10.000000 10.000000