感谢您的建议。请原谅我不够清楚。让我尽我所能再次描述它。
有两种型号 - A& B.模型A有一个子程序(不是模块的一部分)compns.f
由主程序调用。下面是compns.f
代码:
compns.f :(模型A)
subroutine compns(deltim,fhout)
use var_repos, only: compns_var_dump
open(unit=nlunit,file=gfs_namelist) ! reads a file for the variables deltim and fhout
rewind (nlunit)
read(nlunit,nam_mrf)
print *, deltim,fhout ! deltim = 360.0, fhout = 6.0
CALL compns_var_dump(deltim,fhout) ! calls the subroutine and passes the variables
end
包含子程序compns_var_dump(收集变量)的另一个模块是
var_repos.f90
:
MODULE var_repos
IMPLICIT NONE
PUBLIC :: compns_var_dump
PUBLIC :: tstep_var_dump !!! to dump variables from another place
REAL, PUBLIC :: d_time ! dummy variable
! declare the variables which will go public here:
REAL, PUBLIC :: deltim, fhout
CONTAINS
SUBROUTINE compns_var_dump(deltim , fhout)
REAL, INTENT(inout) :: deltim , fhout
d_time = deltim
WRITE(*,*)'Inside var_repos: deltim = ',deltim,d_time
END SUBROUTINE compns_var_dump
SUBROUTINE tstep_var_dump
...
END SUBROUTINE tstep_var_dump
END MODULE var_repos
现在,我需要模型B中var_repos.f90
的变量。模型B中需要它们的模块如下:
mo_time_control.f90 :(模型B)
MODULE time_control
PUBLIC :: get_delta_time
CONTAINS
REAL(dp) FUNCTION get_delta_time()
USE var_repos, ONLY: d_time
IMPLICIT NONE
REAL :: d_time
REAL :: a_time ! Testing
get_delta_time = d_time
a_time = d_time ! Testing
WRITE(*,*)'Inside function get_delta_time(): deltim= ',d_time,get_delta_time, a_time
END FUNCTION get_delta_time
END MODULE time_control
运行模型后的输出如下:
'Inside var_repos: deltim = ' 360.000 360.000
'Inside function get_delta_time(): deltim= ' 0.00000E+00 0.00000E+00 0.00000E+00
我希望我在这篇文章中很清楚。有没有更好的方法来完成上述任务?我的理念是通过不同的子程序调用将模型A中所需的变量收集到一个模块中,因此将此模块用作存储库,让模型B将其用于所需的变量。这种做法是对的吗?
答案 0 :(得分:1)
试试这个例子:
MODULE var_repos
IMPLICIT NONE
PUBLIC :: compns_var_dump
REAL, PUBLIC :: deltim, var2
CONTAINS
SUBROUTINE compns_var_dump(deltim , fhout)
REAL, INTENT(in) :: deltim , fhout
WRITE(*,*)'Inside var_repos: args = ', deltim, fhout
var2 = fhout
END SUBROUTINE compns_var_dump
END MODULE var_repos
program test
use var_repos
call compns_var_dump ( 2.0, 3.0 )
write (*, *) "in main:", deltim, var2
end program test
输出结果为:
Inside var_repos: args = 2.00000000 3.00000000
in main: 0.00000000 3.00000000
我认为答案是子例程的参数deltim和同名的模块变量是不同的变量。创建与模块变量同名的子例程伪参数会屏蔽模块模块,而不是自动将值复制到模块变量。所以在main中,模块变量deltim没有收到值2并且未定义。使用编译器,我使用它的随机值为零;在不同的编译器上,该值可能不同。另一方面,变量fhout和var2是不同的,伪参数fhout被主动复制到var2。因此,模块var2的值已设置并可用于使用该模块的任何例程(此处为主程序)。
编辑:解决方案是我为参数fhout和模块变量var2显示的内容。调用伪参数ARG_varX和模块变量GBL_varX。在子例程内部使用赋值语句将每个ARG_varX复制到GBL_varX。然后,使用该模块的任何过程都可以访问变量GBL_varX,这些变量将具有发送到子例程的值。这是否可以解决您的问题。
编辑2:这是您新代码的一个版本。它似乎工作。如果有错误,我修复它或者它不在您显示的代码之外:
MODULE var_repos
IMPLICIT NONE
PUBLIC :: compns_var_dump
! declare the variables which will go public here:
REAL, PUBLIC :: GBL_deltim, GBL_fhout
CONTAINS
SUBROUTINE compns_var_dump(ARG_deltim, ARG_fhout)
REAL, INTENT(in) :: ARG_deltim , ARG_fhout
GBL_deltim = ARG_deltim
GBL_fhout = ARG_fhout
WRITE(*,*)'Inside compns_var_dump:', ARG_deltim, GBL_deltim, GBL_fhout
END SUBROUTINE compns_var_dump
END MODULE var_repos
! ------------------------------------------------------------
module my_b
contains
subroutine compns ()
use var_repos, only: compns_var_dump
real :: deltim, fhout
deltim = 360.0
fhout = 6.0
write (*, *) "compns:", deltim, fhout
CALL compns_var_dump(deltim,fhout) ! calls the subroutine and passes the variables
end subroutine compns
end module my_b
! ------------------------------------------------------------
MODULE time_control
PUBLIC :: get_delta_time
CONTAINS
FUNCTION get_delta_time()
USE var_repos, ONLY: GBL_deltim
IMPLICIT NONE
real :: get_delta_time
REAL :: a_time ! Testing
get_delta_time = GBL_deltim
a_time = GBL_deltim ! Testing
WRITE(*,*)'Inside function get_delta_time(): deltim= ', GBL_deltim, get_delta_time, a_time
END FUNCTION get_delta_time
END MODULE time_control
! ------------------------------------------------------------
program main
use var_repos, only: GBL_deltim, GBL_fhout
use my_b, only: compns
use time_control, only: get_delta_time
real :: local_var
call compns ()
local_var = get_delta_time ()
write (*, *) "main:", local_var, GBL_deltim, GBL_fhout
end program main