最新版 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)