!= リスタートデータ出力
!
!= Restart data output
!
! Authors::   Yasuhiro MORIKAWA
! Version::   $Id: gridset.f90,v 1.5 2007/06/09 13:12:30 sugiyama Exp $ 
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2008. All rights reserved.
! License::   See COPYRIGHT[link:../../../COPYRIGHT]
!

module restart_file_io
  !
  != リスタートデータ出力
  !
  != Restart data output
  !
  ! <b>Note that Japanese and English are described in parallel.</b>
  !

  ! モジュール引用 ; USE statements
  !

  ! 種別型パラメタ
  ! Kind type parameter
  !
  use dc_types, only: DP, &  ! 倍精度実数型. Double precision. 
    &                 TOKEN  ! キーワード.   Keywords. 

  ! メッセージ出力
  ! Message output
  !
  use dc_message, only: MessageNotify

  ! 宣言文 ; Declaration statements
  !
  implicit none
  private

  ! 公開手続き
  ! Public procedure
  !
  public:: RestartFileOpen, RestartFileClose, RestartFileOutPut
  public:: RestartFileGet

  ! 公開変数
  ! Public variables
  !
  logical, save, public:: restart_file_io_inited = .false.
                              ! 初期設定フラグ. 
                              ! Initialization flag

  logical, save, public:: restart_file_opened = .false.
                              ! リスタートファイルのオープンに関するフラグ. 
                              ! Flag of restart file open

  ! 非公開変数
  ! Private variables
  !
  character(STRING):: file

                              ! リスタートデータのファイル名
                              ! filename of restart data


  namelist /dcpam_hs94_history_nml/ &
    & file, &
    & interval_value, &
    & interval_unit

  character(*), parameter:: module_name = 'restart_file_io'
                              ! モジュールの名称. 
                              ! Module name
  character(*), parameter:: version = &
    & '$Name:  $' // &
    & '$Id:  $'
                              ! モジュールのバージョン
                              ! Module version

  ! INTERFACE 文 ; INTERFACE statements
  !
  interface RestartFileOpen
    module procedure RestartFileOpen
  end interface

  interface RestartFileClose
    module procedure RestartFileClose
  end interface

  interface RestartFileOutput
    module procedure RestartFileOutput
  end interface

  interface RestartFileGet
    module procedure RestartFileGet
  end interface

