program dcpam_ape
!
!dcpam のテストプログラムとしての水惑星実験
!(APE; Aqua Planet Experiment) を行なうプログラムです.
!現在は main/init.f90 によって初期値を生成する
!必要があります.
!
!----- NAMELIST 名設定モジュール -----
use nmlfile_mod, only: nmlfile_init, nmlfile_open, nmlfile_close
!----- 物理定数設定モジュール -----
use constants_mod, only: SecPerDay
!----- 構造体参照モジュール -----
use dycore_type_mod, only: DYCORE_VARS, DYCORE_DIMS, STRING, INTKIND, REKIND
!----- 格子点取得モジュール -----
use dycore_grid_mod, only: dycore_grid_init, dycore_grid_end, im, jm, km, nm
!----- データI/Oモジュール -----
use dycore_in_mod, only: dycore_in_init, dycore_in_dims, dycore_in_vars, dycore_in_end
use dycore_out_mod, only: dycore_out_init, dycore_out_put, dycore_out_end
!----- 力学過程モジュール (DCPAM-APE 力学メインモジュール) -----
use dcpam_ape_dynamics_mod, only: dcpam_ape_dynamics
!----- 物理過程モジュール (DCPAM-APE 物理メインモジュール) -----
use dcpam_ape_physics_mod, only: dcpam_ape_physics
!----- 力学過程モジュール (スペクトルモデル用) -----
use dycore_dynamics_mod, only: dycore_dynamics_init, dycore_dynamics_end
!----- 時間更新・タイムフィルターモジュール -----
use dycore_time_mod, only: dycore_time_init, dycore_time_progress, dycore_time_end, dycore_time_filter, StepInterval, OutputStep, CurrentLoop, CurrentTime, DelTime
!----- データ I/O ツール -----
use io_gt4_out_mod , only: io_gt4_out_SetVars
!----- コマンドライン引数解析ツール -----
use dc_args, only: ARGS, Open, Debug, Help, Strict, Close
!----- デバッグ・汎用ツール -----
use dc_trace, only: SetDebug, DbgMessage, BeginSub, EndSub
use dc_message,only: MessageNotify
use dc_string, only: toChar, Printf
implicit none
logical :: CalcDynamics = .true. ! 力学コアの演算
logical :: CalcDiffusion = .true. ! 拡散項の演算
logical :: CalcHS94forcing = .false. ! Held and Suarez(1994) による強制
namelist /dcpam_ape_nml/ CalcDynamics, CalcDiffusion, CalcHS94forcing
! 実験設定を行う。
!-------------------------------------------------------------------
! 変数定義
!-------------------------------------------------------------------
!----- 次元データ全てを包括 (時間次元のみ除く) -----
type(DYCORE_DIMS) :: Dims ! 次元データ全種
!----- 計算される格子点データ全てを包括 -----
type(DYCORE_VARS) :: Vars_b ! 格子点データ全種(t-Δt)
type(DYCORE_VARS) :: Vars_n ! 格子点データ全種(t)
type(DYCORE_VARS) :: Vars_a ! 格子点データ全種(t+Δt)
!----- 作業変数 -----
!for time measure in temporarily
real(REKIND) :: start_time_init, end_time_init, start_time_dynmcs, end_time_dynmcs, store_time_dynmcs = 0.0, start_time_physics, end_time_physics, store_time_physics = 0.0
integer(INTKIND) :: dateval(1:8)
!for nmlfile_mod
integer(INTKIND) :: nmlstat, nmlunit
logical :: nmlreadable
!for dc_args
type(ARGS) :: arg
character(*), parameter:: version = '$Name: dcpam3-20070608 $' // '$Id: dcpam_ape.f90,v 1.2 2006/08/21 07:52:12 morikawa Exp $'
character(STRING), parameter:: subname = "dcpam_ape"
continue
!-------------------------------------------------------------------
! デバッグモード開始
!-------------------------------------------------------------------
call Open(arg)
call Debug(arg)
call Help(arg)
call Strict(arg)
call Close(arg)
call BeginSub(subname, version=version)
!-------------------------------------------------------------------
! use CPU_TIME
!-------------------------------------------------------------------
call cpu_time(start_time_init)
!-------------------------------------------------------------------
! NAMELIST file Setting
!-------------------------------------------------------------------
call nmlfile_init('dcpam_ape.nml')
!----------------------------------------------------------------
! Read init_nml
!----------------------------------------------------------------
call nmlfile_open(nmlunit, nmlreadable)
if (nmlreadable) then
read(nmlunit, nml=dcpam_ape_nml, iostat=nmlstat)
call DbgMessage('Stat of NAMELIST dcpam_ape_nml Input is <%d>', i=(/nmlstat/))
write(0, nml=dcpam_ape_nml)
else
call DbgMessage('Not Read NAMELIST dcpam_ape_nml')
call MessageNotify('W', subname, 'Can not Read NAMELIST dcpam_ape_nml. Force Use Default Value.')
end if
call nmlfile_close
!-------------------------------------------------------------------
! 格子点数の取得
!-------------------------------------------------------------------
call dycore_grid_init
!-------------------------------------------------------------------
! 初期値データ読み込み (gt4f90io の上位モジュール)
! (ファイル名や読み込む変数は NAMELIST で変更)
!-------------------------------------------------------------------
call dycore_in_init
call dycore_in_dims( Dims ) ! intent(out): 次元データ全種
call dycore_in_vars( Vars_b , Vars_n ) ! intent(out): 格子点データ全種(t)
!-------------------------------------------------------------------
! 時間・ ステップに関する初期設定
!-------------------------------------------------------------------
call dycore_time_init
!-------------------------------------------------------------------
! データ出力の初期設定
!-------------------------------------------------------------------
call dycore_out_init( Dims ) ! intent(in): 次元データ全種
! -- 物理過程の分 --
call io_gt4_out_SetVars('GeoPot')
call io_gt4_out_SetVars('Press')
call io_gt4_out_SetVars('Rain')
call io_gt4_out_SetVars('DPsDt')
call io_gt4_out_SetVars('DNegQvapDt')
call io_gt4_out_SetVars('DLscQvapDt')
call io_gt4_out_SetVars('DLscTempDt')
call io_gt4_out_SetVars('LscRain')
call io_gt4_out_SetVars('DCumulusQvapDt')
call io_gt4_out_SetVars('DCumulusTempDt')
call io_gt4_out_SetVars('CumulusRain')
call io_gt4_out_SetVars('DDryTempDt')
call io_gt4_out_SetVars('SurfTemp')
call io_gt4_out_SetVars('DRadLTempDt')
call io_gt4_out_SetVars('DRadSTempDt')
call io_gt4_out_SetVars('DVerdiffVelLonDt')
call io_gt4_out_SetVars('DVerdiffVelLatDt')
call io_gt4_out_SetVars('DVerdiffTempDt')
call io_gt4_out_SetVars('DVerdiffQvapDt')
!-------------------------------------------------------------------
! 力学過程演算の初期設定
!-------------------------------------------------------------------
call dycore_dynamics_init( Dims , Vars_a ) ! intent(out): 格子点データ全種(t+Δt)
!-------------------------------------------------------------------
! use CPU_TIME
!-------------------------------------------------------------------
call cpu_time(end_time_init)
call date_and_time(values=dateval)
call Printf(6, 'Elapsed Time=<%r>, Start=<%r>, Stop=<%r>, ' // 'Now=<%d/%d/%d %d:%d:%d>', r=(/end_time_init - start_time_init, start_time_init, end_time_init/), i=(/dateval(1), dateval(2), dateval(3), dateval(5), dateval(6), dateval(7) /) )
!-------------------------------------------------------------------
! メインループ
!-------------------------------------------------------------------
MainLoop : do
call BeginSub( subname, 'MainLoop : CurrentLoop=<%d>, CurrentTime=<%f>', i=(/CurrentLoop/), d=(/CurrentTime/) )
!----------------------------------------------------------------
! 力学過程演算
!----------------------------------------------------------------
call cpu_time(start_time_dynmcs)
call dcpam_ape_dynamics( Dims , Vars_b , Vars_n , Vars_a ) ! intent(inout): 格子点データ全種(t+Δt)
call cpu_time(end_time_dynmcs)
!----------------------------------------------------------------
! 物理過程演算
!----------------------------------------------------------------
call cpu_time(start_time_physics)
call dcpam_ape_physics( Dims , Vars_a ) ! intent(inout): 格子点データ全種(t+Δt)
call cpu_time(end_time_physics)
!----------------------------------------------------------------
! タイムフィルター
!----------------------------------------------------------------
call dycore_time_filter( Vars_b , Vars_n , Vars_a ) ! intent(in) : 格子点データ全種(t+Δt)
!----------------------------------------------------------------
! データの出力
!----------------------------------------------------------------
call dycore_out_put( Vars_n ) ! intent(in): 格子点データ全種(t)
!----------------------------------------------------------------
! 時刻更新
!----------------------------------------------------------------
call dycore_time_progress( Vars_b , Vars_n , Vars_a ) ! intent(inout): 格子点データ全種(t+Δt)
!-------------------------------------------------------------------
! use CPU_TIME
!-------------------------------------------------------------------
store_time_physics = store_time_physics + (end_time_physics - start_time_physics)
store_time_dynmcs = store_time_dynmcs + (end_time_dynmcs - start_time_dynmcs)
if ( mod(CurrentLoop, StepInterval) == 0 ) then
call Printf(6, '')
call Printf(6, '-- *** *** ')
call Printf(6, '-- *** TIME *** ')
call Printf(6, '-- *** KEEPING *** ')
call Printf(6, '-- *** *** ')
call Printf(6, '--CurrentLoop=<%d>, CurrentTime=<%f>, Day=<%f>', i=(/CurrentLoop/), d=(/CurrentTime, CurrentTime/SecPerDay /) )
call Printf(6, '--Remaining Loop ' // ': RemainingLoop=<%d>, RemainingTime=<%f>, Day=<%f>', i=(/StepInterval * OutputStep - CurrentLoop/), d=(/StepInterval * OutputStep * DelTime - CurrentTime , ( StepInterval * OutputStep * DelTime - CurrentTime ) / SecPerDay /) )
call date_and_time(values=dateval)
call Printf(6, '--Current Time <%d/%d/%d %d:%d:%d>', i=(/dateval(1), dateval(2), dateval(3), dateval(5), dateval(6), dateval(7) /) )
call Printf(6, '--[Categoly] : [Stored] ' // '[Current] [Start] [Stop] ' )
call Printf(6, '--Dynamics : <%r> <%r> <%r> <%r> ', r=(/store_time_dynmcs, end_time_dynmcs - start_time_dynmcs, start_time_dynmcs, end_time_dynmcs/) )
call Printf(6, '--Physics : <%r> <%r> <%r> <%r> ', r=(/store_time_physics, end_time_physics - start_time_physics, start_time_physics, end_time_physics/) )
end if
!----------------------------------------------------------------
! ループから抜け出すかどうかの判定
!----------------------------------------------------------------
if ( CurrentLoop > StepInterval * OutputStep ) then
exit MainLoop
endif
call EndSub(subname)
enddo MainLoop
call dycore_out_end
call EndSub(subname)
end program dcpam_ape