!= 地表面データの入力
!
!= Ground data input
!
! Authors::   Yoshiyuki O. Takahashi, Yasuhiro MORIKAWA, Yukiko YAMADA
! Version::   $Id: ground_file_io.F90,v 1.2 2009-04-15 22:47:06 yot Exp $ 
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2008. All rights reserved.
! License::   See COPYRIGHT[link:../../../COPYRIGHT]
!

module ground_file_io
  !
  != 地表面データの入力
  !
  != Ground data input
  !
  ! <b>Note that Japanese and English are described in parallel.</b>
  !
  ! 海面温度や地表面諸量に関するデータを NetCDF ファイル, 
  ! もしくは surface_data モジュールから入力します. 
  !
  ! Data about sea surface temperature (SST) or various values on surface
  ! are input from a NetCDF file or "surface_data" module. 
  !
  !== Procedures List
  ! GroundFileGet    :: 地表面データファイルの入力
  !--
  ! GroundFileOpen   :: 地表面データファイルのオープン
  ! GroundFileOutput :: 地表面データファイルへのデータ出力
  ! GroundFileClose  :: 地表面データファイルのクローズ
  !++
  ! ------------     :: ------------
  ! GroundFileGet    :: Input ground data file
  !--
  ! GroundFileOpen   :: Open ground data file
  ! GroundFileOutput :: Data output to ground data file
  ! GroundFileClose  :: Close ground data file
  !++
  !
  !== NAMELIST
  !
  ! NAMELIST#ground_file_io_nml
  !

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

  ! 格子点設定
  ! Grid points settings
  !
  use gridset, only: imax, & ! 経度格子点数. 
                             ! Number of grid points in longitude
    &                jmax, & ! 緯度格子点数. 
                             ! Number of grid points in latitude
    &                kmax    ! 鉛直層数. 
                             ! Number of vertical level

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

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

  ! gtool4 データ出力
  ! Gtool4 data output
  !
  use gtool_history, only: GT_HISTORY

#ifdef LIB_MPI
  ! MPI ライブラリ
  ! MPI library
  !
  use mpi
#endif

  ! 宣言文 ; Declaration statements
  !
  implicit none
  private

  ! 公開手続き
  ! Public procedure
  !
!  public:: GroundFileOpen, GroundFileClose, GroundFileOutPut
  public:: GroundFileGet

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

  logical, save, public:: ground_file_opened = .false.
                              ! 地表面データファイルのオープンに関するフラグ. 
                              ! Flag of ground data file open

  ! 非公開変数
  ! Private variables
  !
  character(STRING), save:: SurfTempFile
                              ! 地表面温度のファイル名. 
                              ! File name of surface temperature
  character(TOKEN), save:: SurfTempName
                              ! 地表面温度の変数名. 
                              ! Variable name of surface temperature

  character(STRING), save:: AlbedoFile
                              ! 地表アルベドのファイル名. 
                              ! File name of surface albedo
  character(TOKEN), save:: AlbedoName
                              ! 地表アルベドの変数名. 
                              ! Variable name of surface albedo

  character(STRING), save:: HumidCoefFile
                              ! 地表湿潤度のファイル名. 
                              ! File name of surface humidity coefficient
  character(TOKEN), save:: HumidCoefName
                              ! 地表湿潤度の変数名. 
                              ! Variable name of surface humidity coefficient

  character(STRING), save:: RoughLengthFile
                              ! 地表粗度長のファイル名. 
                              ! File name of surface rough length
  character(TOKEN), save:: RoughLengthName
                              ! 地表粗度長の変数名. 
                              ! Variable name of surface rough length

  character(STRING), save:: HeatCapacityFile
                              ! 地表熱容量のファイル名. 
                              ! File name of surface heat capacity
  character(TOKEN), save:: HeatCapacityName
                              ! 地表熱容量の変数名. 
                              ! Variable name of surface heat capacity

  character(STRING), save:: TempFluxFile
                              ! 地中熱フラックスのファイル名. 
                              ! File name of ground temperature flux
  character(TOKEN), save:: TempFluxName
                              ! 地中熱フラックスの変数名. 
                              ! Variable name of ground temperature flux

  character(STRING), save:: SurfCondFile
                              ! 地表状態 (0: 固定, 1: 可変) のファイル名. 
                              ! File name of surface condition (0: fixed, 1: variable)
  character(TOKEN), save:: SurfCondName
                              ! 地表状態 (0: 固定, 1: 可変) の変数名. 
                              ! Variable name of surface condition (0: fixed, 1: variable)

  character(STRING), save:: SurfHeightFile
                              ! 地表面高度のファイル名. 
                              ! File name of surface height
  character(TOKEN), save:: SurfHeightName
                              ! 地表面高度の変数名. 
                              ! Variable name of surface height

  logical         , save:: FlagUseMatthewsAlbedo
  logical         , save:: FlagUseLOContrastRoughLength
  logical         , save:: FlagUseMatthewsRoughLength


