!= 木星を模した大気上層への冷却
!
!= Cooling of atmospheric upper layer to imitate Jupiter
!
! Authors::   Yasuhiro MORIKAWA
! Version::   $Id: phy_cooling_s08.f90,v 1.1 2008-06-03 12:55:19 morikawa Exp $
! Tag Name::  $Name: dcpam4-20080626 $
! Copyright:: Copyright (C) GFD Dennou Club, 2008. All rights reserved.
! License::   See COPYRIGHT[link:../../../COPYRIGHT]   
!

module phy_cooling_s08
  !
  != 木星を模した大気上層への冷却
  !
  != Cooling of atmospheric upper layer to imitate Jupiter
  !
  ! <b>Note that Japanese and English are described in parallel.</b>
  !
  ! Sugiyama et al. (2008) の手法を真似て, 
  ! 木星大気を模した放射冷却の効果を算出する. 
  ! 具体的には, 2.0e5 〜 1.0e4 Pa の範囲に一定の冷却を与える. 
  ! デフォルトは -1.0 K/day である. 
  ! 
  ! The method of Sugiyama et al. (2008) is mimicked, and an effect of 
  ! radiation cooling to imitate the Jupiter atmosphere is calculated. 
  ! Concretely, a constant cooling is given within the range of 2.0e5 --
  ! 1.0e4 Pa. 
  ! Default value is -1.0 K/day.
  !
  !== Procedures List
  !
  ! PhyCoolCreate        :: PHYCOOL 型変数の初期設定
  ! Cooling                :: 冷却の効果を返す
  ! PhyCoolClose         :: PHYCOOL 型変数の終了処理
  ! PhyCoolPutLine       :: PHYCOOL 型変数に格納されている情報の印字
  ! PhyCoolinitialized   :: PHYCOOL 型変数が初期設定されているか否か
  ! PhyCoolSetTime       :: 時刻の設定
  ! ------------  :: ------------
  ! PhyCoolCreate        :: Constructor of "PHYCOOL"
  ! Cooling                :: Return an effect of cooling
  ! PhyCoolClose         :: Deconstructor of "PHYCOOL"
  ! PhyCoolPutLine       :: Print information of "PHYCOOL"
  ! PhyCoolinitialized   :: Check initialization of "PHYCOOL"
  ! PhyCoolSetTime       :: Configure time
  !
  !== Usage
  !
  ! 始めに, PHYCOOL 型の変数を定義し, 
  ! PhyCoolCreate で初期設定を行います. 
  ! Cooling に温度と地表面気圧を与えることで, 温度変化を返します. 
  ! PHYCOOL 型の変数の終了処理には
  ! PhyCoolClose を用いてください.
  !
  ! First, initialize "PHYCOOL" by "PhyCoolCreate".
  ! "Cooling" receives temperature and surface pressure, and
  ! returns temperature tendency.
  ! In order to terminate "PHYCOOL", use "PhyCoolClose".
  !

  use dc_types, only: DP, TOKEN, STRING
  use dc_date_types, only: DC_DIFFTIME
  use gt4_history_nmlinfo, only: GTHST_NMLINFO
  implicit none
  private
  public:: PHYCOOL
  public:: PhyCoolCreate, Cooling
  public:: PhyCoolClose, PhyCoolPutLine
  public:: PhyCoolInitialized, PhyCoolSetTime

  type PHYCOOL
    !
    ! まず, PhyCoolCreate で "PHYCOOL" 型の
    ! 変数を初期設定して下さい. 
    ! 初期設定された "PHYCOOL" 型の変数を再度利用する際には,
    ! PhyCoolClose によって終了処理を行ってください.
    !
    ! Initialize "PHYCOOL" variable by 
    ! "PhyCoolCreate" before usage.
    ! If you reuse "PHYCOOL" variable again for another application, 
    ! terminate by "PhyCoolClose".
    !
    logical:: initialized = .false.
                              ! 初期設定フラグ. 
                              ! Initialization flag

    !-----------------------------------------------------------------
    !  格子点数・最大全波数
    !  Grid points and maximum truncated wavenumber
    !-----------------------------------------------------------------
    integer:: imax            ! 経度格子点数. 
                              ! Number of grid points in longitude
    integer:: jmax            ! 緯度格子点数. 
                              ! Number of grid points in latitude
    integer:: kmax            ! 鉛直層数. 
                              ! Number of vertical level

    !-----------------------------------------------------------------
    !  軸データ
    !  Axes data
    !-----------------------------------------------------------------
    real(DP), pointer:: x_Lon (:) =>null()
                              ! 経度. Longitude
    real(DP), pointer:: x_Lon_Weight (:) =>null()
                              ! 経度積分用座標重み. 
                              ! Weight for integration in longitude
    real(DP), pointer:: y_Lat (:) =>null()
                              ! 緯度. Latitude
    real(DP), pointer:: y_Lat_Weight (:) =>null()
                              ! 緯度積分用座標重み. 
                              ! Weight for integration in latitude
    real(DP), pointer:: z_Sigma (:) =>null()
                              ! $ \sigma $ レベル (整数). 
                              ! Full $ \sigma $ level
    real(DP), pointer:: z_DelSigma (:) =>null()
                              ! $ \Delta \sigma $ (整数). 
                              ! $ \Delta \sigma $ (Full)

    !-----------------------------------------------------------------
    !  係数
    !  Coefficients
    !-----------------------------------------------------------------
    real(DP):: day_seconds = 86400.0_DP
                              ! 一日の秒数. Seconds of one day
    real(DP):: DTempDdayCooling = -1.0_DP
                              ! 冷却の効果による一日あたりの温度変化.
                              ! Temperature tendency per day by cooling effect
    real(DP):: UpperPress = 1.0e4_DP
                              ! 冷却範囲の上端の気圧. 
                              ! Pressure in the top within the range of cooling
    real(DP):: LowerPress = 2.0e5_DP
                              ! 冷却範囲の下端の気圧. 
                              ! Pressure at bottom within the range of cooling

    !-----------------------------------------------------------------
    !  文字データ
    !  Character data
    !-----------------------------------------------------------------
!!$    character(TOKEN):: key00  ! キーワード. Keyword
!!$

    !-----------------------------------------------------------------
    !  時刻管理
    !  Time control
    !-----------------------------------------------------------------
    type(DC_DIFFTIME):: current_time
                              ! 現在時刻. Current time.
    type(DC_DIFFTIME):: delta_time
                              ! $ \Delta t $ . タイムステップ. Time step

    !-----------------------------------------------------------------
    !  ヒストリファイルへのデータ出力設定
    !  Configure the settings for history data output
    !-----------------------------------------------------------------
    type(GTHST_NMLINFO):: gthstnml
                              ! NAMELIST#phy_cooling_s08_history_nml 
                              ! から入手される個別のデータ出力情報. 
                              ! 
                              ! Individual data output information from 
                              ! "NAMELIST#phy_cooling_s08_history_nml". 
  end type PHYCOOL


  character(*), parameter:: version = &
    & '$Name: dcpam4-20080626 $' // &
    & '$Id: phy_cooling_s08.f90,v 1.1 2008-06-03 12:55:19 morikawa Exp $'

  !-----------------------------------------------------------------
  !  公開手続
  !  Public procedures
  !-----------------------------------------------------------------

  interface PhyCoolCreate
    module procedure PhyCoolCreate
  end interface

  interface Cooling
    module procedure PhyCoolCooling
  end interface

!!$  interface PhyCoolSample
!!$    module procedure PhyCoolSample
!!$  end interface

  interface PhyCoolClose
    module procedure PhyCoolClose
  end interface

  interface PhyCoolPutLine
    module procedure PhyCoolPutLine
  end interface

  interface PhyCoolinitialized
    module procedure PhyCoolInitialized
  end interface

  interface PhyCoolSetTime
    module procedure PhyCoolSetTime
  end interface

  !-----------------------------------------------------------------
  !  非公開手続
  !  Private procedures
  !-----------------------------------------------------------------

  interface NmlRead
    module procedure PhyCoolNmlRead
  end interface

