!---------------------------------------------------------------------
!     Copyright (C) GFD Dennou Club, 2005. All rights reserved.
!---------------------------------------------------------------------
                                                                 !=begin
!= Module time_mod
!
!   * Developers: Morikawa Yasuhiro
!   * Version: $Id: time.f90,v 1.1.1.1 2005/11/08 14:10:23 morikawa Exp $
!   * Tag Name: $Name:  $
!   * Change History: 
!
!== Overview
!
!This module set "Time" and "Step".
!
!時刻や「計算ステップ」に関して設定するためのモジュールである。
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!== Future Plans
!
                                                                 !=end
module time_mod
                                                                 !=begin
  !== Dependency
  use type_mod,    only : REKIND, DBKIND, INTKIND, TOKEN, STRING
                                                                 !=end
  implicit none
                                                                 !=begin
  !== Public Interface
  private
  public :: time_init, time_progress, time_end,  & ! subroutines
       &    InitTime, DelTime,                   & ! variables
       &    StepInterval, OutputStep,            & ! variables
       &    CurrentTime, CurrentLoop,            & ! variables
       &    tvar, ttype, tname, tunit              ! variables

  !== Public Data
  !
  !データ出力の際のステップ間隔や出力回数などに関する情報。
  !((< time_init >)) で設定。
  !
  real(DBKIND)     , save ::  &
       & InitTime = 0.0     , & ! 積分開始時刻
       & DelTime  = 300         ! 時間ステップ

  integer(INTKIND) , save ::  & 
       & StepInterval = 1   , & ! 出力ステップ間隔
       & OutputStep   = 1       ! 出力回数

  character(STRING), save ::  &
       & tvar  = 'time'     , & ! 時刻変数名
       & ttype = 'float'    , & ! 時刻変数の型
       & tname = 'time'     , & ! 時刻の名称
       & tunit = 'seconds'      ! 時刻の単位
  !
  !現在の時刻やループ回数を保持してある変数。
  !((< time_init >)) で初期設定され、((< time_progress >))
  !で更新される。
  !
  real(DBKIND)     , save :: CurrentTime = 0.0  ! 現在時刻
  integer(INTKIND) , save :: CurrentLoop = 1    ! 現在のループ回数
                                                                 !=end

  logical, save :: time_initialized = .false.
  character(STRING),parameter:: version = &
       & '$Id: time.f90,v 1.1.1.1 2005/11/08 14:10:23 morikawa Exp $'
  character(STRING),parameter:: tagname = '$Name:  $'