!!$  character(STRING), save:: OutputFile
!!$                              ! 出力する地表面データのファイル名
!!$                              ! filename of output ground data
!!$  real(DP), save:: IntValue
!!$                              ! 地表面データの出力間隔. 
!!$                              ! Interval of ground data output
!!$  character(TOKEN):: IntUnit
!!$                              ! 地表面データの出力間隔の単位. 
!!$                              ! Unit for interval of ground data output
!!$
!!$  type(GT_HISTORY), save:: gthst_grd
!!$                              ! 地表面データ用 gtool_history#GT_HISTORY 変数
!!$                              ! "gtool_history#GT_HISTORY" variable for ground data
!!$
!!$
!!$  type(DC_DIFFTIME), save:: PrevOutputTime
!!$                              ! 前回の出力時間. 
!!$                              ! Previous output time
!!$
!!$  type(DC_DIFFTIME), save:: IntTime
!!$                              ! リスタートデータの出力時間. 
!!$                              ! Time interval of restart data output

  character(*), parameter:: module_name = 'ground_file_io'
                              ! モジュールの名称. 
                              ! Module name
  character(*), parameter:: version = &
    & '$Name:  $' // &
    & '$Id: ground_file_io.F90,v 1.2 2009-04-15 22:47:06 yot Exp $'
                              ! モジュールのバージョン
                              ! Module version

  ! INTERFACE 文 ; INTERFACE statements
  !
!!$  interface GroundFileOpen
!!$    module procedure GroundFileOpen
!!$  end interface
!!$
!!$  interface GroundFileClose
!!$    module procedure GroundFileClose
!!$  end interface
!!$
!!$  interface GroundFileOutput
!!$    module procedure GroundFileOutput
!!$  end interface

  interface GroundFileGet
    module procedure GroundFileGet
  end interface

contains

  subroutine GroundFileGet( &
    & xy_SurfTemp, xy_SurfAlbedo, xy_SurfHumidCoef, & ! (inout)
    & xy_SurfRoughLength, xy_SurfHeatCapacity, &      ! (inout)
    & xy_GroundTempFlux, xy_SurfCond, &               ! (inout)
    & xy_SurfHeight &                                 ! (inout)
    & )
    !
    ! 地表面の諸々のデータを設定します. 
    ! xy_SurfTemp 以外は一回目に呼ばれた時のみ設定されます. 
    !
    ! Get various data on ground. 
    ! Arguments excluding "xy_SurfTemp" are configured at first only. 
    !

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

    ! 地表面データ提供
    ! Prepare surface data
    !
    use surface_data, only: SurfDataGet

    ! Matthews のデータに基づく惑星表面アルベド設定
    ! set surface albedo based on data by Matthews
    !
    use set_albedo_Matthews, only: SetAlbedoMathews

    ! 粗度長の設定, 陸面と海洋の差のみ考慮
    ! Set roughness length, only considering land-ocean contrast
    !
    use set_roughlen_landoceancontrast, only: SetRoughLenLandOceanContrast

    ! Matthews のデータに基づく地面粗度の設定
    ! set roughness length on land surface based on data by Matthews
    !
    use set_roughlen_Matthews, only: SetRoughLenLandMatthews

    ! gtool4 データ入力
    ! Gtool4 data input
    !
    use gtool_history, only: HistoryGet

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

    ! 宣言文 ; Declaration statements
    !
    implicit none
    real(DP), intent(inout), optional:: xy_SurfTemp (0:imax-1, 1:jmax)
                              ! 地表面温度. 
                              ! Surface temperature
    real(DP), intent(inout), optional:: xy_SurfAlbedo (0:imax-1, 1:jmax)
                              ! 地表アルベド. 
                              ! Surface albedo
    real(DP), intent(inout), optional:: xy_SurfHumidCoef (0:imax-1, 1:jmax)
                              ! 地表湿潤度. 
                              ! Surface humidity coefficient
    real(DP), intent(inout), optional:: xy_SurfRoughLength (0:imax-1, 1:jmax)
                              ! 地表粗度長. 
                              ! Surface rough length
    real(DP), intent(inout), optional:: xy_SurfHeatCapacity (0:imax-1, 1:jmax)
                              ! 地表熱容量. 
                              ! Surface heat capacity
    real(DP), intent(inout), optional:: xy_GroundTempFlux (0:imax-1, 1:jmax)
                              ! 地中熱フラックス. 
                              ! Ground temperature flux
    integer, intent(inout), optional:: xy_SurfCond (0:imax-1, 1:jmax)
                              ! 地表状態 (0: 固定, 1: 可変). 
                              ! Surface condition (0: fixed, 1: variable)
    real(DP), intent(inout), optional:: xy_SurfHeight (0:imax-1, 1:jmax)
                              ! $ z_s $ . 地表面高度. 
                              ! Surface height. 

    ! 作業変数
    ! Work variables
    !
    real(DP), allocatable, save:: xy_SurfTempSave (:,:)
                              ! 地表面温度の保存値. 
                              ! Saved values surface temperature

    logical, save:: flag_first = .true.
                              ! 初回を示すフラグ. 
                              ! 
                              ! Flag that indicates first loop
    logical:: flag_mpi_init