contains

  subroutine PhyCoolCreate( phy_cool, &
    & imax, jmax, kmax, &
    & x_Lon, y_Lat, z_Sigma, &
    & DelTime, &
    & day_seconds, &
    & DTempDdayCooling, UpperPress, LowerPress, &
    & x_Lon_Weight, y_Lat_Weight, z_DelSigma, &
    & current_time_value, current_time_unit, &
    & history_varlist, &
    & history_interval_value, history_interval_unit, &
    & history_precision, history_fileprefix, &
    & nmlfile, err )
    !
    ! PHYCOOL 型の変数の初期設定を行います. 
    ! 他のサブルーチンを使用する前に必ずこのサブルーチンによって 
    ! PHYCOOL 型の変数を初期設定してください. 
    !
    ! なお, 与えられた *phy_cool* が既に初期設定されている場合, 
    ! プログラムはエラーを発生させます. 
    !
    ! NAMELIST を利用する場合には引数 *nmlfile* に NAMELIST ファイル名
    ! を与えてください. NAMELIST 変数群の詳細に関しては 
    ! NAMELIST#phy_cooling_s08_nml を参照してください. 
    !
    ! Constructor of "PHYCOOL". 
    ! Initialize *phy_cool* by this subroutine, 
    ! before other procedures are used, 
    !
    ! Note that if *phy_cool* is already initialized 
    ! by this procedure, error is occurred. 
    !
    ! In order to use NAMELIST, specify a NAMELIST filename to 
    ! argument *nmlfile*. See "NAMELIST#phy_cooling_s08_nml" 
    ! for details about a NAMELIST group. 
    !
    use dc_trace, only: BeginSub, EndSub
    use dc_string, only: PutLine, Printf, Split, StrInclude, StoA, JoinChar
    use dc_types, only: DP, STRING, TOKEN, STDOUT
    use dc_present, only: present_and_not_empty, present_and_true, &
      & present_select
    use dc_message, only: MessageNotify
    use dc_error, only: DC_NOERR, DC_EALREADYINIT, &
      & DC_EARGLACK, DC_ENEGATIVE, DC_ENOFILEREAD, USR_ERRNO, HST_EBADVARNAME
    use dcpam_error, only: StoreError, DCPAM_ESMALLVAL
    use dc_date, only: DCDiffTimeCreate
    use dc_hash, only: HASH, DCHashPut, DCHashRewind, DCHashNext, DCHashDelete
    use gt4_history_nmlinfo, only: HstNmlInfoCreate, HstNmlInfoAdd, &
      & HstNmlInfoEndDefine, HstNmlInfoPutLine, HstNmlInfoAllNameValid
    use gt4_history, only: GT_HISTORY, &
      & HistoryAddVariable, HistoryAddAttr
    implicit none
    type(PHYCOOL), intent(inout):: phy_cool
    integer, intent(in):: imax ! 経度格子点数. 
                               ! Number of grid points in longitude
    integer, intent(in):: jmax ! 緯度格子点数. 
                               ! Number of grid points in latitude
    integer, intent(in):: kmax ! 鉛直層数. 
                               ! Number of vertical level
    real(DP), intent(in):: x_Lon (0:imax-1)
                              ! 経度. Longitude
    real(DP), intent(in):: y_Lat (0:jmax-1)
                              ! 緯度. Latitude
    real(DP), intent(in):: z_Sigma (0:kmax-1)
                              ! $ \sigma $ レベル (整数). 
                              ! Full $ \sigma $ level
    real(DP), intent(in):: DelTime    ! $ \Delta t $ . タイムステップ. Time step
    real(DP), intent(in), optional:: day_seconds
                              ! 1 日の秒数. 
                              ! この引数を与えない場合, 1 日の秒数は
                              ! 86400.0 となります. 
                              ! 
                              ! Seconds in day. 
                              ! If this argument is not given, seconds in day
                              ! become 86400.0 .
    real(DP), intent(in), optional:: DTempDdayCooling
                              ! 冷却の効果による一日あたりの温度変化.
                              ! Temperature tendency per day by cooling effect
    real(DP), intent(in), optional:: UpperPress
                              ! 冷却範囲の上端の気圧. 
                              ! Pressure in the top within the range of cooling
    real(DP), intent(in), optional:: LowerPress
                              ! 冷却範囲の下端の気圧. 
                              ! Pressure at bottom within the range of cooling
    real(DP), intent(in), optional:: x_Lon_Weight (0:imax-1)
                              ! 経度積分用座標重み. 
                              ! Weight for integration in longitude
    real(DP), intent(in), optional:: y_Lat_Weight (0:jmax-1)
                              ! 緯度積分用座標重み. 
                              ! Weight for integration in latitude
    real(DP), intent(in), optional:: z_DelSigma (0:kmax-1)
                              ! $ \Delta \sigma $ (整数). 
                              ! $ \Delta \sigma $ (Full)


    real, intent(in), optional:: current_time_value
                              ! 現在時刻の数値. Numerical value of current time
    character(*), intent(in), optional:: current_time_unit
                              ! 現在時刻の単位. Unit of current time
    character(*), intent(in), optional:: history_varlist
                              ! ヒストリデータの出力変数リスト. 
                              ! カンマで区切って並べる. 
                              ! (例: "Data1,Data2" ). 
                              ! 
                              ! List of variables output to history data. 
                              ! Delimiter is comma. 
                              ! (exp. "Data1,Data2" ). 
                              ! 
    real, intent(in), optional:: history_interval_value
                              ! ヒストリデータの出力間隔の数値. 
                              ! Numerical value for interval of history data output
    character(*), intent(in), optional:: history_interval_unit
                              ! ヒストリデータの出力間隔の単位. 
                              ! Unit for interval of history data output
    character(*), intent(in), optional:: history_precision
                              ! ヒストリデータの精度. 
                              ! Precision of history data
    character(*), intent(in), optional:: history_fileprefix
                              ! ヒストリデータのファイル名の接頭詞. 
                              ! Prefix of history data filenames

    character(*), intent(in), optional:: nmlfile
                              ! NAMELIST ファイルの名称. 
                              ! この引数に空文字以外を与えた場合, 
                              ! 指定されたファイルから 
                              ! NAMELIST 変数群を読み込みます. 
                              ! ファイルを読み込めない場合にはエラーを
                              ! 生じます. 
                              !
                              ! NAMELIST 変数群の詳細に関しては 
                              ! NAMELIST#phy_cooling_s08_nml 
                              ! を参照してください. 
                              !
                              ! NAMELIST file name. 
                              ! If nonnull character is specified to 
                              ! this argument, 
                              ! NAMELIST group name is loaded from the 
                              ! file. 
                              ! If the file can not be read, 
                              ! an error occurs.
                              ! 
                              ! See "NAMELIST#phy_cooling_s08_nml" 
                              ! for details about a NAMELIST group. 
                              ! 

    logical, intent(out), optional:: err
                              ! 例外処理用フラグ. 
                              ! デフォルトでは, この手続き内でエラーが
                              ! 生じた場合, プログラムは強制終了します. 
                              ! 引数 *err* が与えられる場合, 
                              ! プログラムは強制終了せず, 代わりに
                              ! *err* に .true. が代入されます. 
                              !
                              ! Exception handling flag. 
                              ! By default, when error occur in 
                              ! this procedure, the program aborts. 
                              ! If this *err* argument is given, 
                              ! .true. is substituted to *err* and 
                              ! the program does not abort. 

    !-----------------------------------
    !  ヒストリファイルへのデータ出力設定
    !  Configure the settings for history data output
    character(STRING):: name = ''
                              ! 変数名. Variable identifier
    character(STRING):: longname = ''
                              ! 変数の記述的名称. Descriptive name of variables
    character(STRING), allocatable:: dims(:)
                              ! 座標軸の名称. Name of axes
    character(STRING):: units = ''
                              ! 単位. Units
    type(GT_HISTORY), pointer:: gthist =>null()
                              ! gt4_history モジュール用構造体. 
                              ! Derived type for "gt4_history" module
    character(TOKEN):: precision
                              ! ヒストリデータの精度. 
                              ! Precision of history data
    logical:: average
                              ! 出力データの平均化フラグ. 
                              ! Flag for average of output data
    type(HASH):: registered_varnames
                              ! このモジュールから出力される変数名のリスト.
                              ! 
                              ! List of names of variables output 
                              ! from this module. 
    logical:: hash_end
                              ! HASH オブジェクトの終了フラグ. 
                              ! 
                              ! End flag of "HASH" object
    logical:: allvar_invalid
                              ! 無効な変数名のチェックフラグ. 
                              ! 
                              ! Check flag of invalid variable names
    character(STRING):: names_invalid
                              ! 無効な変数名. 
                              ! 
                              ! Invalid variable names
    character(STRING):: nmlfile_msg
                              ! NAMELIST ファイル名に関するメッセージ. 
                              ! 
                              ! Messages about NAMELIST file name


    !-----------------------------------
    !  作業変数
    !  Work variables
    real(DP):: UpperPressCheck
                              ! 冷却範囲の上端の気圧. 
                              ! Pressure in the top within the range of cooling
    real(DP):: LowerPressCheck
                              ! 冷却範囲の下端の気圧. 
                              ! Pressure at bottom within the range of cooling

    integer:: stat
    character(STRING):: cause_c
    real(DP), parameter:: PI = 3.1415926535897930_DP
                                ! $ \pi $ . 円周率. Circular constant
    character(*), parameter:: subname = 'PhyCoolCreate'
  continue
    call BeginSub( subname, version )
    stat = DC_NOERR
    cause_c = ''

    !-----------------------------------------------------------------
    !  初期設定のチェック
    !  Check initialization
    !-----------------------------------------------------------------
    if ( phy_cool % initialized ) then
      stat = DC_EALREADYINIT
      cause_c = 'PHYCOOL'
      goto 999
    end if

    !-----------------------------------------------------------------
    !  引数の正当性のチェック
    !  Validate arguments
    !-----------------------------------------------------------------
    if (imax < 1) then
      stat = DC_ENEGATIVE
      cause_c = 'imax'
      goto 999
    end if
    if (jmax < 1) then
      stat = DC_ENEGATIVE
      cause_c = 'jmax'
      goto 999
    end if
    if (kmax < 1) then
      stat = DC_ENEGATIVE
      cause_c = 'kmax'
      goto 999
    end if
    if (DelTime < 0.0_DP) then
      stat = DC_ENEGATIVE
      cause_c = 'DelTime'
      goto 999
    end if
    if ( present(day_seconds) ) then
      if (day_seconds < 0.0_DP) then
        stat = DC_ENEGATIVE
        cause_c = 'day_seconds'
        goto 999
      end if
    end if
    if ( present(UpperPress) ) then
      if (UpperPress < 0.0_DP) then
        stat = DC_ENEGATIVE
        cause_c = 'UpperPress'
        goto 999
      end if
      UpperPressCheck = UpperPress
    else
      UpperPressCheck = phy_cool % UpperPress
    end if
    if ( present(LowerPress) ) then
      if (LowerPress < 0.0_DP) then
        stat = DC_ENEGATIVE
        cause_c = 'LowerPress'
        goto 999
      end if
      LowerPressCheck = LowerPress
    else
      LowerPressCheck = phy_cool % LowerPress
    end if
    if ( UpperPressCheck > LowerPressCheck ) then
      call MessageNotify( 'W', subname, &
        & 'UpperPress=<%f> must be smaller than LowerPress=<%f>.', &
        & d = (/ UpperPressCheck, LowerPressCheck /) )
      stat = DCPAM_ESMALLVAL
      cause_c = 'UpperPress'
      goto 999
    end if

    !-----------------------------------------------------------------
    !  波数・格子点の設定
    !  Configure wave number and grid point
    !-----------------------------------------------------------------
    phy_cool % imax  = imax 
    phy_cool % jmax  = jmax 
    phy_cool % kmax  = kmax 

    !-----------------------------------------------------------------
    !  座標軸の設定
    !  Configure axes
    !-----------------------------------------------------------------
    allocate( phy_cool % x_Lon (0:imax-1) )
    phy_cool % x_Lon = x_Lon

    allocate( phy_cool % y_Lat (0:jmax-1) )
    phy_cool % y_Lat = y_Lat

    allocate( phy_cool % z_Sigma (0:kmax-1) )
    phy_cool % z_Sigma = z_Sigma

    allocate( phy_cool % x_Lon_Weight (0:imax-1) )
    if ( present(x_Lon_Weight) ) then
      phy_cool % x_Lon_Weight = x_Lon_Weight
    else
      phy_cool % x_Lon_Weight = 2.0_DP * PI / imax
    end if

    allocate( phy_cool % y_Lat_Weight (0:jmax-1) )
    if ( present(y_Lat_Weight) ) then
      phy_cool % y_Lat_Weight = y_Lat_Weight
    else
      phy_cool % y_Lat_Weight = 2.0_DP / jmax
    end if

    allocate( phy_cool % z_DelSigma (0:kmax-1) )
    if ( present(z_DelSigma) ) then
      phy_cool % z_DelSigma = z_DelSigma
    else
      phy_cool % z_DelSigma = 1.0_DP / kmax
    end if

    !-----------------------------------------------------------------
    !  その他のパラメータの設定
    !  Other parameters are configured
    !-----------------------------------------------------------------
    if ( present(day_seconds) ) then
      phy_cool % day_seconds = day_seconds
    end if

    if ( present(DTempDdayCooling) ) then
      phy_cool % DTempDdayCooling = DTempDdayCooling
    end if

    if ( present(UpperPress) ) then
      phy_cool % UpperPress = UpperPress
    end if

    if ( present(LowerPress) ) then
      phy_cool % LowerPress = LowerPress
    end if

    !-----------------------------------------------------------------
    !  時刻管理
    !  Time control
    !-----------------------------------------------------------------
    if ( present(current_time_value) .and. present(current_time_unit) ) then
      call DCDiffTimeCreate( &
        & diff = phy_cool % current_time, &  ! (out)
        & value = real( current_time_value, DP ), & ! (in)
        & unit = current_time_unit )                ! (in)
    else
      call DCDiffTimeCreate( &
        & diff = phy_cool % current_time, & ! (out)
        & value = 0.0_DP, &    ! (in)
        & unit = 'sec' )       ! (in)
    end if

    call DCDiffTimeCreate( &
      & diff = phy_cool % delta_time, & ! (out)
      & value = DelTime, &             ! (in)
      & unit = 'sec' )                 ! (in)

    !-----------------------------------------------------------------
    !  ヒストリファイルへのデータ出力設定
    !  Configure the settings for history data output
    !-----------------------------------------------------------------

    !-------------------------
    !  デフォルト値
    !  Default values
    call HstNmlInfoCreate( gthstnml = phy_cool % gthstnml ) ! (inout)

    !-------------------------
    !  オプショナル引数からの値
    !  Values from optional arguments
    call HstNmlInfoAdd( &
      & gthstnml = phy_cool % gthstnml, &   ! (inout)
      & name = '', &                               ! (in)
      & interval_value = history_interval_value, & ! (in)
      & interval_unit = history_interval_unit, &   ! (in)
      & precision = history_precision, &           ! (in)
      & average = .false., &                       ! (in)
      & fileprefix = history_fileprefix )          ! (in)

    if ( present(history_varlist) ) then
      call HstNmlInfoAdd( &
        & gthstnml = phy_cool % gthstnml, & ! (inout)
        & name = history_varlist )                 ! (in)
    end if

    !-----------------------------------------------------------------
    !  NAMELIST からの値の読み込み
    !  Load values from NAMELIST
    !-----------------------------------------------------------------
    if ( present_and_not_empty(nmlfile) ) then
      call MessageNotify( 'M', subname, &
        & 'Loading NAMELIST file "%c" ...', &
        & c1 = trim(nmlfile) )
      call NmlRead ( nmlfile = nmlfile, &          ! (in)
        & DTempDdayCooling = phy_cool % DTempDdayCooling, & ! (inout)
        & UpperPress  = phy_cool % UpperPress, & ! (inout)
        & LowerPress  = phy_cool % LowerPress, & ! (inout)
        & gthstnml    = phy_cool % gthstnml, &  ! (inout)
        & err = err )                              ! (out)
      if ( present_and_true(err) ) then
        call MessageNotify( 'W', subname, &
          & '"%c" can not be read.', &
          & c1 = trim(nmlfile) )
        stat = DC_ENOFILEREAD
        cause_c = nmlfile
        goto 999
      end if
    end if

    call HstNmlInfoEndDefine( &
      & gthstnml = phy_cool % gthstnml, & ! (inout)
      & err = err )                              ! (out)
    if ( present_and_true( err ) ) then
      stat = USR_ERRNO
      goto 999
    end if


    !-----------------------------------------------------------------
    !  データ出力の初期設定
    !  Initialize data output
    !-----------------------------------------------------------------

    !-------------------------
    !  xyz_DTempDtCooling の出力設定
    !  Configure the settings for "xyz_DTempDtCooling" output
    name = 'DTempDtCooling'
    longname = 'temperature tendency by effect of radiation cooling like Jovian atmoshere'
    units = 'K s-1'
    allocate( dims(4) )
    dims = StoA( 'lon', 'lat', 'sig', 'time' )

    ! 出力ファイルの初期設定.
    !   * gthist (gt4_history#GT_HISTORY) が設定される.
    ! Initialize output file.
    !   * "gthist" (gt4_history#GT_HISTORY) is configured.
    call output_init  ! これは内部サブルーチン. This is an internal subroutine

!!$    ! 属性の付加などを行う場合には以下のようにする. 
!!$    ! Describe codes as follows in order to add attributes etc.
!!$    if ( associated( gthist ) ) then
!!$      call HistoryAddAttr( &
!!$        & history = gthist, &                           ! (inout)
!!$        & varname = name, attrname = 'missing_value', & ! (in)
!!$        &   value = 9999.0 )                            ! (in)
!!$    end if

    deallocate( dims )

!!$    !-------------------------
!!$    !  y_Data2 の出力設定
!!$    !  Configure the settings for "y_Data2" output
!!$    name = 'Data2'
!!$    longname = 'Sample data (2)'
!!$    units = '1'
!!$    allocate( dims(2) )
!!$    dims = StoA( 'lat', 'time' )
!!$
!!$    ! 出力ファイルの初期設定.
!!$    !   * gthist (gt4_history#GT_HISTORY) が設定される.
!!$    ! Initialize output file.
!!$    !   * "gthist" (gt4_history#GT_HISTORY) is configured.
!!$    call output_init  ! これは内部サブルーチン. This is an internal subroutine
!!$    deallocate( dims )

    !-----------------------------------------------------------------
    !  このモジュールから出力される変数名のリストを表示
    !  Print list of names of variables output from this module
    !-----------------------------------------------------------------
    call Printf( STDOUT, &
      & ' *** MESSAGE *** +---- "%c" module output varnames list -----', &
      & c1 = 'phy_cooling_s08' )
    call DCHashRewind( hashv = registered_varnames ) ! (inout)
    do
      call DCHashNext( hashv = registered_varnames, &    ! (inout)
        & key = name, value = longname, end = hash_end ) ! (out)
      if ( hash_end ) exit
      call Printf( STDOUT, &
        & ' *** MESSAGE *** |      "%c" (%c)', &
        & c1 = trim(name), c2 = trim(longname) )
    enddo
    call DCHashDelete( hashv = registered_varnames ) ! (inout)
    call Printf( STDOUT, &
      & ' *** MESSAGE *** `----------------------------------------' )

    !-----------------------------------------------------------------
    !  無効な変数名のチェック
    !  Check invalid variable names
    !-----------------------------------------------------------------
    call HstNmlInfoAllNameValid( &
      & gthstnml = phy_cool % gthstnml, &               ! (inout)
      & invalid = allvar_invalid, names = names_invalid, & ! (out)
      & err = err )                                        ! (out)

    if ( allvar_invalid ) then
      stat = HST_EBADVARNAME
      cause_c = names_invalid
      phy_cool % initialized = .true.
      call PhyCoolClose( phy_cool, & ! (inout)
        & err = err )                     ! (out)
      if ( present(nmlfile) ) then
        nmlfile_msg = ' or NAMELIST "phy_cooling_s08_history_nml" in "'// trim(nmlfile) // '"'
      else
        nmlfile_msg = ''
      end if
      call MessageNotify( 'W', subname, &
        & 'names "%c" from an optional argument "history_varlist"%c are invalid.', &
        & c1 = trim(names_invalid), &
        & c2 = trim(nmlfile_msg) )
      goto 999
    end if

    !-----------------------------------------------------------------
    !  設定値の正当性のチェック
    !  Validate setting values
    !-----------------------------------------------------------------
!!$    if ( phy_cool % CoefAlpha < 0.0_DP ) then
!!$      stat = DC_ENEGATIVE
!!$      cause_c = 'CoefAlpha'
!!$      goto 999
!!$    end if

    !-----------------------------------------------------------------
    !  終了処理, 例外処理
    !  Termination and Exception handling
    !-----------------------------------------------------------------
    phy_cool % initialized = .true.
999 continue
    call StoreError( stat, subname, err, cause_c )
    call EndSub( subname )

  contains

    subroutine output_init
      !
      ! 変数 *name* に関して出力ファイルの初期設定を行います. 
      ! 出力ファイル名や出力間隔などの情報は phy_cool % gthstnml 
      ! から取り出されます. 
      ! 
      ! 変数 *name* に関して出力が行われる場合には, 
      ! *gthist* に出力先ファイルの gt4_history#GT_HISTORY
      ! 型変数を結合させます. そうでない場合は, *gthist* を空状態にします. 
      !
      ! また, 出力データの精度を precision に, 
      ! 出力データ平均化の可否を average に設定します. 
      ! 
      ! 標準出力に表示される変数リスト *registered_varnames* に
      ! *name*, *longname*, *dims*, *units* が登録されます. 
      !
      ! An output file is initialized for a variable *name*. 
      ! Information such as the output filename and output intervals 
      ! is taken out of "phy_cool % gthstnml". 
      !
      ! When output is done for the variable *name*, *gthist* is 
      ! associated with the "gt4_history#GT_HISTORY" variable of 
      ! the output file. Otherwise, *gthist* is nullified. 
      !
      ! Moreover, the accuracy of output data is set to *precision*, and 
      ! right or wrong of averaging the output data is set to *average*. 
      !
      ! *name*, *longname*, *dims*, *units* are registered to 
      ! a list of variables *registered_varnames* that is printed to 
      ! standard output. 
      !
      use dc_date, only: DCDiffTimeCreate, EvalSec, EvalByUnit
      use gt4_history_nmlinfo, only: GTHST_NMLINFO, &
        & HstNmlInfoInitialized, HstNmlInfoInquire, &
        & HstNmlInfoOutputValid, HstNmlInfoAssocGtHist, HstNmlInfoPutLine, &
        & HstNmlInfoSetValidName
      use gt4_history, only: GT_HISTORY, &
        & HistoryCreate, HistoryAddVariable, HistoryPut, &
        & HistoryAddAttr, HistoryInitialized

      !-----------------------------------
      !  作業変数
      !  Work variables
      character(STRING):: file
                                ! ヒストリデータのファイル名. 
                                ! History data filenames
      character(STRING):: dims_str
                                ! 座標軸のリスト. 
                                ! List of axes
      real:: interval_value
                                ! ヒストリデータの出力間隔の数値. 
                                ! Numerical value for interval of history data output
      character(TOKEN):: interval_unit
                                ! ヒストリデータの出力間隔の単位. 
                                ! Unit for interval of history data output
      real(DP), parameter:: PI = 3.1415926535897930_DP
                                ! $ \pi $ . 円周率. Circular constant
    continue
      !-----------------------------------------------------------------
      !  標準出力に表示される変数の登録
      !  Register a variable name for print to standard output
      !-----------------------------------------------------------------
      if ( allocated(dims) ) then
        dims_str = JoinChar( dims, ',' )
      else
        dims_str = ''
      end if
      call DCHashPut( hashv = registered_varnames, &     ! (inout)
        & key = name, &                                  ! (in)
        & value = trim( longname ) // ' [' // &
        &         trim( units ) // '] {' // &
        &         trim( dims_str ) // '}' ) ! (in)

      !-----------------------------------------------------------------
      !  変数の初期化
      !  Initialize variable
      !-----------------------------------------------------------------
      nullify( gthist )
      precision = 'float'
      average = .false.

      !-----------------------------------------------------------------
      !  変数名の有効性を設定
      !  Set validation of the variable name
      !-----------------------------------------------------------------
      call HstNmlInfoSetValidName( &
        & gthstnml = phy_cool % gthstnml, & ! (in)
        & name = name )                        ! (in)

      !-----------------------------------------------------------------
      !  出力が有効かどうかを確認する
      !  Confirm whether the output is effective
      !-----------------------------------------------------------------
      if ( .not. HstNmlInfoOutputValid( phy_cool % gthstnml, name ) ) then
        return
      end if

      !-----------------------------------------------------------------
      !  GT_HISTORY 変数の取得
      !  Get "GT_HISTORY" variable
      !-----------------------------------------------------------------
      call HstNmlInfoAssocGtHist( &
        & gthstnml = phy_cool % gthstnml, & ! (in)
        & name = name, &                       ! (in)
        & history = gthist, &                  ! (out)
        & err = err )                          ! (out)
      if ( present_and_true( err ) ) return

      call HstNmlInfoInquire( &
        & gthstnml = phy_cool % gthstnml, & ! (in)
        & name = name, &                       ! (in)
        & precision = precision, &             ! (out)
        & average = average, &                 ! (out)
        & err = err )                          ! (out)
      if ( present_and_true( err ) ) return

      !-----------------------------------------------------------------
      !  GT_HISTORY 変数の初期設定の確認
      !  Check initialization of "GT_HISTORY" variable
      !-----------------------------------------------------------------
      if ( HistoryInitialized( gthist ) ) then

        !---------------------------------------------------------------
        !  HistoryAddVariable による変数作成
        !  A variable is created by "HistoryAddVariable"
        !---------------------------------------------------------------
        call HistoryAddVariable( &
          &  history = gthist, &                       ! (inout)
          &  varname = name,         dims = dims, &    ! (in)
          & longname = longname,    units = units, &   ! (in)
          &    xtype = precision, average = average )  ! (in)
        return
      end if

      !-----------------------------------------------------------------
      !  HistoryCreate のための設定値の取得
      !  Get the settings for "HistoryCreate"
      !-----------------------------------------------------------------
      call HstNmlInfoInquire( &
        & gthstnml = phy_cool % gthstnml, & ! (in)
        & name = name, &                       ! (in)
        & file = file, &                       ! (out)
        & interval_unit = interval_unit, &     ! (out)
        & interval_value = interval_value, &   ! (out)
        & err = err )                          ! (out)
      if ( present_and_true( err ) ) return

      !-----------------------------------------------------------------
      !  HistoryCreate によるファイル作成
      !  Files are created by "HistoryCreate"
      !-----------------------------------------------------------------
      call HistoryCreate( &
        & history = gthist, &   ! (out)
        & file = file, &        ! (in)
        & title = 'Cooling of atmospheric upper layer to imitate Jupiter', &  ! (in)
        & source = 'dcpam4 project : ' // trim(version), &       ! (in)
        & institution = 'GFD Dennou Club', &                     ! (in)
        & dims = StoA( 'lon', 'lat', 'sig', 'time' ), &          ! (in)
        & dimsizes = (/ phy_cool % imax, phy_cool % jmax, &
        &               phy_cool % kmax, 0 /), & ! (in)
        & longnames = StoA('longitude', 'latitude', &
        &                  'sigma at layer midpoints', &
        &                  'time'), &                            ! (in)
        & units = StoA( 'degree_east', 'degree_north', &
        &               '1', interval_unit ), &                  ! (in)
        & origin = real( EvalbyUnit( phy_cool % current_time, &
        &                            interval_unit) ), &         ! (in)
        & interval = interval_value, &                           ! (in)
        & err = err )                                            ! (out)
      if ( present_and_true( err ) ) then
        nullify( gthist )
        return
      end if

      call HistoryAddAttr( &
        & history = gthist, &                            ! (inout)
        & varname = 'lon', attrname = 'standard_name', & ! (in)
        & value = 'longitude' )                          ! (in)
      call HistoryAddAttr( &
        & history = gthist, &                            ! (inout)
        & varname = 'lat', attrname = 'standard_name', & ! (in)
        & value = 'latitude' )                           ! (in)
      call HistoryAddAttr( &
        & history = gthist, &                              ! (inout)
        & varname = 'sig', attrname = 'standard_name', &   ! (in)
        & value = 'atmosphere_sigma_coordinate' )          ! (in)
      call HistoryAddAttr( &
        & history = gthist, &                             ! (inout)
        & varname = 'time', attrname = 'standard_name', & ! (in)
        & value = 'time' )                                ! (in)
      call HistoryAddAttr( &
        & history = gthist, &                              ! (inout)
        & varname = 'sig', attrname = 'positive', &        ! (in)
        & value = 'down' )                                 ! (in)

      call HistoryPut( &
        & history = gthist, &                           ! (inout)
        & varname = 'lon', &                            ! (in)
        & array = phy_cool % x_Lon / PI * 180.0_DP ) ! (in)
      call HistoryPut( &
        & history = gthist, &                           ! (inout)
        & varname = 'lat', &                            ! (in)
        & array = phy_cool % y_Lat / PI * 180.0_DP ) ! (in)
      call HistoryPut( &
        & history = gthist, &             ! (inout)
        & varname = 'sig', &              ! (in)
        & array = phy_cool % z_Sigma ) ! (in)

      call HistoryAddVariable( &
        & history = gthist, &                                 ! (inout)
        & varname = 'lon_weight', &                           ! (in)
        & dims = StoA('lon'), &                               ! (in)
        & longname = 'weight for integration in longitude', & ! (in)
        & units = 'radian', xtype = 'double' )                ! (in)
      call HistoryAddAttr( &
        & history = gthist, &                                 ! (inout)
        & varname = 'lon', attrname = 'gt_calc_weight', &     ! (in)
        & value = 'lon_weight' )                              ! (in)
      call HistoryPut( &
        & history = gthist, &                     ! (inout)
        & varname = 'lon_weight', &               ! (in)
        & array = phy_cool % x_Lon_Weight )    ! (in)

      call HistoryAddVariable( &
        & history = gthist, &                                 ! (inout)
        & varname = 'lat_weight', &                           ! (in)
        & dims = StoA('lat'), &                               ! (in)
        & longname = 'weight for integration in latitude', &  ! (in)
        & units = 'radian', xtype = 'double' )                ! (in)
      call HistoryAddAttr( &
        & history = gthist, &                                 ! (inout)
        & varname = 'lat', attrname = 'gt_calc_weight', &     ! (in)
        & value = 'lat_weight' )                              ! (in)
      call HistoryPut( &
        & history = gthist, &                     ! (inout)
        & varname = 'lat_weight', &               ! (in)
        & array = phy_cool % y_Lat_Weight )    ! (in)

      call HistoryAddVariable( &
        & history = gthist, &                                 ! (inout)
        & varname = 'sig_weight', &                           ! (in)
        & dims = StoA('sig'), &                               ! (in)
        & longname = 'weight for integration in sigma', &     ! (in)
        & units = '1', xtype = 'float' )                      ! (in)
      call HistoryAddAttr( &
        & history = gthist, &                                 ! (inout)
        & varname = 'sig', attrname = 'gt_calc_weight', &     ! (in)
        & value = 'sig_weight' )                              ! (in)
      call HistoryPut( &
        & history = gthist, &                     ! (inout)
        & varname = 'sig_weight', &               ! (in)
        & array = phy_cool % z_DelSigma )      ! (in)

      !-----------------------------------------------------------------
      !  HistoryAddVariable による変数作成
      !  A variable is created by "HistoryAddVariable"
      !-----------------------------------------------------------------
      if ( HistoryInitialized( gthist ) ) then
        call HistoryAddVariable( &
          &  history = gthist, &                       ! (inout)
          &  varname = name,         dims = dims, &    ! (in)
          & longname = longname,    units = units, &   ! (in)
          &    xtype = precision, average = average )  ! (in)
      else
        nullify( gthist )
      end if

    end subroutine output_init

  end subroutine PhyCoolCreate

  subroutine PhyCoolCooling( phy_cool, &
!!$    & xyz_Temp, &
    & xy_Ps, xyz_DTempDtCooling, &
    & historyput_flag, &
    & err )
    !--
    ! 温度 *xyz_Temp* と
    !++
    ! 地表面気圧 *xy_Ps* から, 
    ! 冷却の効果による温度変化 *xyz_DTempDtCooling* を算出して返します. 
    ! 計算後, *phy_cool* 内の時刻を更新します. 
    !
    ! なお, 与えられた *phy_cool* が PhyCoolCreate 
    ! によって初期設定されていない場合, プログラムはエラーを発生させます. 
    !
    ! Calculate and return 
    ! temperature tendency by cooling effect *xyz_DTempDtCooling*
    ! from 
    !--
    ! temperature *xyz_Temp* and 
    !++
    ! surface pressure *xy_Ps*.
    ! After the calculation, time stored in *phy_cool* is updated. 
    !
    ! If *phy_cool* is not initialized 
    ! by "PhyCoolCreate" yet, error is occurred. 
    !
    use dc_trace, only: BeginSub, EndSub
    use dc_string, only: PutLine, Printf, Split, StrInclude, StoA, JoinChar
    use dc_types, only: DP, STRING, TOKEN, STDOUT
    use dc_present, only: present_and_true
    use dc_date, only: mod, operator(+), operator(==), EvalbyUnit, EvalSec
    use dc_error, only: StoreError, DC_NOERR, DC_ENOTINIT, USR_ERRNO
    use gt4_history_nmlinfo, only: HstNmlInfoInquire, &
      & HstNmlInfoOutputValid, HstNmlInfoAssocGtHist, HstNmlInfoPutLine
    use gt4_history, only: GT_HISTORY, HistoryPut, HistoryInitialized
    implicit none
    type(PHYCOOL), intent(inout):: phy_cool

!!$    real(DP), intent(in):: xyz_Temp (0:phy_cool%imax-1, 0:phy_cool%jmax-1, 0:phy_cool%kmax-1)
!!$                              ! $ T $ .     温度. Temperature

    real(DP), intent(in):: xy_Ps  (0:phy_cool%imax-1, 0:phy_cool%jmax-1)
                              ! $ p_s $ .   地表面気圧. Surface pressure
    real(DP), intent(out):: xyz_DTempDtCooling (0:phy_cool%imax-1, 0:phy_cool%jmax-1, 0:phy_cool%kmax-1)
                              ! $ \DP{T}{t} $ . 
                              ! 冷却の効果による温度変化. 
                              ! Temperature tendency by cooling effect
    logical, intent(in), optional:: historyput_flag
                              ! データ出力のフラグ. 
                              ! SetTime によって時刻を明示的に
                              ! 指定した場合には, この引数に
                              ! .true. または .false. を指定する
                              ! ことでデータ出力のオンオフを
                              ! 明示的に指定する必要があります. 
                              ! デフォルトは .false. です. 
                              ! 
                              ! Data output flag. 
                              ! When time is specified by "SetTime", 
                              ! explicit specification of data output 
                              ! on/off by specifying ".true." or ".false." 
                              ! to this argument. 
                              ! Default value is ".false.". 
                              ! 
    logical, intent(out), optional:: err
                              ! 例外処理用フラグ. 
                              ! デフォルトでは, この手続き内でエラーが
                              ! 生じた場合, プログラムは強制終了します. 
                              ! 引数 *err* が与えられる場合, 
                              ! プログラムは強制終了せず, 代わりに
                              ! *err* に .true. が代入されます. 
                              !
                              ! Exception handling flag. 
                              ! By default, when error occur in 
                              ! this procedure, the program aborts. 
                              ! If this *err* argument is given, 
                              ! .true. is substituted to *err* and 
                              ! the program does not abort. 

    !-----------------------------------
    !  *phy_cool* から取り出される設定値
    !  Setting values fetched from *phy_cool*
    integer:: imax            ! 経度格子点数. 
                              ! Number of grid points in longitude
    integer:: jmax            ! 緯度格子点数. 
                              ! Number of grid points in latitude
    integer:: kmax            ! 鉛直層数. 
                              ! Number of vertical level

    real(DP):: z_Sigma (0:phy_cool%kmax-1)
                              ! $ \sigma $ レベル (整数). 
                              ! Full $ \sigma $ level

    real(DP):: day_seconds
                              ! 一日の秒数. Seconds of one day
    real(DP):: DTempDdayCooling
                              ! 冷却の効果による一日あたりの温度変化.
                              ! Temperature tendency per day by cooling effect
    real(DP):: UpperPress
                              ! 冷却範囲の上端の気圧. 
                              ! Pressure in the top within the range of cooling
    real(DP):: LowerPress
                              ! 冷却範囲の下端の気圧. 
                              ! Pressure at bottom within the range of cooling

    !-----------------------------------
    !  ヒストリファイルへのデータ出力設定
    !  Configure the settings for history data output
    character(STRING):: name = ''
                              ! 変数名. Variable identifier
    real:: time
                              ! 時刻. Time
    type(GT_HISTORY), pointer:: gthist =>null()
                              ! gt4_history モジュール用構造体. 
                              ! Derived type for "gt4_history" module

    !-----------------------------------
    !  作業変数
    !  Work variables
    real(DP):: xyz_Press (0:phy_cool%imax-1, 0:phy_cool%jmax-1, 0:phy_cool%kmax-1)
                              ! $ p $ .     気圧. Air pressure

    integer:: i, j, k         ! DO ループ用作業変数
                              ! Work variables for DO loop

    integer:: stat
    character(STRING):: cause_c
    character(*), parameter:: subname = 'Cooling'
  continue
    call BeginSub( subname )
    stat = DC_NOERR
    cause_c = ''

    !-----------------------------------------------------------------
    !  初期設定のチェック
    !  Check initialization
    !-----------------------------------------------------------------
    if ( .not. phy_cool % initialized ) then
      stat = DC_ENOTINIT
      cause_c = 'PHYCOOL'
      goto 999
    end if

    !-----------------------------------------------------------------
    !  *phy_cool* に格納されている設定値の取り出し
    !  Fetch setting values stored in *phy_cool*
    !-----------------------------------------------------------------
    imax  = phy_cool % imax 
    jmax  = phy_cool % jmax 
    kmax  = phy_cool % kmax 

    z_Sigma  =  phy_cool % z_Sigma 

    day_seconds  =  phy_cool % day_seconds
    DTempDdayCooling  = phy_cool % DTempDdayCooling 
    UpperPress  = phy_cool % UpperPress 
    LowerPress  = phy_cool % LowerPress 


    !-----------------------------------------------------------------
    !  時間変化の演算
    !  Calculate tendency
    !-----------------------------------------------------------------
    do k = 0, kmax-1
      xyz_Press(:,:,k) = xy_Ps * z_Sigma(k)
    end do

    xyz_DTempDtCooling = 0.0_DP
    do k = 0, kmax-1
      do j = 0, jmax-1
        do i = 0, imax-1
          if ( ( xyz_Press(i,j,k) < LowerPress ) &
            &  .and. ( xyz_Press(i,j,k) > UpperPress ) ) then
            xyz_DTempDtCooling(i,j,k) = DTempDdayCooling / day_seconds
          end if
        end do
      end do
    end do

    !----------------------------------------------------------------
    !  ヒストリファイルへのデータ出力
    !  History data output
    !----------------------------------------------------------------

    !-----------------------------------
    !  xyz_DTempDtCooling の出力
    !  Output "xyz_DTempDtCooling"
    name = 'DTempDtCooling'

    ! 出力のチェック. 
    !   * gthist (gt4_history#GT_HISTORY), time (単精度実数型) が設定される.
    ! Check for output.
    !   * "gthist" (gt4_history#GT_HISTORY), time (real) are configured.
    call output_check ! これは内部サブルーチン. This is an internal subroutine

    ! 出力データを引数 array に渡す.
    ! Give output data to argument "array"
    if ( associated( gthist ) ) then
      call HistoryPut( &
        & history = gthist, &                ! (inout)
        & varname = name, array = xyz_DTempDtCooling, & ! (in)
        & time = time, quiet = .false., &    ! (in)
        & err = err )                        ! (out)
    end if

!!$    !-----------------------------------
!!$    !  y_Data2 の出力
!!$    !  Output "y_Data2"
!!$    name = 'Data2'
!!$
!!$    ! 出力のチェック. 
!!$    !   * gthist (gt4_history#GT_HISTORY), time (単精度実数型) が設定される.
!!$    ! Check for output.
!!$    !   * "gthist" (gt4_history#GT_HISTORY), time (real) are configured.
!!$    call output_check ! これは内部サブルーチン. This is an internal subroutine
!!$
!!$    ! 出力データを引数 array に渡す.
!!$    ! Give output data to argument "array"
!!$    if ( associated( gthist ) ) then
!!$      call HistoryPut( &
!!$        & history = gthist, &                ! (inout)
!!$        & varname = name, array = y_Data2, & ! (in)
!!$        & time = time, quiet = .false., &    ! (in)
!!$        & err = err )                        ! (out)
!!$    end if

    !-----------------------------------------------------------------
    !  時刻の更新
    !  Update time
    !-----------------------------------------------------------------
    phy_cool % current_time = &
      & phy_cool % current_time + phy_cool % delta_time

    !-----------------------------------------------------------------
    !  終了処理, 例外処理
    !  Termination and Exception handling
    !-----------------------------------------------------------------
999 continue
    call StoreError( stat, subname, err, cause_c )
    call EndSub( subname )

  contains

    subroutine output_check
      !
      ! 変数 *name* を出力するかどうかをチェックします. 
      ! 出力に関する情報は dcm_sam_cod % gthstnml から取り出されます. 
      !
      ! 変数 *name* に関して出力するよう設定されている場合には, 
      ! *gthist* に出力先ファイルの gt4_history#GT_HISTORY
      ! 型変数を結合させます. そうでない場合は, *gthist* を空状態にします. 
      !
      ! また, 現在時刻を *time* に設定します. 
      !
      ! Check whether to output variable *name*. 
      ! Information about output is taken out of "dcm_sam_cod % gthstnml". 
      !
      ! When output is done for the variable *name*, *gthist* is 
      ! associated with "gt4_history#GT_HISTORY" variable of
      ! the output file. Otherwise, *gthist* is nullified. 
      !
      ! Moreover, current time is set to *time*. 
      !
      character(TOKEN):: interval_unit
                                ! ヒストリデータの出力間隔の単位. 
                                ! Unit for interval of history data output
    continue

      nullify( gthist )
      time = 0.0

      if ( HstNmlInfoOutputValid( phy_cool % gthstnml, name ) ) then
        call HstNmlInfoInquire( &
          & gthstnml = phy_cool % gthstnml, & ! (in)
          & name = name, &                           ! (in)
          & interval_unit = interval_unit )          ! (out)

        time = real( EvalbyUnit( phy_cool % current_time, interval_unit ) )
        if ( present_and_true( historyput_flag ) ) time = 0.0

        call HstNmlInfoAssocGtHist( & 
          & gthstnml = phy_cool % gthstnml, & ! (in)
          & name = name, &                           ! (in)
          & history = gthist, err = err )            ! (out)
        if ( present_and_true( err ) ) then
          nullify( gthist )
          return
        end if

        if ( .not. HistoryInitialized( gthist ) ) nullify( gthist )
      end if

    end subroutine output_check
  end subroutine PhyCoolCooling

!!$  subroutine PhyCoolSample( phy_cool, err )
!!$    !--
!!$    ! PhyCoolSample の要約を記述してください. 
!!$    !++
!!$    ! なお, 与えられた *phy_cool* が PhyCoolCreate 
!!$    ! によって初期設定されていない場合, プログラムはエラーを発生させます. 
!!$    !--
!!$    ! Describe brief of "PhyCoolSample". 
!!$    !++
!!$    ! If *phy_cool* is not initialized 
!!$    ! by "PhyCoolCreate" yet, error is occurred.
!!$    !
!!$    use dc_trace, only: BeginSub, EndSub
!!$    use dc_string, only: PutLine, Printf, Split, StrInclude, StoA, JoinChar
!!$    use dc_types, only: DP, STRING, TOKEN, STDOUT
!!$    use dc_error, only: StoreError, DC_NOERR, DC_ENOTINIT
!!$    implicit none
!!$    type(PHYCOOL), intent(inout):: phy_cool
!!$    logical, intent(out), optional:: err
!!$                              ! 例外処理用フラグ. 
!!$                              ! デフォルトでは, この手続き内でエラーが
!!$                              ! 生じた場合, プログラムは強制終了します. 
!!$                              ! 引数 *err* が与えられる場合, 
!!$                              ! プログラムは強制終了せず, 代わりに
!!$                              ! *err* に .true. が代入されます. 
!!$                              !
!!$                              ! Exception handling flag. 
!!$                              ! By default, when error occur in 
!!$                              ! this procedure, the program aborts. 
!!$                              ! If this *err* argument is given, 
!!$                              ! .true. is substituted to *err* and 
!!$                              ! the program does not abort. 
!!$
!!$    !-----------------------------------
!!$    !  *phy_cool* から取り出される設定値
!!$    !  Setting values fetched from *phy_cool*
!!$!!$    real(DP):: CoefAlpha      ! $ \alpha $ . 係数. Coefficient
!!$!!$    real(DP):: DelTime        ! $ \Delta t $ . タイムステップ. Time step
!!$
!!$    !-----------------------------------
!!$    !  作業変数
!!$    !  Work variables
!!$    integer:: stat
!!$    character(STRING):: cause_c
!!$    character(*), parameter:: subname = 'PhyCoolSample'
!!$  continue
!!$    call BeginSub( subname )
!!$    stat = DC_NOERR
!!$    cause_c = ''
!!$
!!$    !-----------------------------------------------------------------
!!$    !  初期設定のチェック
!!$    !  Check initialization
!!$    !-----------------------------------------------------------------
!!$    if ( .not. phy_cool % initialized ) then
!!$      stat = DC_ENOTINIT
!!$      cause_c = 'PHYCOOL'
!!$      goto 999
!!$    end if
!!$
!!$    !-----------------------------------------------------------------
!!$    !  *phy_cool* に格納されている設定値の取り出し
!!$    !  Fetch setting values stored in *phy_cool*
!!$    !-----------------------------------------------------------------
!!$!!$    CoefAlpha = phy_cool % CoefAlpha
!!$!!$    DelTime   = phy_cool % DelTime
!!$
!!$    !-----------------------------------------------------------------
!!$    !  終了処理, 例外処理
!!$    !  Termination and Exception handling
!!$    !-----------------------------------------------------------------
!!$999 continue
!!$    call StoreError( stat, subname, err, cause_c )
!!$    call EndSub( subname )
!!$
!!$  end subroutine PhyCoolSample

  subroutine PhyCoolClose( phy_cool, err )
    !
    ! PHYCOOL 型の変数の終了処理を行います. 
    ! なお, 与えられた *phy_cool* が PhyCoolCreate 
    ! によって初期設定されていない場合, プログラムはエラーを発生させます. 
    !
    ! Deconstructor of "PHYCOOL". 
    ! Note that if *phy_cool* is not initialized 
    ! by "PhyCoolCreate" yet, error is occurred. 
    !
    use dc_trace, only: BeginSub, EndSub
    use dc_string, only: PutLine, Printf, Split, StrInclude, StoA, JoinChar
    use dc_types, only: DP, STRING, TOKEN, STDOUT
    use dc_error, only: StoreError, DC_NOERR, DC_ENOTINIT
    use gt4_history_nmlinfo, only: HstNmlInfoClose, HstNmlInfoNames, &
      & HstNmlInfoAssocGtHist, HstNmlInfoPutLine
    use gt4_history, only: GT_HISTORY, HistoryClose, HistoryInitialized
    implicit none
    type(PHYCOOL), intent(inout):: phy_cool
    logical, intent(out), optional:: err
                              ! 例外処理用フラグ. 
                              ! デフォルトでは, この手続き内でエラーが
                              ! 生じた場合, プログラムは強制終了します. 
                              ! 引数 *err* が与えられる場合, 
                              ! プログラムは強制終了せず, 代わりに
                              ! *err* に .true. が代入されます. 
                              !
                              ! Exception handling flag. 
                              ! By default, when error occur in 
                              ! this procedure, the program aborts. 
                              ! If this *err* argument is given, 
                              ! .true. is substituted to *err* and 
                              ! the program does not abort. 

    !-----------------------------------
    !  ヒストリファイルへのデータ出力設定
    !  Configure the settings for history data output
    character(STRING):: name = ''
                              ! 変数名. Variable identifier
    character(STRING):: varnames
                              ! 変数名リスト. 
                              ! List of variables
    character(TOKEN), pointer:: varnames_array(:) =>null()
                              ! 変数名リスト配列. 
                              ! List of variables (array) 
    integer:: i, vnmax
    type(GT_HISTORY), pointer:: gthist =>null()
                              ! gt4_history モジュール用構造体. 
                              ! Derived type for "gt4_history" module

    !-----------------------------------
    !  作業変数
    !  Work variables
    integer:: stat
    character(STRING):: cause_c
    character(*), parameter:: subname = 'PhyCoolClose'
  continue
    call BeginSub( subname )
    stat = DC_NOERR
    cause_c = ''

    !-----------------------------------------------------------------
    !  初期設定のチェック
    !  Check initialization
    !-----------------------------------------------------------------
    if ( .not. phy_cool % initialized ) then
      stat = DC_ENOTINIT
      cause_c = 'PHYCOOL'
      goto 999
    end if

    !-----------------------------------------------------------------
    !  "PHYCOOL" の設定の消去
    !  Clear the settings for "PHYCOOL"
    !-----------------------------------------------------------------
    deallocate( phy_cool % x_Lon )
    deallocate( phy_cool % x_Lon_Weight )
    deallocate( phy_cool % y_Lat )
    deallocate( phy_cool % y_Lat_Weight )
    deallocate( phy_cool % z_Sigma )
    deallocate( phy_cool % z_DelSigma )
    phy_cool % day_seconds = 86400.0_DP
    phy_cool % DTempDdayCooling = -1.0_DP
    phy_cool % UpperPress = 1.0e4_DP
    phy_cool % LowerPress = 2.0e5_DP

    !-----------------------------------------------------------------
    !  ヒストリファイルへのデータ出力の終了処理
    !  Terminate the settings for history data output
    !-----------------------------------------------------------------
    varnames = HstNmlInfoNames( phy_cool % gthstnml )
    call Split( str = varnames, sep = ',', & ! (in)
      & carray = varnames_array )            ! (out)
    vnmax = size( varnames_array )

    do i = 1, vnmax
      name = varnames_array(i)
      if ( trim( name ) == '' ) exit
      nullify( gthist )
      call HstNmlInfoAssocGtHist( & 
        & gthstnml = phy_cool % gthstnml, & ! (in)
        & name = name, &                           ! (in)
        & history = gthist, &                      ! (out)
        & err = err )                              ! (out)
      if ( HistoryInitialized( gthist ) ) then

        call HistoryClose( history = gthist, & ! (inout)
          & err = err )                        ! (out)

      end if
    end do

    !-----------------------------------------------------------------
    !  ヒストリファイルへのデータ出力設定の割付解除
    !  Deallocate the settings for history data output
    !-----------------------------------------------------------------
    call HstNmlInfoClose( &
      & phy_cool % gthstnml, & ! (inout)
      & err = err )                   ! (out)

    !-----------------------------------------------------------------
    !  終了処理, 例外処理
    !  Termination and Exception handling
    !-----------------------------------------------------------------
    phy_cool % initialized = .false.
999 continue
    call StoreError( stat, subname, err, cause_c )
    call EndSub( subname )

  end subroutine PhyCoolClose

  subroutine PhyCoolPutLine( phy_cool, unit, indent, err )
    !
    ! 引数 *phy_cool* に設定されている情報を印字します. 
    ! デフォルトではメッセージは標準出力に出力されます. 
    ! *unit* に装置番号を指定することで, 出力先を変更することが可能です. 
    !
    ! Print information of *phy_cool*. 
    ! By default messages are output to standard output. 
    ! Unit number for output can be changed by *unit* argument. 
    !
    use dc_trace, only: BeginSub, EndSub
    use dc_string, only: PutLine, Printf, Split, StrInclude, StoA, JoinChar
    use dc_types, only: DP, STRING, TOKEN, STDOUT
    use dc_date, only: EvalSec
    use dc_error, only: StoreError, DC_NOERR, DC_ENOTINIT
    use gt4_history_nmlinfo, only: GTHST_NMLINFO, HstNmlInfoPutLine
    implicit none
    type(PHYCOOL), intent(in):: phy_cool
    integer, intent(in), optional:: unit
                              ! 出力先の装置番号. 
                              ! デフォルトの出力先は標準出力. 
                              !
                              ! Unit number for output. 
                              ! Default value is standard output. 
    character(*), intent(in), optional:: indent
                              ! 表示されるメッセージの字下げ. 
                              !
                              ! Indent of displayed messages. 
    logical, intent(out), optional:: err
                              ! 例外処理用フラグ. 
                              ! デフォルトでは, この手続き内でエラーが
                              ! 生じた場合, プログラムは強制終了します. 
                              ! 引数 *err* が与えられる場合, 
                              ! プログラムは強制終了せず, 代わりに
                              ! *err* に .true. が代入されます. 
                              !
                              ! Exception handling flag. 
                              ! By default, when error occur in 
                              ! this procedure, the program aborts. 
                              ! If this *err* argument is given, 
                              ! .true. is substituted to *err* and 
                              ! the program does not abort. 

    !-----------------------------------
    !  作業変数
    !  Work variables
    integer:: stat
    character(STRING):: cause_c
    integer:: out_unit
    integer:: indent_len
    character(STRING):: indent_str
    character(*), parameter:: subname = 'PhyCoolPutLine'
  continue
    call BeginSub( subname )
    stat = DC_NOERR
    cause_c = ''

    !-----------------------------------------------------------------
    !  出力先装置番号と字下げの設定
    !  Configure output unit number and indents
    !-----------------------------------------------------------------
    if ( present(unit) ) then
      out_unit = unit
    else
      out_unit = STDOUT
    end if

    indent_len = 0
    indent_str = ''
    if ( present(indent) ) then
      if ( len(indent) /= 0 ) then
        indent_len = len(indent)
        indent_str(1:indent_len) = indent
      end if
    end if

    !-----------------------------------------------------------------
    !  "PHYCOOL" の設定の印字
    !  Print the settings for "PHYCOOL"
    !-----------------------------------------------------------------
    if ( phy_cool % initialized ) then
      call Printf( unit = out_unit, &              ! (in)
        & fmt = indent_str(1:indent_len) // & 
        &       '#<PHYCOOL:: @initialized=%y', & ! (in)
        & l = (/ phy_cool % initialized /) )    ! (in)

      call Printf( unit = out_unit, &             ! (in)
        & fmt = indent_str(1:indent_len) // &
        &       ' @imax=%d @jmax=%d @kmax=%d', &  ! (in)
        & i = (/ phy_cool % imax, phy_cool % jmax, &
        &        phy_cool % kmax /) )          ! (in)

      call Printf( unit = out_unit, &                             ! (in)
        & fmt = indent_str(1:indent_len) // &
        &       ' @current_time=%f [sec] @delta_time=%f [sec]', & ! (in)
        & d = (/ EvalSec( phy_cool % current_time ), &
        &        EvalSec( phy_cool % delta_time ) /) )      ! (in)

      call Printf( unit = out_unit, &         ! (in)
        & fmt = indent_str(1:indent_len) // &
        &       ' @day_seconds=%f', &         ! (in)
        & d = (/phy_cool % day_seconds/) ) ! (in)

      call Printf( unit = out_unit, &         ! (in)
        & fmt = indent_str(1:indent_len) // &
        &       ' @DTempDdayCooling=%f', &         ! (in)
        & d = (/phy_cool % DTempDdayCooling/) ) ! (in)

      call Printf( unit = out_unit, &         ! (in)
        & fmt = indent_str(1:indent_len) // &
        &       ' @UpperPress=%f, @LowerPress=%f', &                   ! (in)
        & d = (/phy_cool % UpperPress, phy_cool % LowerPress/) ) ! (in)

      call PutLine( array = phy_cool % x_Lon, & ! (in)
        & unit = out_unit, &                           ! (in)
        & lbounds = lbound(phy_cool % x_Lon), & ! (in)
        & ubounds = ubound(phy_cool % x_Lon), & ! (in)
        & indent = indent_str(1:indent_len) // &
        &          ' @x_Lon=' )                        ! (in)

      call PutLine( array = phy_cool % y_Lat, & ! (in)
        & unit = out_unit, &                           ! (in)
        & lbounds = lbound(phy_cool % y_Lat), & ! (in)
        & ubounds = ubound(phy_cool % y_Lat), & ! (in)
        & indent = indent_str(1:indent_len) // &
        &          ' @y_Lat=' )                        ! (in)

      call PutLine( array = phy_cool % z_Sigma, & ! (in)
        & unit = out_unit, &                         ! (in)
        & lbounds = lbound(phy_cool % z_Sigma), & ! (in)
        & ubounds = ubound(phy_cool % z_Sigma), & ! (in)
        & indent = indent_str(1:indent_len) // &
        &          ' @z_Sigma=' )                    ! (in)

      call Printf( unit = out_unit, &         ! (in)
        & fmt = indent_str(1:indent_len) // &
        &       ' @gthstnml=' )               ! (in)
      call HstNmlInfoPutLine( &
        & gthstnml = phy_cool % gthstnml, &    ! (in)
        & unit = out_unit, &                          ! (in)
        & indent = indent_str(1:indent_len) // '  ' ) ! (in)

      call Printf( unit = out_unit, &             ! (in)
        & fmt = indent_str(1:indent_len) // '>' ) ! (in)
    else
      call Printf( unit = out_unit, &                   ! (in)
        & fmt = indent_str(1:indent_len) // &           ! (in)
        &       '#<PHYCOOL:: @initialized=%y>', &  ! (in)
        & l = (/phy_cool % initialized/) )       ! (in)
    end if

    !-----------------------------------------------------------------
    !  終了処理, 例外処理
    !  Termination and Exception handling
    !-----------------------------------------------------------------
999 continue
    call StoreError( stat, subname, err, cause_c )
    call EndSub( subname )

  end subroutine PhyCoolPutLine

  logical function PhyCoolInitialized( phy_cool ) result(result)
    !
    ! *phy_cool* が初期設定されている場合には .true. が, 
    ! 初期設定されていない場合には .false. が返ります. 
    !
    ! If *phy_cool* is initialized, .true. is returned. 
    ! If *phy_cool* is not initialized, .false. is returned. 
    !
    implicit none
    type(PHYCOOL), intent(in):: phy_cool
  continue
    result = phy_cool % initialized
  end function PhyCoolInitialized

  subroutine PhyCoolSetTime( phy_cool, &
    & current_time_value, current_time_unit, &
    & err )
    !
    ! *phy_cool* に対して時刻の設定を行います. 
    !
    ! ヒストリデータを出力している場合には, 
    ! ヒストリデータの出力時刻も設定します. 
    ! 一度でもこのサブルーチンを呼んだ場合には, 
    ! それ以後のヒストリデータ出力前にこのサブルーチンを呼び出し, 
    ! 時刻の設定を行ってください. 
    ! また, データを出力するサブルーチンに対しても 
    ! オプショナル引数 historyput_flag に .true. を与えてください. 
    !
    ! なお, 与えられた *phy_cool* が PhyCoolCreate 
    ! によって初期設定されていない場合, プログラムはエラーを発生させます. 
    !
    ! Set time to *phy_cool*. 
    !
    ! When history data are output, 
    ! the output time of history data are specified. 
    ! Once this subroutine is called, the time of history data must be 
    ! specified by this routine before history data output. 
    ! In additional, give ".true." to an optional argument 
    ! "historyput_flag" of a data output subroutine. 
    !
    ! If *phy_cool* is not initialized 
    ! by "PhyCoolCreate" yet, error is occurred. 
    !
    use dc_trace, only: BeginSub, EndSub
    use dc_string, only: PutLine, Printf, Split, StrInclude, StoA, JoinChar
    use dc_types, only: DP, STRING, TOKEN, STDOUT
    use dc_date, only: DCDiffTimeCreate, EvalbyUnit
    use dc_error, only: StoreError, DC_NOERR, DC_ENOTINIT
    use gt4_history_nmlinfo, only: HstNmlInfoAdd, HstNmlInfoInquire, &
      & HstNmlInfoNames, HstNmlInfoAssocGtHist, &
      & HstNmlInfoOutputStepDisable, HstNmlInfoPutLine
    use gt4_history, only: GT_HISTORY, HistorySetTime, HistoryInitialized
    implicit none
    type(PHYCOOL), intent(inout):: phy_cool
    real, intent(in):: current_time_value
                              ! 現在時刻の数値. Numerical value of current time
    character(*), intent(in):: current_time_unit
                              ! 現在時刻の単位. Unit of current time
    logical, intent(out), optional:: err
                              ! 例外処理用フラグ. 
                              ! デフォルトでは, この手続き内でエラーが
                              ! 生じた場合, プログラムは強制終了します. 
                              ! 引数 *err* が与えられる場合, 
                              ! プログラムは強制終了せず, 代わりに
                              ! *err* に .true. が代入されます. 
                              !
                              ! Exception handling flag. 
                              ! By default, when error occur in 
                              ! this procedure, the program aborts. 
                              ! If this *err* argument is given, 
                              ! .true. is substituted to *err* and 
                              ! the program does not abort. 

    !-----------------------------------
    !  ヒストリファイルへのデータ出力設定
    !  Configure the settings for history data output
    character(STRING):: name = ''
                              ! 変数名. Variable identifier
    character(TOKEN):: interval_unit
                              ! ヒストリデータの出力間隔の単位. 
                              ! Unit for interval of history data output
    character(STRING):: varnames
                              ! 変数名リスト. 
                              ! List of variables
    character(TOKEN), pointer:: varnames_array(:) =>null()
                              ! 変数名リスト配列. 
                              ! List of variables (array) 
    integer:: i, vnmax
    type(GT_HISTORY), pointer:: gthist =>null()
                              ! gt4_history モジュール用構造体. 
                              ! Derived type for "gt4_history" module

    !-----------------------------------
    !  作業変数
    !  Work variables
    integer:: stat
    character(STRING):: cause_c
    character(*), parameter:: subname = 'PhyCoolSetTime'
  continue
    call BeginSub( subname )
    stat = DC_NOERR
    cause_c = ''

    !-----------------------------------------------------------------
    !  初期設定のチェック
    !  Check initialization
    !-----------------------------------------------------------------
    if ( .not. phy_cool % initialized ) then
      stat = DC_ENOTINIT
      cause_c = 'PHYCOOL'
      goto 999
    end if

    !-----------------------------------------------------------------
    !  時刻設定
    !  Configure time
    !-----------------------------------------------------------------
    call DCDiffTimeCreate( &
      & diff = phy_cool % current_time, &  ! (out)
      & value = real( current_time_value, DP ), & ! (in)
      & unit = current_time_unit )                ! (in)

    !-----------------------------------------------------------------
    !  ヒストリファイルへのデータの時刻設定
    !  Configure the time of history data
    !-----------------------------------------------------------------
    varnames = HstNmlInfoNames( phy_cool % gthstnml )
    call Split( str = varnames, sep = ',', & ! (in)
      & carray = varnames_array )            ! (out)
    vnmax = size( varnames_array )

    do i = 1, vnmax
      name = varnames_array(i)
      if ( trim( name ) == '' ) exit

      call HstNmlInfoOutputStepDisable( & 
        & gthstnml = phy_cool % gthstnml, & ! (inout)
        & name = name, &                           ! (in)
        & err = err )                              ! (out)

      nullify( gthist )
      call HstNmlInfoAssocGtHist( & 
        & gthstnml = phy_cool % gthstnml, & ! (in)
        & name = name, &                           ! (in)
        & history = gthist, &                      ! (out)
        & err = err )                              ! (out)

      if ( HistoryInitialized( gthist ) ) then
        call HstNmlInfoInquire( &
          & gthstnml = phy_cool % gthstnml, & ! (in)
          & name = name, &                           ! (in)
          & interval_unit = interval_unit )          ! (out)

        call HistorySetTime( &
          & history = gthist, &                     ! (inout)
          & time = &
          &   real( EvalbyUnit( phy_cool % current_time, &
          &                     interval_unit) ) ) ! (in)
      end if

    end do

    !-----------------------------------------------------------------
    !  終了処理, 例外処理
    !  Termination and Exception handling
    !-----------------------------------------------------------------
999 continue
    call StoreError( stat, subname, err, cause_c )
    call EndSub( subname )

  end subroutine PhyCoolSetTime

  subroutine PhyCoolNmlRead( nmlfile, &
    & DTempDdayCooling, UpperPress, LowerPress, &
    & gthstnml, &
    & err )
    !
    ! NAMELIST ファイル *nmlfile* から値を入力するための
    ! サブルーチンです. PhyCoolCreate 
    ! 内で呼び出されることを想定しています. 
    !
    ! 値が NAMELIST ファイル内で指定されていない場合には, 
    ! 入力された値がそのまま返ります. 
    !
    ! なお, *nmlfile* に空文字が与えられた場合, または
    ! 与えられた *nmlfile* を読み込むことができない場合, 
    ! プログラムはエラーを発生させます. 
    !
    ! This is a subroutine to input values from 
    ! NAMELIST file *nmlfile*. This subroutine is expected to be 
    ! called by "PhyCoolCreate". 
    !
    ! A value not specified in NAMELIST file is returned 
    ! without change. 
    !
    ! If *nmlfile* is empty, or *nmlfile* can not be read, 
    ! error is occurred. 
    !
    use dc_trace, only: BeginSub, EndSub
    use dc_string, only: PutLine, Printf, Split, StrInclude, StoA, JoinChar
    use dc_types, only: DP, STRING, TOKEN, STDOUT
    use dc_iounit, only: FileOpen
    use dc_message, only: MessageNotify
    use dc_present, only: present_and_true
    use dc_date, only: DCDiffTimeCreate
    use dc_error, only: StoreError, DC_NOERR, DC_ENOFILEREAD, DC_ENOTINIT
    use gt4_history_nmlinfo, only: GTHST_NMLINFO, HstNmlInfoAdd, &
      & HstNmlInfoInquire, HstNmlInfoInitialized, HstNmlInfoPutLine
    implicit none
    character(*), intent(in):: nmlfile
                              ! NAMELIST ファイルの名称. 
                              ! NAMELIST file name

    real(DP), intent(inout):: DTempDdayCooling
                              ! 冷却の効果による一日あたりの温度変化.
                              ! Temperature tendency per day by cooling effect
    real(DP), intent(inout):: UpperPress
                              ! 冷却範囲の上端の気圧. 
                              ! Pressure in the top within the range of cooling
    real(DP), intent(inout):: LowerPress
                              ! 冷却範囲の下端の気圧. 
                              ! Pressure at bottom within the range of cooling
    type(GTHST_NMLINFO), intent(inout):: gthstnml
                              ! NAMELIST#phy_cooling_s08_history_nml 
                              ! から入手される個別のデータ出力情報. 
                              ! 
                              ! 初期設定やデフォルト値の設定などを
                              ! 行った後に与えること. 
                              ! 
                              ! Individual data output information from 
                              ! "NAMELIST#phy_cooling_s08_history_nml". 
                              ! 
                              ! Before this argument is given to 
                              ! this procedure, initialize and 
                              ! configure the defaut settings. 
    logical, intent(out), optional:: err
                              ! 例外処理用フラグ. 
                              ! デフォルトでは, この手続き内でエラーが
                              ! 生じた場合, プログラムは強制終了します. 
                              ! 引数 *err* が与えられる場合, 
                              ! プログラムは強制終了せず, 代わりに
                              ! *err* に .true. が代入されます. 
                              !
                              ! Exception handling flag. 
                              ! By default, when error occur in 
                              ! this procedure, the program aborts. 
                              ! If this *err* argument is given, 
                              ! .true. is substituted to *err* and 
                              ! the program does not abort. 

    namelist /phy_cooling_s08_nml/ &
      & DTempDdayCooling, UpperPress, LowerPress
                              ! phy_cooling_s08 モジュール用
                              ! NAMELIST 変数群名. 
                              !
                              ! phy_cooling_s08#PhyCoolCreate 
                              ! を使用する際に, オプショナル引数 *nmlfile* 
                              ! へ NAMELIST ファイル名を指定することで, 
                              ! そのファイルからこの NAMELIST 変数群を
                              ! 読み込みます. 
                              !
                              ! NAMELIST group name for 
                              ! "phy_cooling_s08" module. 
                              ! 
                              ! If a NAMELIST filename is specified to 
                              ! an optional argument *nmlfile* when 
                              ! "phy_cooling_s08#PhyCoolCreate" 
                              ! is used, this NAMELIST group is 
                              ! loaded from the file. 

    character(STRING):: name
                              ! 変数名. 
                              ! 空白の場合には, この他の設定値は
                              ! phy_cooling_s08 モジュールにおいて
                              ! 出力されるデータ全ての
                              ! デフォルト値となります. 
                              ! 
                              ! "Data1,Data2" のようにカンマで区切って複数
                              ! の変数を指定することも可能です. 
                              ! 
                              ! Variable identifier. 
                              ! If blank is given, other values are 
                              ! used as default values of output data 
                              ! in "phy_cooling_s08". 
                              ! 
                              ! Multiple variables can be specified 
                              ! as "Data1,Data2" too. Delimiter is comma. 
    character(STRING):: file
                              ! 出力ファイル名. 
                              ! これはデフォルト値としては使用されません. 
                              ! *name* に値が設定されている時のみ有効です. 
                              ! 
                              ! Output file name. 
                              ! This is not used as default value. 
                              ! This value is valid only when *name* is 
                              ! specified. 

    real:: interval_value
                              ! ヒストリデータの出力間隔の数値. 
                              ! 負の値を与えると, 出力を抑止します. 
                              ! Numerical value for interval of history data output
                              ! Negative values suppresses output.
    character(TOKEN):: interval_unit
                              ! ヒストリデータの出力間隔の単位. 
                              ! Unit for interval of history data output
    character(TOKEN):: precision
                              ! ヒストリデータの精度. 
                              ! Precision of history data
    logical:: average
                              ! 出力データの平均化フラグ. 
                              ! Flag for average of output data
    character(STRING):: fileprefix
                              ! ヒストリデータのファイル名の接頭詞. 
                              ! Prefixes of history data filenames

    namelist /phy_cooling_s08_history_nml/ &
      & name, &
      & file, &
      & interval_value, &
      & interval_unit, &
      & precision, &
      & fileprefix, &
      & average
                              ! phy_cooling_s08 モジュールのヒストリデータ用
                              ! NAMELIST 変数群名. 
                              !
                              ! phy_cooling_s08#PhyCoolCreate 
                              ! を使用する際に, オプショナル引数 *nmlfile* 
                              ! へ NAMELIST ファイル名を指定することで, 
                              ! そのファイルからこの NAMELIST 変数群を
                              ! 読み込みます. 
                              !
                              ! NAMELIST group name for 
                              ! history data of "phy_cooling_s08" module. 
                              ! 
                              ! If a NAMELIST filename is specified to 
                              ! an optional argument *nmlfile* when 
                              ! "phy_cooling_s08#PhyCoolCreate" 
                              ! is used, this NAMELIST group is 
                              ! loaded from the file. 

    !-----------------------------------
    !  作業変数
    !  Work variables
    integer:: stat
    character(STRING):: cause_c
    integer:: unit_nml        ! NAMELIST ファイルオープン用装置番号. 
                              ! Unit number for NAMELIST file open
    integer:: iostat_nml      ! NAMELIST 読み込み時の IOSTAT. 
                              ! IOSTAT of NAMELIST read
    character(TOKEN):: pos_nml
                              ! NAMELIST 読み込み時のファイル位置. 
                              ! File position of NAMELIST read
    character(*), parameter:: subname = 'PhyCoolNmlRead'
  continue
    call BeginSub( subname )
    stat = DC_NOERR
    cause_c = ''

    !-----------------------------------------------------------------
    !  初期設定のチェック
    !  Check initialization
    !-----------------------------------------------------------------

    !-----------------------------------------------------------------
    !  文字型引数を NAMELIST 変数群へ代入
    !  Substitute character arguments to NAMELIST group
    !-----------------------------------------------------------------
!!$    key00       = key00_

    !----------------------------------------------------------------
    !  NAMELIST ファイルのオープン
    !  Open NAMELIST file
    !----------------------------------------------------------------
    call FileOpen( unit = unit_nml, & ! (out)
      & file = nmlfile, mode = 'r', & ! (in)
      & err = err )                   ! (out)
    if ( present_and_true(err) ) then
      stat = DC_ENOFILEREAD
      cause_c = nmlfile
      goto 999
    end if

    !-----------------------------------------------------------------
    !  NAMELIST 変数群の取得
    !  Get NAMELIST group
    !-----------------------------------------------------------------

    !-------------------------
    !  係数などの取得
    !  Get coefficients etc.
    rewind( unit_nml )
    read( unit = unit_nml, &         ! (in)
      &    nml = phy_cooling_s08_nml, & ! (out)
      & iostat = iostat_nml )        ! (out)
    if ( iostat_nml == 0 ) then
      call MessageNotify( 'M', subname, &
        & 'NAMELIST group "%c" is loaded from "%c".', &
        & c1 = 'phy_cooling_s08_nml', c2 = trim(nmlfile) )
      write(STDOUT, nml = phy_cooling_s08_nml)
    else
      call MessageNotify( 'W', subname, &
        & 'NAMELIST group "%c" is not found in "%c" (iostat=%d).', &
        & c1 = 'phy_cooling_s08_nml', c2 = trim(nmlfile), &
        & i = (/iostat_nml/) )
    end if

    !-------------------------
    !  出力データの個別情報の取得
    !  Get individual information of output data
    rewind( unit_nml )
    iostat_nml = 0
    pos_nml = ''
    do while ( trim(pos_nml) /= 'APPEND' .and. iostat_nml == 0 )

      name                   = ''
      file                   = ''
      call HstNmlInfoInquire( &
        & gthstnml = gthstnml, &             ! (in)
        & interval_value = interval_value, & ! (out)
        & interval_unit = interval_unit, &   ! (out)
        & precision = precision, &           ! (out)
        & average = average, &               ! (out)
        & fileprefix = fileprefix )          ! (out)

      read( unit = unit_nml, &                 ! (in)
        &    nml = phy_cooling_s08_history_nml, & ! (out)
        & iostat = iostat_nml )                ! (out)
      inquire( unit = unit_nml, & ! (in)
        &  position = pos_nml )   ! (out)

      if ( iostat_nml == 0 ) then
        call MessageNotify( 'M', subname, &
          & 'NAMELIST group "%c" is loaded from "%c".', &
          & c1='phy_cooling_s08_history_nml', c2=trim(nmlfile) )
        write(STDOUT, nml = phy_cooling_s08_history_nml)

        call HstNmlInfoAdd( &
          & gthstnml = gthstnml, &             ! (in)
          & name = name, &                     ! (in)
          & file = file, &                     ! (in)
          & interval_value = interval_value, & ! (in)
          & interval_unit = interval_unit, &   ! (in)
          & precision = precision, &           ! (in)
          & average = average, &               ! (in)
          & fileprefix = fileprefix )          ! (in)

      else
        call MessageNotify( 'W', subname, &
          & 'NAMELIST group "%c" is not found in "%c" any more (iostat=%d).', &
          & c1='phy_cooling_s08_history_nml', c2=trim(nmlfile), &
          & i = (/iostat_nml/) )
      end if
    end do

    close( unit_nml )

    !-----------------------------------------------------------------
    !  NAMELIST 変数群を文字型引数へ代入
    !  Substitute NAMELIST group to character arguments
    !-----------------------------------------------------------------
!!$    key00_       = key00

    !-----------------------------------------------------------------
    !  終了処理, 例外処理
    !  Termination and Exception handling
    !-----------------------------------------------------------------
999 continue
    call StoreError( stat, subname, err, cause_c )
    call EndSub( subname )

  end subroutine PhyCoolNmlRead

end module phy_cooling_s08
