最新版 dcpam5 における I/O 関連の
!!!! use gt4_historyauto, only: HistoryAutoPut, HistoryAutoProgress ... ! リスタートデータ出力 ! Restart data output ! call RestartFileOpen ! リスタートファイルへ初期値データ出力 ! Output initial data to a restart file ! call RestartFileOutput( & & xyz_UB, xyz_VB, xyz_TempB, xyz_QVapB, xy_PsB, & ! (in) & xyz_UN, xyz_VN, xyz_TempN, xyz_QVapN, xy_PsN ) ! (in) ! ヒストリデータファイルの初期化 ! Initialization of history data files ! call HistoryFileOpen ! ヒストリデータ出力のためのへの変数登録 ! Register of variables for history data output ! call HistoryAutoAddVariable( 'U' , & & (/ 'lon ', 'lat ', 'sig ', 'time' /), & & 'eastward wind', 'm s-1' ) ... do (時間積分) ... ! ヒストリデータ出力 ! History data output ! if ( .not. firstloop ) then call HistoryAutoPut( 'U', xyz_UN ) call HistoryAutoPut( 'V', xyz_VN ) call HistoryAutoPut( 'Temp', xyz_TempN ) call HistoryAutoPut( 'QVap', xyz_QVapN ) call HistoryAutoPut( 'Ps', xy_PsN ) end if ! 時刻の進行 ! Progress time ! call TimesetProgress ! モデルの管理する時刻を 1 ステップ進める call HistoryAutoProgress ! I/O ライブラリが持つ時刻を 1 ステップ進める ! リスタートデータ出力 ! Restart data output ! if ( .not. firstloop ) then call RestartFileOutput( & & xyz_UB, xyz_VB, xyz_TempB, xyz_QVapB, xy_PsB, & ! (in) & xyz_UN, xyz_VN, xyz_TempN, xyz_QVapN, xy_PsN ) ! (in) end if end do ..
議論の内容
dcpam
t=t1 のデータを出力する場合には, t=t1+Δtまで計算する
積算値を計算するときには t=t0+Δt から t=t1 までのデータを使う
t=t0 t=t1 |--|--|--|--|--|--| t=t1+Δt
積算値を計算するときには t=t0 から t=t1-Δt までのデータを使う
t=t0 t=t1 |--|--|--|--|--|
時間積分ループ構造の検討
素直にループを記述した場合. HistoryAuto は現在の仕様.
do i = 1, N Time = Time0 + dt*i Tendency = f(VarN, VarB) call HistoryAutoPut(Tendency) ! t=Time-Dt の Tendency を出力 call HistoryAutoSetTime(Time) ! 出力用の時刻設定 VarA = VarB + 2.0*Dt*Tendency call HistoryAutoPut(VarA) ! t=Time の Var を出力 call timefilter(VarA, VarN, VarB) ! 時間フィルタ VarB = VarN VarN = VarA end do
最後に Tendency を 1 ステップ余分に計算する場合. HistoryAuto は現在の仕様.
do i = 1, N+1 Tendency = f(VarN, VarB) call HistoryAutoPut(Tendency) ! t=Time-Dt の Tendency を出力 FooTendency = f(FooN, FooB) call HistoryAutoPut(FooTendency) ! t=Time-Dt の Tendency を出力 TimeA = TimeN + dt call HistoryAutoSetTime(TimeA) ! 出力用の時刻設定 exit if (i=N+1) ! 最後のループは Tendency だけ計算して ! ループを抜ける FooA = FooB + 2.0*Dt*FooTendency VarA = VarB + 2.0*Dt*VarTendency call Adjustment(VarA) ! VarA の調節 call HistoryAutoPut(VarA) ! t=Time の Var を出力 call timefilter(VarA, VarN, VarB) ! 時間フィルタ VarB = VarN VarN = VarA TimeB = TimeN TimeN = TimeA end do
HistoryAutoPut の引数に出力時刻を与える場合
do i = 1, N+1 TimeA = TimeN + dt Tendency = f(VarN, VarB) call HistoryAutoPut(TimeN, Tendency) ! t=TimeN の Tendency を出力 FooTendency = f(FooN, FooB) call HistoryAutoPut(TimeN, FooTendency) ! t=TimeN の Tendency を出力 tmp_VarA = VarB + 2.0*Dt*VarTendency call Adjustment(tmp_VarA, adjust_tendency) ! Var の調節 call HistoryAutoPut(TimeN, adjust_tendency) ! t=TimeN の Tendency を出力 exit if (i=N+1) ! 最後のループは Tendency だけ計算して ! ループを抜ける VarA = VarB + 2.0*Dt*(VarTendency+adjust_tendency) FooA = FooB + 2.0*Dt*FooTendency call HistoryAutoPut(TimeA, VarA) ! t=Time の Var を出力 call timefilter(VarA, VarN, VarB) ! 時間フィルタ VarB = VarN VarN = VarA TimeB = TimeN TimeN = TimeA end do
HistoryAutoPut の引数に出力時刻を与え, HistoryAutoPut が各変数を出力するタイミングを判断してくれる場合 (決定案)
call HistoryAutoCreate ! Var, Foo, Tendency の出力時刻, ! 出力終了時刻(EndTime)を与える do while (TimeA <= LoopEndTime) ! ループの制御は時刻変数で行う TimeA = TimeN + dt Tendency = f(VarN, VarB) call HistoryAutoPut(TimeN, Tendency) ! t=TimeN の Tendency を出力 FooTendency = f(FooN, FooB) call HistoryAutoPut(TimeN, FooTendency) ! t=TimeN の Tendency を出力 tmp_VarA = VarB + 2.0*Dt*VarTendency call Adjustment(tmp_VarA, adjust_tendency) ! Var の調節 call HistoryAutoPut(TimeN, adjust_tendency) ! t=TimeN の Tendency を出力 VarA = VarB + 2.0*Dt*(VarTendency+adjust_tendency) FooA = FooB + 2.0*Dt*FooTendency call HistoryAutoPut(TimeA, VarA) ! t=Time の Var を出力 call timefilter(VarA, VarN, VarB) ! 時間フィルタ VarB = VarN VarN = VarA FooB = FooN FooN = FooA TimeB = TimeN TimeN = TimeA end do
小高さんが気持よいループ構造. deepconv/arare4 はこれに近い構造をしている. でもこのように書けないことが多々あるだろう.
do i = 1, N+1 TimeA = TimeN + dt Tendency = f(VarN, VarB) call HistoryAutoPut(TimeN, Tendency) ! t=TimeN の Tendency を出力 tmp_VarA = VarB + 2.0*Dt*VarTendency call Adjustment(tmp_VarA, adjust_tendency) ! Var の調節 call HistoryAutoPut(TimeN, adjust_tendency) ! t=TimeN の Tendency を出力 VarA = VarB + 2.0*Dt*(VarTendency+adjust_tendency) FooTendency = f(FooN, FooB) call HistoryAutoPut(TimeN, FooTendency) ! t=TimeN の Tendency を出力 FooA = FooB + 2.0*Dt*FooTendency call HistoryAutoPut(TimeA, VarA) ! t=Time の Var を出力 call timefilter(VarA, VarN, VarB) ! 時間フィルタ VarB = VarN VarN = VarA TimeB = TimeN TimeN = TimeA end do
モデルでは 4 倍精度で計算し, そのデータを出力する場合は あらかじめ gt4f90io の実数型を 4 倍精度指定でコンパイル しておかなくてはいけない
モデルで指定されている精度に対応して, gt4f90io がよろしく 判断してくれるならよいが, 現状ではそのようにはできない.
具体例
! 現在の dcpam, deepconv の書き方 ! A は本当は DP ではないか, という疑念が湧く人もいる real :: A real(DP) :: B ! 単精度実数も明示的に精度指定する場合 ! real(SP) :: A real(DP) :: B ! 種別型パラメタを小文字で書く場合 ! real(sp) :: A real(dp) :: B ! F77 以来の書き方 B = 1.0d0 ! F90 で可能になった書き方 ! gt4f90io, dcpam ではこのように書いている B = 1.0_DP
NAMELIST でリスタートファイル名が与えられていない場合は, デフォルトの初期値を生成して返す
! リスタートデータ入力 ! Restart data input ! call RestartFileGet( &
& xyz_UB, xyz_VB, xyz_TempB, xyz_QVapB, xy_PsB, & ! (out) & xyz_UN, xyz_VN, xyz_TempN, xyz_QVapN, xy_PsN ) ! (out)