#ifdef LIB_MPI
    integer:: err_mpi
#endif

    ! 実行文 ; Executable statement
    !

    if ( .not. ground_file_io_inited ) call GroundFileInit

    ! 初回はデータを読み込む
    ! Load data at first
    ! 
    if ( flag_first ) then

      ! 地表面温度の保存用変数の割付
      ! Allocate a variable for save of surface temperature
      !
      allocate( xy_SurfTempSave (0:imax-1, 1:jmax) )

      ! データ (デフォルト値) を surface_data モジュールから取得
      ! Data (default values) is input from "surface_data" module
      ! 
      call SurfDataGet( &
        & xy_SurfTempSave, xy_SurfAlbedo, xy_SurfHumidCoef, & ! (out)
        & xy_SurfRoughLength, xy_SurfHeatCapacity, &          ! (out)
        & xy_GroundTempFlux, xy_SurfCond )                    ! (out)

      ! 地形はデフォルトでは平坦
      ! Geography is flat by default
      !
      if ( present(xy_SurfHeight) ) xy_SurfHeight = 0.0_DP

#ifdef LIB_MPI
      ! MPI における初期化が行われているかを確認する. 
      ! Confirm initialization of MPI
      !
      call MPI_Initialized(flag_mpi_init, err_mpi)
#else
      flag_mpi_init = .false.
#endif

      ! データをファイルから取得
      ! Data is input from files
      ! 
      if ( trim(SurfTempFile) /= '' .or. trim(SurfTempName) /= '' ) then
        call HistoryGet( &
          & SurfTempFile, SurfTempName, &    ! (in)
          & xy_SurfTempSave, &               ! (out)
          & flag_mpi_split = flag_mpi_init ) ! (in) optional
      end if

      if ( trim(AlbedoFile) /= '' .or. trim(AlbedoName) /= '' ) then
        if ( present(xy_SurfAlbedo) ) then
          call HistoryGet( &
            & AlbedoFile, AlbedoName, &        ! (in)
            & xy_SurfAlbedo, &                 ! (out)
            & flag_mpi_split = flag_mpi_init ) ! (in) optional
        end if
      end if

      if ( trim(HumidCoefFile) /= '' .or. trim(HumidCoefName) /= '' ) then
        if ( present(xy_SurfHumidCoef) ) then
          call HistoryGet( &
            & HumidcoefFile, HumidcoefName, &  ! (in)
            & xy_SurfHumidcoef, &              ! (out)
            & flag_mpi_split = flag_mpi_init ) ! (in) optional
        end if
      end if

      if ( trim(RoughLengthFile) /= '' .or. trim(RoughLengthName) /= '' ) then
        if ( present(xy_SurfRoughLength) ) then
          call HistoryGet( &
            & RoughLengthFile, RoughLengthName, & ! (in)
            & xy_SurfRoughLength, &               ! (out)
            & flag_mpi_split = flag_mpi_init )    ! (in) optional
        end if
      end if

      if ( trim(HeatCapacityFile) /= '' .or. trim(HeatCapacityName) /= '' ) then
        if ( present(xy_SurfHeatCapacity) ) then
          call HistoryGet( &
            & HeatCapacityFile, HeatCapacityName, & ! (in)
            & xy_SurfHeatCapacity, &                ! (out)
            & flag_mpi_split = flag_mpi_init )      ! (in) optional
        end if
      end if

      if ( trim(TempFluxFile) /= '' .or. trim(TempFluxName) /= '' ) then
        if ( present(xy_GroundTempFlux) ) then
          call HistoryGet( &
            & TempFluxFile, TempFluxName, &     ! (in)
            & xy_GroundTempFlux, &              ! (out)
            & flag_mpi_split = flag_mpi_init )  ! (in) optional
        end if
      end if

      if ( trim(SurfCondFile) /= '' .or. trim(SurfCondName) /= '' ) then
        if ( present(xy_SurfCond) ) then
          call HistoryGet( &
            & SurfCondFile, SurfCondName, &     ! (in)
            & xy_SurfCond, &                    ! (out)
            & flag_mpi_split = flag_mpi_init )  ! (in) optional
        end if
      end if

      if ( trim(SurfHeightFile) /= '' .or. trim(SurfHeightName) /= '' ) then
        if ( present(xy_SurfHeight) ) then
          call HistoryGet( &
            & SurfHeightFile, SurfHeightName, &  ! (in)
            & xy_SurfHeight, &                   ! (out)
            & flag_mpi_split = flag_mpi_init )   ! (in) optional
        end if
      end if

      flag_first = .false.
    end if

    ! 地表面温度を SST で置き換え ( xy_SurfCond <=0 の場所のみ )
    ! Surface temperature is replaced with SST ( only xy_SurfCond <=0 )
    ! 
    if ( present(xy_SurfTemp) ) then
      where( xy_SurfCond <= 0 .and. xy_SurfTempSave > 0.0_DP  )
        xy_SurfTemp = xy_SurfTempSave
      end where
    end if


    ! アルベドを Matthews のデータをもとに設定
    ! Surface albedo is set based on Matthews' data
    ! 
    if ( present(xy_SurfAlbedo) ) then
      if ( FlagUseMatthewsAlbedo ) then
        call SetAlbedoMathews( xy_SurfCond, xy_SurfAlbedo )
      end if
    end if

    ! 粗度長の設定, 陸面と海洋の差のみ考慮
    ! Set roughness length, only considering land-ocean contrast
    !
    if ( present(xy_SurfRoughLength) ) then
      if ( FlagUseLOContrastRoughLength ) then
        call SetRoughLenLandOceanContrast( &
          & xy_SurfCond,       &
          & xy_SurfRoughLength &
          )
      else if ( FlagUseMatthewsRoughLength ) then
        call SetRoughLenLandMatthews( &
          & xy_SurfCond,       &
          & xy_SurfRoughLength &
          )
      end if
    end if

  end subroutine GroundFileGet

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

