首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在公共位置收集变量- fortran90

在公共位置收集变量- fortran90
EN

Stack Overflow用户
提问于 2012-09-07 18:38:34
回答 1查看 276关注 0票数 0

谢谢你的建议。请您原谅我说得不够清楚。让我尽我所能再描述一次。

有两个模型-A和B。模型A有一个子程序(不是模块的一部分) compns.f,它由主程序调用。下面是compns.f代码:

compns.f:(模型A)

代码语言:javascript
复制
 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

代码语言:javascript
复制
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)

代码语言:javascript
复制
 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

运行模型后的输出如下所示:

代码语言:javascript
复制
'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将其用于所需的变量。这种方法正确吗?

EN

回答 1

Stack Overflow用户

发布于 2012-09-07 19:16:17

试一下这个例子:

代码语言:javascript
复制
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

输出为:

代码语言:javascript
复制
 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:这是你的新代码的一个版本。它似乎起作用了。如果有错误,要么是我修复了它,要么是在您所显示的代码之外:

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12316467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档