contains
                                                                 !=begin
  !== Procedure Interface
  !
  !=== Initialize module and acquire NAMELIST
  !
  !モジュールを初期化し、NAMELIST から値を取得する。
  !NAMELIST から値が取得できないものに関しては上記のデフォルト値が
  !用いられる。
  !
  !NAMELIST ファイルは、メインプログラムにて ((< nmlfile_mod >)) の
  !((< nmlfile_init >)) で指定されることが想定されているが、
  !もしもこの初期化ルーチンより以前に指定されていなければ、
  !((< nmlfile_init >)) のデフォルトで指定される NAMELIST ファイルを
  !読む。
  !
  subroutine time_init
  !==== Dependency
    use type_mod,    only : REKIND, DBKIND, INTKIND, TOKEN, STRING
    use nmlfile_mod, only : nmlfile_init, nmlfile_open, nmlfile_close
    use dc_trace,    only : BeginSub, EndSub, DbgMessage
    use dc_message,  only : MessageNotify
                                                                 !=end
    implicit none
                                                                 !=begin
    !
    !==== NAMELIST
    !
    !InitTime に与えられた数値に DelTime を加えた値が、
    !CurrentTime に代入される。
    !
    namelist /time_nml/    &

         & InitTime      , &   ! 積分開始時刻
         & DelTime       , &   ! 時間ステップ

         & StepInterval  , &   ! 出力回数
         & OutputStep    , &   ! 出力ステップ間隔

         & tvar          , &   ! 時刻変数名
         & ttype         , &   ! 時刻変数の型
         & tname         , &   ! 時刻の名称
         & tunit               ! 時刻の単位
                                                                 !=end

    !----- 作業用内部変数 -----
    integer(INTKIND)            :: nmlstat, nmlunit
    logical                     :: nmlreadable
    character(STRING), parameter:: subname = "time_init"

  continue

    !----------------------------------------------------------------
    !   Check Initialization
    !----------------------------------------------------------------
    call BeginSub(subname)
    if (time_initialized) then
       call EndSub( subname, '%c is already called', c1=trim(subname) )
       return
    else
       time_initialized = .true.
    endif

    !----------------------------------------------------------------
    !   Version identifier
    !----------------------------------------------------------------
    call DbgMessage('%c :: %c', c1=trim(version), c2=trim(tagname))

    !----------------------------------------------------------------
    !   read time_nml
    !----------------------------------------------------------------
    call nmlfile_init
    call nmlfile_open(nmlunit, nmlreadable)
    if (nmlreadable) then
       read(nmlunit, nml=time_nml, iostat=nmlstat)
       call DbgMessage('Stat of NAMELIST time_nml Input is <%d>', &
            &           i=(/nmlstat/))
       write(0, nml=time_nml)
    else
       call DbgMessage('Not Read NAMELIST time_nml')
       call MessageNotify('W', subname, &
            & 'Can not Read NAMELIST time_nml. Force Use Default Value.')
    end if
    call nmlfile_close

    !----------------------------------------------------------------
    !   Set CurrentTime
    !----------------------------------------------------------------
    CurrentTime = InitTime + DelTime

    call EndSub(subname)
  end subroutine time_init


                                                                 !=begin
  !=== Progress Time and Number of Loop
  !
  !CurrentTime を ((< time_init >)) で指定された DelTime 分だけ進め、
  !CurrentLoop を 1 増やす。
  !今の所、時間を指定したり巻戻したりできない。
  !
  subroutine time_progress
  !==== Dependency
    use type_mod,    only : STRING
    use dc_trace,    only : BeginSub, EndSub, DbgMessage
                                                                 !=end
    implicit none

    !-----------------------------------------------------------------
    !   変数定義
    !-----------------------------------------------------------------
    !----- 作業用内部変数 -----
    character(STRING),  parameter:: subname = "time_progress"
  continue

    !-----------------------------------------------------------------
    !   Check Initialization
    !-----------------------------------------------------------------
    call BeginSub(subname)
    if (.not. time_initialized) then
       call EndSub( subname, 'Call time_init before call %c', &
            &       c1=trim(subname) )
       return
    endif

    !----------------------------------------------------------------
    !   Set CurrentTime and CurrentLoop
    !----------------------------------------------------------------
    CurrentTime = CurrentTime + DelTime
    CurrentLoop = CurrentLoop + 1

    call EndSub(subname, 'CurrentLoop=<%d>, CurrentTime=<%f>', &
         & i=(/CurrentLoop/), d=(/CurrentTime/))
  end subroutine time_progress


                                                                 !=begin
  !=== Terminate module
  !
  !NAMELIST から読み込んだ値を破棄し、各定数をデフォルトの値に戻す。
  !
  subroutine time_end
  !==== Dependency
    use type_mod,    only : STRING
    use dc_trace,    only : BeginSub, EndSub, DbgMessage
                                                                 !=end
    implicit none

    !-----------------------------------------------------------------
    !   変数定義
    !-----------------------------------------------------------------
    !----- 作業用内部変数 -----
    character(STRING),  parameter:: subname = "time_end"
  continue

    !-----------------------------------------------------------------
    !   Check Initialization
    !-----------------------------------------------------------------
    call BeginSub(subname)
    if ( .not. time_initialized) then
       call EndSub( subname, 'time_init was not called', &
            &       c1=trim(subname) )
       return
    else
       time_initialized = .false.
    endif

    !----------------------------------------------------------------
    !   Reset to default value
    !----------------------------------------------------------------
    InitTime = 0.0      ! 積分開始時刻
    DelTime  = 300      ! 時間ステップ

    StepInterval = 1    ! 出力ステップ間隔
    OutputStep   = 1    ! 出力回数

    tvar  = 'time'      ! 時刻変数名
    ttype = 'float'     ! 時刻変数の型
    tname = 'time'      ! 時刻の名称
    tunit = 'seconds'   ! 時刻の単位

    CurrentTime = 0.0   ! 現在時刻
    CurrentLoop = 1     ! 現在のループ回数


    call EndSub(subname)
  end subroutine time_end

end module time_mod