!!$  subroutine GroundFileOpen
!!$    !
!!$    ! 地表面データファイルをオープンします. 
!!$    !
!!$    ! A ground data file is opened. 
!!$    !
!!$
!!$    ! モジュール引用 ; 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 constants settings
!!$    !
!!$    use constants, only: PI   ! $ \pi $ .
!!$                              ! 円周率.  Circular constant
!!$
!!$    ! 座標データ設定
!!$    ! Axes data settings
!!$    !
!!$    use axesset, only: &
!!$      & 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)
!!$
!!$    ! 時刻管理
!!$    ! Time control
!!$    !
!!$    use timeset, only: &
!!$      & DelTime, &            ! $ \Delta t $ [s]
!!$      & StartTime, &          ! 計算開始時刻. 
!!$                              ! Start time of calculation
!!$      & StartDate, &          ! 計算開始日時. 
!!$                              ! Start date of calculation
!!$      & StartDateValid        ! 計算開始日時の有効性. 
!!$                              ! Validation of start date of calculation
!!$
!!$    ! gtool4 データ出力
!!$    ! Gtool4 data output
!!$    !
!!$    use gtool_history, only: HistoryCreate, HistoryAddVariable, &
!!$      & HistoryPut, HistoryAddAttr
!!$
!!$    ! 文字列操作
!!$    ! Character handling
!!$    !
!!$    use dc_string, only: StoA
!!$
!!$    ! 日付および時刻の取り扱い
!!$    ! Date and time handler
!!$    !
!!$    use dc_date, only: toChar, EvalByUnit
!!$
!!$    ! 宣言文 ; Declaration statements
!!$    !
!!$    implicit none
!!$
!!$    ! 作業変数
!!$    ! Work variables
!!$    !
!!$    real(DP):: origin_time
!!$                              ! 計算開始時刻. 
!!$                              ! Start time of calculation
!!$
!!$    ! 実行文 ; Executable statement
!!$    !
!!$
!!$    ! 初期化
!!$    ! Initialization
!!$    !
!!$    if ( .not. ground_file_io_inited ) call GroundFileInit
!!$    if ( ground_file_opened ) return
!!$
!!$    ! 時刻情報の取得
!!$    ! Get time information
!!$    !
!!$    origin_time = EvalByUnit( StartTime, IntUnit )
!!$
!!$    ! 地表面データファイルのオープン
!!$    ! Open a ground data file
!!$    !
!!$    call HistoryCreate( &
!!$      &      file = OutputFile,   &
!!$      &     title = trim(FileTitle) // ' ground data', &          ! (in)
!!$      &    source = FileSource, institution = FileInstitution, &   ! (in)
!!$      &      dims = StoA( 'lon', 'lat', 'sig', 'sigm', 'time' ), & ! (in)
!!$      &  dimsizes = (/ imax, jmax, kmax, kmax + 1, 0 /), &         ! (in)
!!$      & longnames = StoA( 'longitude', 'latitude', &
!!$      &                   'sigma at layer midpoints', &
!!$      &                   'sigma at layer end-points (half level)', &
!!$      &                   'time' ), &                              ! (in)
!!$      &     units = StoA( 'degree_east', 'degree_north', &
!!$      &                   '1', '1', IntUnit ), &                   ! (in)
!!$      &    origin = real( origin_time ), &                         ! (in)
!!$      &  interval = real( IntValue ), &                            ! (in)
!!$      &   history = gthst_grd )                                    ! (out)
!!$
!!$    ! $ \Delta t $ に関する情報を追加
!!$    ! Add information about $ \Delta t $
!!$    !
!!$    call HistoryAddVariable( &
!!$      & varname = 'deltime', &            ! (in)
!!$      & dims = StoA(''), &                ! (in)
!!$      & longname = 'delta time', &        ! (in)
!!$      & units = 's', xtype = 'float', &   ! (in)
!!$      & history = gthst_grd )             ! (inout)
!!$    call HistoryPut( &
!!$      & varname = 'deltime', &            ! (in)
!!$      & array = (/ DelTime /), &          ! (in)
!!$      & history = gthst_grd )             ! (inout)
!!$
!!$    ! 座標データの設定
!!$    ! Axes data settings
!!$    !
!!$    call HistoryAddAttr( &
!!$      & varname = 'lon', attrname = 'standard_name', &   ! (in)
!!$      & value = 'longitude', &                           ! (in)
!!$      & history = gthst_grd )                            ! (inout)
!!$    call HistoryAddAttr( &
!!$      & varname = 'lat', attrname = 'standard_name', &   ! (in)
!!$      & value = 'latitude', &                            ! (in)
!!$      & history = gthst_grd )                            ! (inout)
!!$    call HistoryAddAttr( &
!!$      & varname = 'sig', attrname = 'standard_name', &   ! (in)
!!$      & value = 'atmosphere_sigma_coordinate', &         ! (in)
!!$      & history = gthst_grd )                            ! (inout)
!!$    call HistoryAddAttr( &
!!$      & varname = 'sigm', attrname = 'standard_name', &  ! (in)
!!$      & value = 'atmosphere_sigma_coordinate', &         ! (in)
!!$      & history = gthst_grd )                            ! (inout)
!!$    call HistoryAddAttr( &
!!$      & varname = 'time', attrname = 'standard_name', &  ! (in)
!!$      & value = 'time', &                                ! (in)
!!$      & history = gthst_grd )                            ! (inout)
!!$    call HistoryAddAttr( &
!!$      & varname = 'sig', attrname = 'positive', &        ! (in)
!!$      & value = 'down', &                                ! (in)
!!$      & history = gthst_grd )                            ! (inout)
!!$    call HistoryAddAttr( &
!!$      & varname = 'sigm', attrname = 'positive', &       ! (in)
!!$      & value = 'down', &                                ! (in)
!!$      & history = gthst_grd )                            ! (inout)
!!$
!!$    call HistoryPut( &
!!$      & varname = 'lon', &               ! (in)
!!$      & array = x_Lon / PI * 180.0_DP, & ! (in)
!!$      & history = gthst_grd )            ! (inout)
!!$    call HistoryPut( &
!!$      & varname = 'lat', &               ! (in)
!!$      & array = y_Lat / PI * 180.0_DP, & ! (in)
!!$      & history = gthst_grd )            ! (inout)
!!$    call HistoryPut( &
!!$      & varname = 'sig', &               ! (in)
!!$      & array = z_Sigma, &               ! (in)
!!$      & history = gthst_grd )            ! (inout)
!!$    call HistoryPut( & 
!!$      & varname = 'sigm', &              ! (in)
!!$      & array = r_Sigma, &               ! (in)
!!$      & history = gthst_grd )            ! (inout)
!!$
!!$    ! 座標重みの設定
!!$    ! Axes weights settings
!!$    !
!!$    call HistoryAddVariable( &
!!$      & varname = 'lon_weight', &                           ! (in)
!!$      & dims = StoA('lon'), &                               ! (in)
!!$      & longname = 'weight for integration in longitude', & ! (in)
!!$      & units = 'radian', xtype = 'double', &               ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddAttr( &
!!$      & varname = 'lon', attrname = 'gt_calc_weight', &     ! (in)
!!$      & value = 'lon_weight', &                             ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryPut( &
!!$      & varname = 'lon_weight', array = x_Lon_Weight, &     ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$
!!$    call HistoryAddVariable( &
!!$      & varname = 'lat_weight', &                           ! (in)
!!$      & dims = StoA('lat'), &                               ! (in)
!!$      & longname = 'weight for integration in latitude', &  ! (in)
!!$      & units = 'radian', xtype = 'double', &               ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddAttr( &
!!$      & varname = 'lat', attrname = 'gt_calc_weight', &     ! (in)
!!$      & value = 'lat_weight', &                             ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryPut( &
!!$      & varname = 'lat_weight', array = y_Lat_Weight, &     ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$
!!$    call HistoryAddVariable( &
!!$      & varname = 'sig_weight', &                           ! (in)
!!$      & dims = StoA('sig'), &                               ! (in)
!!$      & longname = 'weight for integration in sigma', &     ! (in)
!!$      & units = '1', xtype = 'double', &                    ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddAttr( &
!!$      & varname = 'sig', attrname = 'gt_calc_weight', &     ! (in)
!!$      & value = 'sig_weight', &                             ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryPut( &
!!$      & varname = 'sig_weight', array = z_DelSigma, &       ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$
!!$    ! 予報変数の設定
!!$    ! Predictional variables settings
!!$    !
!!$    call HistoryAddVariable( &
!!$      & varname = 'UB', &                                   ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig', 'time'), &         ! (in)
!!$      & longname = 'eastward wind (at t-\Delta t)', &       ! (in)
!!$      & units = 'm s-1', xtype = 'double', &                ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddVariable( &
!!$      & varname = 'VB', &                                   ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig', 'time'), &         ! (in)
!!$      & longname = 'northward wind (at t-\Delta t)', &      ! (in)
!!$      & units = 'm s-1', xtype = 'double', &                ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddVariable( &
!!$      & varname = 'TempB', &                                ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig', 'time'), &         ! (in)
!!$      & longname = 'temperature (at t-\Delta t)', &         ! (in)
!!$      & units = 'K', xtype = 'double', &                    ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddVariable( &
!!$      & varname = 'QVapB', &                                ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig', 'time'), &         ! (in)
!!$      & longname = 'specific humidity (at t-\Delta t)', &   ! (in)
!!$      & units = 'kg kg-1', xtype = 'double', &              ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddVariable( &
!!$      & varname = 'PsB', &                                  ! (in)
!!$      & dims = StoA('lon', 'lat', 'time'), &                ! (in)
!!$      & longname = 'surface pressure (at t-\Delta t)', &    ! (in)
!!$      & units = 'Pa', xtype = 'double', &                   ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$
!!$    call HistoryAddVariable( &
!!$      & varname = 'UN', &                                   ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig', 'time'), &         ! (in)
!!$      & longname = 'eastward wind (at t)', &                ! (in)
!!$      & units = 'm s-1', xtype = 'double', &                ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddVariable( &
!!$      & varname = 'VN', &                                   ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig', 'time'), &         ! (in)
!!$      & longname = 'northward wind (at t)', &               ! (in)
!!$      & units = 'm s-1', xtype = 'double', &                ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddVariable( &
!!$      & varname = 'TempN', &                                ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig', 'time'), &         ! (in)
!!$      & longname = 'temperature (at t)', &                  ! (in)
!!$      & units = 'K', xtype = 'double', &                    ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddVariable( &
!!$      & varname = 'QVapN', &                                ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig', 'time'), &         ! (in)
!!$      & longname = 'specific humidity (at t)', &            ! (in)
!!$      & units = 'kg kg-1', xtype = 'double', &              ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$    call HistoryAddVariable( &
!!$      & varname = 'PsN', &                                  ! (in)
!!$      & dims = StoA('lon', 'lat', 'time'), &                ! (in)
!!$      & longname = 'surface pressure (at t)', &             ! (in)
!!$      & units = 'Pa', xtype = 'double', &                   ! (in)
!!$      & history = gthst_grd )                               ! (inout)
!!$
!!$    ground_file_opened = .true.
!!$  end subroutine GroundFileOpen
!!$
!!$  !-------------------------------------------------------------------
!!$
!!$  subroutine GroundFileOutput( &
!!$    & xyz_UB, xyz_VB, xyz_TempB, xyz_QVapB, xy_PsB, &   ! (in)
!!$    & xyz_UN, xyz_VN, xyz_TempN, xyz_QVapN, xy_PsN  &   ! (in)
!!$    & )
!!$    !
!!$    ! 地表面データの出力を行います. 
!!$    !
!!$    ! Output ground data
!!$
!!$    ! モジュール引用 ; USE statements
!!$    !
!!$
!!$    ! gtool4 データ出力
!!$    ! Gtool4 data output
!!$    !
!!$    use gtool_history, only: HistoryPut
!!$
!!$    ! 時刻管理
!!$    ! Time control
!!$    !
!!$    use timeset, only: TimeN  ! ステップ $ t $ の時刻. 
!!$                              ! Time of step $ t $. 
!!$
!!$    ! 宣言文 ; Declaration statements
!!$    !
!!$    implicit none
!!$    real(DP), intent(in):: xyz_UB  (0:imax-1, 1:jmax, 1:kmax)
!!$                              ! $ u (t-\Delta t) $ .   東西風速. Eastward wind
!!$    real(DP), intent(in):: xyz_VB  (0:imax-1, 1:jmax, 1:kmax)
!!$                              ! $ v (t-\Delta t) $ .   南北風速. Northward wind
!!$    real(DP), intent(in):: xyz_TempB  (0:imax-1, 1:jmax, 1:kmax)
!!$                              ! $ T (t-\Delta t) $ .   温度. Temperature
!!$    real(DP), intent(in):: xyz_QVapB  (0:imax-1, 1:jmax, 1:kmax)
!!$                              ! $ q (t-\Delta t) $ .   比湿. Specific humidity
!!$    real(DP), intent(in):: xy_PsB (0:imax-1, 1:jmax)
!!$                              ! $ p_s (t-\Delta t) $ . 地表面気圧. Surface pressure
!!$    real(DP), intent(in):: xyz_UN  (0:imax-1, 1:jmax, 1:kmax)
!!$                              ! $ u (t) $ .     東西風速. Eastward wind
!!$    real(DP), intent(in):: xyz_VN  (0:imax-1, 1:jmax, 1:kmax)
!!$                              ! $ v (t) $ .     南北風速. Northward wind
!!$    real(DP), intent(in):: xyz_TempN  (0:imax-1, 1:jmax, 1:kmax)
!!$                              ! $ T (t) $ .     温度. Temperature
!!$    real(DP), intent(in):: xyz_QVapN  (0:imax-1, 1:jmax, 1:kmax)
!!$                              ! $ q (t) $ .     比湿. Specific humidity
!!$    real(DP), intent(in):: xy_PsN (0:imax-1, 1:jmax)
!!$                              ! $ p_s (t) $ .   地表面気圧. Surface pressure
!!$
!!$    ! 作業変数
!!$    ! Work variables
!!$    !
!!$
!!$
!!$    ! 実行文 ; Executable statement
!!$    !
!!$
!!$    if ( .not. ground_file_opened ) call GroundFileOpen
!!$
!!$    ! 出力タイミングのチェック
!!$    ! Check output timing
!!$    !
!!$    if ( TimeN - PrevOutputTime < IntTime ) return
!!$    PrevOutputTime = TimeN
!!$
!!$    ! データ出力
!!$    ! Data output
!!$    !
!!$    call HistoryPut( &
!!$      & 'UB', xyz_UB, history = gthst_grd ) ! (in)
!!$    call HistoryPut( &
!!$      & 'VB', xyz_VB, history = gthst_grd ) ! (in)
!!$    call HistoryPut( &
!!$      & 'TempB', xyz_TempB, history = gthst_grd ) ! (in)
!!$    call HistoryPut( &
!!$      & 'QVapB', xyz_QVapB, history = gthst_grd ) ! (in)
!!$    call HistoryPut( &
!!$      & 'PsB', xy_PsB, history = gthst_grd ) ! (in)
!!$
!!$    call HistoryPut( &
!!$      & 'UN', xyz_UN, history = gthst_grd ) ! (in)
!!$    call HistoryPut( &
!!$      & 'VN', xyz_VN, history = gthst_grd ) ! (in)
!!$    call HistoryPut( &
!!$      & 'TempN', xyz_TempN, history = gthst_grd ) ! (in)
!!$    call HistoryPut( &
!!$      & 'QVapN', xyz_QVapN, history = gthst_grd ) ! (in)
!!$    call HistoryPut( &
!!$      & 'PsN', xy_PsN, history = gthst_grd ) ! (in)
!!$
!!$  end subroutine GroundFileOutput
!!$
!!$  !-------------------------------------------------------------------
!!$
!!$  subroutine GroundFileClose
!!$    !
!!$    ! 地表面データファイル出力の終了処理を行います. 
!!$    !
!!$    ! Terminate ground data files output. 
!!$
!!$    ! モジュール引用 ; USE statements
!!$    !
!!$
!!$    ! gtool4 データ出力
!!$    ! Gtool4 data output
!!$    !
!!$    use gtool_history, only: HistoryClose
!!$
!!$    ! 宣言文 ; Declaration statements
!!$    !
!!$    implicit none
!!$
!!$    ! 作業変数
!!$    ! Work variables
!!$    !
!!$
!!$    ! 実行文 ; Executable statement
!!$    !
!!$    if ( .not. ground_file_opened ) return
!!$
!!$    call HistoryClose( history = gthst_grd ) ! (inout)
!!$
!!$    ground_file_opened = .false.
!!$  end subroutine GroundFileClose

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

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

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

    ! 時刻管理
    ! Time control
    !
    use timeset, only: DelTime  ! $ \Delta t $ [s]

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

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

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

    ! 宣言文 ; Declaration statements
    !
    implicit none

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

    ! NAMELIST 変数群
    ! NAMELIST group name
    !
    namelist /ground_file_io_nml/ &
      & SurfTempFile, &
      & SurfTempName, &
      & AlbedoFile, &
      & AlbedoName, &
      & HumidCoefFile, &
      & HumidCoefName, &
      & RoughLengthFile, &
      & RoughLengthName, &
      & HeatCapacityFile, &
      & HeatCapacityName, &
      & TempFluxFile, &
      & TempFluxName, &
      & SurfCondFile, &
      & SurfCondName, &
      & SurfHeightFile, &
      & SurfHeightName, &
      & FlagUseMatthewsAlbedo, &
      & FlagUseLOContrastRoughLength, &
      & FlagUseMatthewsRoughLength

          ! デフォルト値については初期化手続 "ground_file_io#GroundFileInit" 
          ! のソースコードを参照のこと. 
          !
          ! Refer to source codes in the initialization procedure
          ! "ground_file_io#GroundFileInit" for the default values. 
          !

!!$      & OutputFile, &
!!$      & IntValue, IntUnit


    ! 実行文 ; Executable statement
    !

    if ( ground_file_io_inited ) return
    call InitCheck

    ! デフォルト値の設定
    ! Default values settings
    !
    SurfTempFile     = ''
    SurfTempName     = ''
    AlbedoFile       = ''
    AlbedoName       = ''
    HumidCoefFile    = ''
    HumidCoefName    = ''
    RoughLengthFile  = ''
    RoughLengthName  = ''
    HeatCapacityFile = ''
    HeatCapacityName = ''
    TempFluxFile     = ''
    TempFluxName     = ''
    SurfCondFile     = ''
    SurfCondName     = ''
    SurfHeightFile   = ''
    SurfHeightName   = ''
    FlagUseMatthewsAlbedo = .false.
    FlagUseLOContrastRoughLength = .false.
    FlagUseMatthewsRoughLength   = .false.

!!$    OutputFile = 'sst.nc'
!!$    IntValue   = 1.0_DP
!!$    IntUnit    = 'day'

    ! NAMELIST の読み込み
    ! NAMELIST is input
    !
    if ( trim(namelist_filename) /= '' ) then
      call FileOpen( unit_nml, &          ! (out)
        & namelist_filename, mode = 'r' ) ! (in)

      rewind( unit_nml )
      read( unit_nml, &         ! (in)
        & nml = ground_file_io_nml, &  ! (out)
        & iostat = iostat_nml ) ! (out)
      close( unit_nml )

      call NmlutilMsg( iostat_nml, module_name ) ! (in)
      if ( iostat_nml == 0 ) write( STDOUT, nml = ground_file_io_nml )
    end if

!!$    ! 出力時間間隔の設定
!!$    ! Configure time interval of output 
!!$    !
!!$    call DCDiffTimeCreate( PrevOutputTime, & ! (out)
!!$      & sec = 0.0_DP )                       ! (in)
!!$    call DCDiffTimeCreate( IntTime, & ! (out)
!!$      & IntValue, IntUnit )           ! (in)

    ! 印字 ; Print
    !
    call MessageNotify( 'M', module_name, '----- Initialization Messages -----' )
    call MessageNotify( 'M', module_name, 'Input:: ' )
    call MessageNotify( 'M', module_name, '  SurfTempFile     = %c', c1 = trim(SurfTempFile) )
    call MessageNotify( 'M', module_name, '  SurfTempName     = %c', c1 = trim(SurfTempName        ) )
    call MessageNotify( 'M', module_name, '  AlbedoFile       = %c', c1 = trim(AlbedoFile      ) )
    call MessageNotify( 'M', module_name, '  AlbedoName       = %c', c1 = trim(AlbedoName      ) )
    call MessageNotify( 'M', module_name, '  HumidCoefFile    = %c', c1 = trim(HumidCoefFile  ) )
    call MessageNotify( 'M', module_name, '  HumidCoefName    = %c', c1 = trim(HumidCoefName  ) )
    call MessageNotify( 'M', module_name, '  RoughLengthFile  = %c', c1 = trim(RoughLengthFile ) )
    call MessageNotify( 'M', module_name, '  RoughLengthName  = %c', c1 = trim(RoughLengthName ) )
    call MessageNotify( 'M', module_name, '  HeatCapacityFile = %c', c1 = trim(HeatCapacityFile) )
    call MessageNotify( 'M', module_name, '  HeatCapacityName = %c', c1 = trim(HeatCapacityName) )
    call MessageNotify( 'M', module_name, '  TempFluxFile     = %c', c1 = trim(TempFluxFile  ) )
    call MessageNotify( 'M', module_name, '  TempFluxName     = %c', c1 = trim(TempFluxName  ) )
    call MessageNotify( 'M', module_name, '  SurfCondFile     = %c', c1 = trim(SurfCondFile   ) )
    call MessageNotify( 'M', module_name, '  SurfCondName     = %c', c1 = trim(SurfCondName   ) )
    call MessageNotify( 'M', module_name, '  SurfHeightFile   = %c', c1 = trim(SurfHeightFile   ) )
    call MessageNotify( 'M', module_name, '  SurfHeightName   = %c', c1 = trim(SurfHeightName   ) )
    call MessageNotify( 'M', module_name, '  FlagUseMatthewsAlbedo = %y', l  = (/ FlagUseMatthewsAlbedo /) )
    call MessageNotify( 'M', module_name, '  FlagUseLOContrastRoughLength = %y', l  = (/ FlagUseLOContrastRoughLength /) )
    call MessageNotify( 'M', module_name, '  FlagUseMatthewsRoughLength = %y', l  = (/ FlagUseMatthewsRoughLength /) )



!!$    call MessageNotify( 'M', module_name, 'Output:: ' )
!!$    call MessageNotify( 'M', module_name, '  OutputFile = %c', c1 = trim(OutputFile) )
!!$    call MessageNotify( 'M', module_name, '  IntTime    = %f [%c]', d = (/ IntValue /), c1 = trim(IntUnit) )
    call MessageNotify( 'M', module_name, '-- version = %c', c1 = trim(version) )

    ground_file_io_inited = .true.
  end subroutine GroundFileInit

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

  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

    ! 物理定数設定
    ! Physical constants settings
    !
    use constants, only: constants_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. constants_inited ) &
      & call MessageNotify( 'E', module_name, '"constants" 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 ground_file_io
