0

提案をありがとう。十分に明確でないことをお許しください。私の能力の及ぶ範囲でもう一度説明させてください。

A と B の 2 つのモデルがあります。モデル 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 から必要な変数を、さまざまなサブルーチン呼び出しによって 1 つのモジュールに収集することでした。したがって、このモジュールをリポジトリとして使用し、モデル B が必要な変数に使用できるようにします。このアプローチは正しいですか?

4

1 に答える 1

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 と同名のモジュール変数が別の変数であるということだと思います。モジュール変数と同じ名前のサブルーチン仮引数を作成すると、値がモジュール変数に自動的にコピーされるのではなく、モジュール モジュールがマスクされます。そのため、メインのモジュール変数 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
于 2012-09-07T11:16:17.330 に答える