!= ヒストリデータ出力
!
!= History data output
!
! Authors::   Yoshiyuki O. Takahashi, Yasuhiro MORIKAWA
! Version::   $Id: history_file_io.F90,v 1.9 2013/09/16 12:23:38 yot Exp $ 
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2010. All rights reserved.
! License::   See COPYRIGHT[link:../../../COPYRIGHT]
!

module history_file_io
  !
  != ヒストリデータ出力
  !
  != History data output
  !
  ! <b>Note that Japanese and English are described in parallel.</b>
  !
  ! ヒストリデータ出力の初期化, 時刻進行, 登録変数の表示と
  ! 終了処理を行います. 
  ! [gtool5 ライブラリ]{http://www.gfd-dennou.org/library/gtool} の 
  ! gtool_historyauto モジュールを用います. 
  ! 
  ! 各データの出力は, モデルの各プログラム内において, 
  ! gtool_historyauto モジュールから提供される
  ! HistoryAutoAddVariable および HistoryAutoPut を用います. 
  !

  ! モジュール引用 ; USE statements
  !
  
  ! MPI
  !
  use mpi_wrapper, only : flag_mpi_init

  ! 格子点設定
  ! Grid points settings
  !
  use gridset, only:   lmax, & ! スペクトルデータの配列サイズ
                               ! Size of array for spectral data
    &                  imax, & ! 経度格子点数. 
                               ! Number of grid points in longitude
    &                  jmax, & ! 緯度格子点数. 
                               ! Number of grid points in latitude
    &                  kmax, & ! 鉛直層数. 
                               ! Number of vertical level
    &                kslmax, & ! 地下の鉛直層数. 
                               ! Number of subsurface vertical level
    &                ksimax    ! 海氷の鉛直層数. 
                               ! Number of sea ice vertical level

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

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


  ! 宣言文 ; Declaration statements
  !
  implicit none
  private

  ! 公開手続き
  ! Public procedure
  !
  public:: HistoryFileOpen, HistoryFileClose

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

  ! 非公開変数
  ! Private variables
  !
  real(DP),      save:: DefaultIntValue
                              ! ヒストリデータの出力間隔の数値 (デフォルト値). 
                              ! Numerical value for interval of history data output (default value)
  character(STRING), save:: DefaultIntUnit
                              ! ヒストリデータの出力間隔の単位 (デフォルト値). 
                              ! Unit for interval of history data output (default value)
  character(STRING):: DefaultFilePrefix
                              ! ヒストリデータのファイル名の接頭詞 (デフォルト値). 
                              ! Prefixes of history data filenames (default value)

!!$  namelist /history_file_io_nml/ 

  character(*), parameter:: module_name = 'history_file_io'
                              ! モジュールの名称. 
                              ! Module name
  character(*), parameter:: version = &
    & '$Name:  $' // &
    & '$Id: history_file_io.F90,v 1.9 2013/09/16 12:23:38 yot Exp $'
                              ! モジュールのバージョン
                              ! Module version

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

  interface HistoryFileClose
    module procedure HistoryFileClose
  end interface

contains

  !-------------------------------------------------------------------

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

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

    ! 出力ファイルの基本情報
    ! Basic information for output files
    ! 
    use fileset, only: &
      & FileTitle, &
                              ! 出力データファイルの表題.
                              ! Title of output data files
      & FileSource, &
                              ! データファイル作成の手段. 
                              ! Source of data file
      & FileInstitution
                              ! データファイルを最終的に変更した組織/個人. 
                              ! Institution or person that changes data files for the last time

    ! 物理・数学定数設定
    ! Physical and mathematical constants settings
    !
    use constants0, only: &
      & PI                    ! $ \pi $.
                              ! 円周率. Circular constant

    ! 座標データ設定
    ! Axes data settings
    !
    use axesset, only: &
      & AxnameX  , &
      & AxnameY  , &
      & AxnameZ  , &
      & AxnameR  , &
      & AxnameSSZ, &
      & AxnameSSR, &
      & AxnameSIZ, &
      & AxnameSIR, &
      & AxnameWN , &
      & AxnameT  , &
      & x_Lon, &
                              ! $ \lambda $ [rad.] . 経度. Longitude
      & x_Lon_Weight, &
                              ! $ \Delta \lambda $ [rad.] . 
                              ! 経度座標重み. 
                              ! Weight of longitude
      & y_Lat, &
                              ! $ \varphi $ [rad.] . 緯度. Latitude
      & y_Lat_Weight, &
                              ! $ \Delta \varphi $ [rad.] . 
                              ! 緯度座標重み. 
                              ! Weight of latitude
      & z_Sigma, &
                              ! $ \sigma $ レベル (整数). 
                              ! Full $ \sigma $ level
      & r_Sigma, &
                              ! $ \sigma $ レベル (半整数). 
                              ! Half $ \sigma $ level
      & z_DelSigma, &
                              ! $ \Delta \sigma $ (整数). 
                              ! $ \Delta \sigma $ (Full)
      & w_Number, &
                              ! スペクトルデータの添字番号. 
                              ! Subscript of spectral data
      & r_SSDepth, &
                              ! subsurface grid on interface of layer
      & z_SSDepth, &
                              ! subsurface grid at midpoint of layer
      & r_SIDepth, &
                              ! sea ice grid on interface of layer
      & z_SIDepth
                              ! sea ice grid at midpoint of layer

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

    ! 時刻管理
    ! Time control
    !
    use timeset, only: &
      & RestartTime, &        ! リスタート開始時刻. 
                              ! Restart time of calculation
      & EndTime, &            ! 計算終了時刻. 
                              ! End time of calculation
      & DelTime               ! $ \Delta t $ [s]

    ! gtool4 netCDF データの入出力インターフェース (大規模モデル用)
    ! Interface of Input/Output of gtool4 netCDF data (For large models)
    !
    use gtool_historyauto, only: HistoryAutoCreate, &
      & HistoryAutoAddAttr, HistoryAutoAddWeight, HistoryAutoPutAxis, &
      & HistoryAutoPutAxisMPI

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

    ! 文字列操作
    ! Character handling
    !
    use dc_string, only: CPrintf

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

    ! 宣言文 ; Declaration statements
    !
    implicit none

    ! 実行文 ; Executable statement
    !

    if ( history_file_io_inited ) return
    call InitCheck

    ! デフォルト値の設定
    ! Default values settings
    !
    DefaultIntValue = 1.0
    DefaultIntUnit  = 'sec'
    DefaultFilePrefix = ''
!!$    DefaultIntValue = 1.0
!!$    DefaultIntUnit  = 'hrs'
!!$    DefaultFilePrefix = 'data01/'

    ! HistoryAutoCreate による初期化
    ! Initialization by "HistoryAutoCreate"
    !
    call HistoryAutoCreate( &
      &     title = trim(FileTitle) // ' history data',        &   ! (in)
      &    source = FileSource, institution = FileInstitution, &   ! (in)
      &      dims = (/ AxnameX, AxnameY, AxnameZ, AxnameR,     &   ! (in)
      &                AxnameSSZ, AxnameSSR,                   &   ! (in)
      &                AxnameSIZ, AxnameSIR,                   &   ! (in)
      &                AxnameWN, AxnameT /),                   &   ! (in)
      &  dimsizes = (/ imax, jmax, kmax, kmax + 1,             &   ! (in)
      &                max(kslmax,1), kslmax+1,                &   ! (in)
      &                max(ksimax,1), ksimax+1,                &   ! (in)
      &                lmax, 0 /),                             &   ! (in)
      & longnames = (/ 'longitude                                       ', &
      &                'latitude                                        ', &
      &                'sigma at layer midpoints                        ', &
      &                'sigma at layer interface (half level)           ', &
      &                'depth at subsurface layer midpoints             ', &
      &                'depth at subsurface layer interface (half level)', &
      &                'depth at sea ice layer midpoints                ', &
      &                'depth at sea ice layer interface (half level)   ', &
      &                'subscript of spectral data                      ', &
      &                'time                                            ' /), & ! (in)
      &     units = (/ 'degrees_east ', 'degrees_north', &
      &                '1            ', '1            ', &
      &                'm            ', 'm            ', &
      &                'm            ', 'm            ', &
      &                '1            ', DefaultIntUnit(1:13) /), &       ! (in)
      &     xtypes = (/ 'float', 'float', &
      &                 'float', 'float', &
      &                 'float', 'float', &
      &                 'float', 'float', &
      &                 'int  ', 'float' /), &                     ! (in)
      &          origin  = RestartTime, &                      ! (in) optional
      &         terminus = EndTime + 2. * DelTime, &           ! (in) optional
      &         interval = DefaultIntValue, &                  ! (in) optional
#ifdef INCLUDE_TIME_ORIGIN
      &       start_date = InitialDate, &                      ! (in) optional
#endif
!!$      &     slice_start  = (/ 1.0, 1.0, 1.0, 1.0, 1.0 /), & ! (in) optional
!!$      &     slice_end    = (/ 0.0, 0.0, 0.0, 0.0, 0.0 /), & ! (in) optional
!!$      &     slice_stride = (/   1,   1,   1,   1,   1 /), & ! (in) optional
!!$      &    space_average = (/ .false., .false., .false., &
!!$      &                       .false., .false. /), &        ! (in) optional
!!$      & newfile_interval = real( delta_time * 10 ), &       ! (in) optional

!!$      &  flag_mpi_gather = flag_mpi_init, &                    ! (in) optional
      &  flag_mpi_split  = flag_mpi_init, &                    ! (in) optional
      &      file_prefix = DefaultFilePrefix, &                ! (in) optional
      & namelist_filename = namelist_filename )                ! (in) optional


    ! 座標データへの属性の設定
    ! Attributes of axes data settings
    !
    call HistoryAutoAddAttr( &
      & varname = 'lon', attrname = 'standard_name', &   ! (in)
      & value = 'longitude' )                            ! (in)
    call HistoryAutoAddAttr( &
      & varname = 'lat', attrname = 'standard_name', &   ! (in)
      & value = 'latitude' )                             ! (in)
    call HistoryAutoAddAttr( &
      & varname = 'sig', attrname = 'standard_name', &   ! (in)
      & value = 'atmosphere_sigma_coordinate' )          ! (in)
    call HistoryAutoAddAttr( &
      & varname = 'sigm', attrname = 'standard_name', &  ! (in)
      & value = 'atmosphere_sigma_coordinate' )          ! (in)
    call HistoryAutoAddAttr( &
      & varname = 'sig', attrname = 'positive', &        ! (in)
      & value = 'down' )                                 ! (in)
    call HistoryAutoAddAttr( &
      & varname = 'sigm', attrname = 'positive', &       ! (in)
      & value = 'down' )                                 ! (in)
    call HistoryAutoAddAttr( &
      & varname = 'ssz', attrname = 'standard_name', &   ! (in)
      & value = 'depth' )                                ! (in)
    call HistoryAutoAddAttr( &
      & varname = 'sszi', attrname = 'standard_name', &  ! (in)
      & value = 'depth' )                                ! (in)

    ! 座標データの設定
    ! Axes data settings
    !
    call HistoryAutoPutAxis( &
      & 'lon',  x_Lon / PI * 180.0_DP )  ! (in)
    call HistoryAutoPutAxis( &
      & 'lat',  y_Lat / PI * 180.0_DP )  ! (in)
    call HistoryAutoPutAxis( &
      & 'sig',  z_Sigma )                ! (in)
    call HistoryAutoPutAxis( &
      & 'sigm', r_Sigma )                ! (in)
    if ( kslmax == 0 ) then
      call HistoryAutoPutAxis( &
        & 'ssz',  r_SSDepth )              ! (in)
    else
      call HistoryAutoPutAxis( &
        & 'ssz',  z_SSDepth )              ! (in)
    end if
    call HistoryAutoPutAxis( &
      & 'sszi', r_SSDepth )              ! (in)
    if ( ksimax == 0 ) then
      call HistoryAutoPutAxis( &
        & 'siz',  r_SIDepth )              ! (in)
    else
      call HistoryAutoPutAxis( &
        & 'siz',  z_SIDepth )              ! (in)
    end if
    call HistoryAutoPutAxis( &
      & 'sizi', r_SIDepth )              ! (in)
    call HistoryAutoPutAxis( &
      & 'wn',   w_Number )               ! (in)

    ! 座標重みの設定
    ! Axes weights settings
    !
    call HistoryAutoAddWeight( &
      & dim = 'lon', weight = x_Lon_Weight, & ! (in)
      & units = 'radian', xtype = 'double' )  ! (in) optional
    call HistoryAutoAddWeight( &
      & dim = 'lat', weight = y_Lat_Weight, & ! (in)
      & units = 'radian', xtype = 'double' )  ! (in) optional
    call HistoryAutoAddWeight( &
      & dim = 'sig', weight = z_DelSigma, &   ! (in)
      & xtype = 'double' )                    ! (in) optional

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

    history_file_io_inited = .true.
  end subroutine HistoryFileOpen

  !-------------------------------------------------------------------

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

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

    ! gtool4 netCDF データの入出力インターフェース (大規模モデル用)
    ! Interface of Input/Output of gtool4 netCDF data (For large models)
    !
    use gtool_historyauto, only: HistoryAutoClose

    ! 宣言文 ; Declaration statements
    !
    implicit none

    ! 作業変数
    ! Work variables
    !

    ! 実行文 ; Executable statement
    !

    call HistoryAutoClose

  end subroutine HistoryFileClose

  !-------------------------------------------------------------------

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

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

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

    ! 出力ファイルの基本情報管理
    ! Management basic information for output files
    !
    use fileset, only: fileset_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. fileset_inited ) &
      & call MessageNotify( 'E', module_name, '"fileset" 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 history_file_io