contains

  subroutine RestartFileOpen
    !
    ! リスタートファイルをオープンします. 
    !
    ! A restart file is opened. 
    !

    ! モジュール引用 ; USE statements
    !

    ! 時刻管理
    ! Time control
    !
    use timeset, only: TimesetGetStartTime

    ! 宣言文 ; Declaration statements
    !
    implicit none

    ! 作業変数
    ! Work variables
    !
    real(DP):: origin_time
                              ! 計算開始時刻. 
                              ! Start time of calculation

    ! 実行文 ; Executable statement
    !

    ! 初期化
    ! Initialization
    !
    if ( .not. restart_file_io_inited ) call RestartFileInit
    if ( restart_file_opened ) return

    ! 時刻情報の取得
    ! Get time information
    !
    TimesetGetStartTime( &
      & origin_time, & ! (out)
      & unit  & ! (in) optional
      & )    

    ! リスタートファイルのオープン
    ! Open a restart file
    !
    call HistoryCreate
      & restart_file, title, source, institution, &    ! (in)
      & StoA( 'lon', 'lat', 'sig', 'sigm', 'time' ), & ! (in)
      & (/ imax, jmax, kmax, kmax + 1, 0 /), &         ! (in)
      & StoA( 'longitude', 'latitude', &
      &       'sigma at layer midpoints', &
      &       'sigma at layer end-points (half level)', &
      &       'time' ), &                              ! (in)
      & StoA( 'degree_east', 'degree_north', &
      &       '1', '1', interval_unit ), &             ! (in)
      & real( EvalbyUnit( current_time, &
      &                   interval_unit) ), &          ! (in)
      & interval_value )                               ! (in)

      & gthst_rst, &                                     ! (out)


    restart_file_opened = .true.
  end subroutine RestartFileOpen



  subroutine RestartFileClose
    !
    ! リスタートデータファイル出力の終了処理を行います. 
    !
    ! Terminate restart data files output. 

    ! モジュール引用 ; USE statements
    !

    ! 宣言文 ; Declaration statements
    !
    implicit none

    ! 作業変数
    ! Work variables
    !

    ! 実行文 ; Executable statement
    !
    if ( .not. restart_file_opened ) return

    restart_file_opened = .false.
  end subroutine RestartFileClose



  subroutine RestartFileOutput( &
    & xyz_UN, xyz_VN, xyz_TempN, xyz_QVapN, xy_PsN, &   ! (in)
    & xyz_UA, xyz_VA, xyz_TempA, xyz_QVapA, xy_PsA  &   ! (in)
    & )
    !
    ! リスタートデータの出力を行います. 
    !
    ! Output restart data

    ! モジュール引用 ; USE statements
    !

    ! 宣言文 ; Declaration statements
    !
    implicit none
    real(DP), intent(in):: xyz_UN  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ u (t) $ .     東西風速. Eastward wind
    real(DP), intent(in):: xyz_VN  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ v (t) $ .     南北風速. Northward wind
    real(DP), intent(in):: xyz_TempN  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ T (t) $ .     温度. Temperature
    real(DP), intent(in):: xyz_QVapN  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ q (t) $ .     比湿. Specific humidity
    real(DP), intent(in):: xy_PsN (0:imax-1, 1:jmax)
                              ! $ p_s (t) $ .   地表面気圧. Surface pressure
    real(DP), intent(in):: xyz_UA  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ u (t+\Delta t) $ .   東西風速. Eastward wind
    real(DP), intent(in):: xyz_VA  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ v (t+\Delta t) $ .   南北風速. Northward wind
    real(DP), intent(in):: xyz_TempA  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ T (t+\Delta t) $ .   温度. Temperature
    real(DP), intent(in):: xyz_QVapA  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ q (t+\Delta t) $ .   比湿. Specific humidity
    real(DP), intent(in):: xy_PsA (0:imax-1, 1:jmax)
                              ! $ p_s (t+\Delta t) $ . 地表面気圧. Surface pressure

    ! 作業変数
    ! Work variables
    !
    if ( .not. restart_file_opened ) call RestartFileOpen

    ! 実行文 ; Executable statement
    !

  end subroutine RestartFileOutput



  subroutine RestartFileGet( &
    & xyz_UB, xyz_VB, xyz_TempB, xyz_QVapB, xy_PsB, &   ! (out)
    & xyz_UN, xyz_VN, xyz_TempN, xyz_QVapN, xy_PsN  &   ! (out)
    & )
    !
    ! リスタートデータの入力を行います. 
    !
    ! Input restart data

    ! モジュール引用 ; USE statements
    !

    ! 宣言文 ; Declaration statements
    !
    implicit none
    real(DP), intent(out):: xyz_UB  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ u (t-\Delta t) $ .   東西風速. Eastward wind
    real(DP), intent(out):: xyz_VB  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ v (t-\Delta t) $ .   南北風速. Northward wind
    real(DP), intent(out):: xyz_TempB  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ T (t-\Delta t) $ .   温度. Temperature
    real(DP), intent(out):: xyz_QVapB  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ q (t-\Delta t) $ .   比湿. Specific humidity
    real(DP), intent(out):: xy_PsB (0:imax-1, 1:jmax)
                              ! $ p_s (t-\Delta t) $ . 地表面気圧. Surface pressure
    real(DP), intent(out):: xyz_UN  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ u (t) $ .     東西風速. Eastward wind
    real(DP), intent(out):: xyz_VN  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ v (t) $ .     南北風速. Northward wind
    real(DP), intent(out):: xyz_TempN  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ T (t) $ .     温度. Temperature
    real(DP), intent(out):: xyz_QVapN  (0:imax-1, 1:jmax, 1:kmax)
                              ! $ q (t) $ .     比湿. Specific humidity
    real(DP), intent(out):: xy_PsN (0:imax-1, 1:jmax)
                              ! $ p_s (t) $ .   地表面気圧. Surface pressure

    ! 作業変数
    ! Work variables
    !

    ! 実行文 ; Executable statement
    !
    if ( .not. restart_file_io_inited ) call RestartFileInit

  end subroutine RestartFileGet



  subroutine RestartFileInit
    !
    ! restart_file_io モジュールの初期化を行います. 
    ! NAMELIST#restart_file_io_nml の読み込みはこの手続きで行われます. 
    !
    ! "restart_file_io" module is initialized. 
    ! "NAMELIST#restart_file_io_nml" is loaded in this procedure. 
    !

    ! モジュール引用 ; USE statements
    !

    ! NAMELIST ファイル入力に関するユーティリティ
    ! Utilities for NAMELIST file input
    !
    use namelist_util, only: namelist_filename, NmlutilMsg

    ! ファイル入出力補助
    ! File I/O support
    !
    use dc_iounit, only: FileOpen

    ! 種別型パラメタ
    ! Kind type parameter
    !
    use dc_types, only: STDOUT ! 標準出力の装置番号. Unit number of standard output

    ! 宣言文 ; Declaration statements
    !
    implicit none

    ! 作業変数
    ! Work variables
    !
    integer:: unit_nml        ! NAMELIST ファイルオープン用装置番号. 
                              ! Unit number for NAMELIST file open
    integer:: iostat_nml      ! NAMELIST 読み込み時の IOSTAT. 
                              ! IOSTAT of NAMELIST read

    ! 実行文 ; Executable statement
    !

    if ( .not. restart_file_io_inited ) 
    call InitCheck

    ! NAMELIST の読み込み
    ! NAMELIST is input
    !
!!$    call FileOpen( unit_nml, &          ! (out)
!!$      & namelist_filename, mode = 'r' ) ! (in)
!!$
!!$    rewind( unit_nml )
!!$    read( unit_nml, &         ! (in)
!!$      & nml = restart_file_io_nml, &  ! (out)
!!$      & iostat = iostat_nml ) ! (out)
!!$    close( unit_nml )
!!$
!!$    call NmlutilMsg( iostat_nml, module_name ) ! (in)
!!$    if ( iostat_nml == 0 ) write( STDOUT, nml = restart_file_io_nml )


    ! 印字 ; Print
    !
    call MessageNotify( 'M', module_name, '----- Initialization Messages -----' )
    call MessageNotify( 'M', module_name, '-- version = %c', c1 = trim(version) )

    restart_file_io_inited = .true.
  end subroutine RestartFileInit



  subroutine InitCheck
    !
    ! 依存モジュールの初期化チェック
    !
    ! Check initialization of dependency modules

    ! モジュール引用 ; USE statements
    !

    ! NAMELIST ファイル入力に関するユーティリティ
    ! Utilities for NAMELIST file input
    !
    use namelist_util, only: namelist_util_inited

    ! 格子点設定
    ! Grid points settings
    !
    use gridset, only: gridset_inited

    ! 座標データ設定
    ! Axes data settings
    !
    use axesset, only: axesset_inited

    ! 時刻管理
    ! Time control
    !
    use timeset, only: timeset_inited


    ! 実行文 ; Executable statement
    !

    if ( .not. namelist_util_inited ) &
      & call MessageNotify( 'E', module_name, '"namelist_util" module is not initialized.' )

    if ( .not. gridset_inited ) &
      & call MessageNotify( 'E', module_name, '"gridset" module is not initialized.' )

    if ( .not. axesset_inited ) &
      & call MessageNotify( 'E', module_name, '"axesset" module is not initialized.' )

    if ( .not. timeset_inited ) &
      & call MessageNotify( 'E', module_name, '"timeset" module is not initialized.' )


  end subroutine InitCheck

end module restart_file_io
