!= 惑星表面データの設定
!
!= Setting planetary surface properties
!
! Authors::   Yasuhiro Morikawa, Yukiko Yamada, Yoshiyuki O. Takahashi, Shin-ichi Takehiro
! Version::   $Id: surface_properties.f90,v 1.20 2025/09/17 22:00:00 takepiro Exp $ 
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2008-2025. All rights reserved.
! License::   See COPYRIGHT[link:../../../COPYRIGHT]
!

module surface_properties
  !
  != 惑星表面特性の設定
  !
  != Setting planetary surface properties
  !
  ! <b>Note that Japanese and English are described in parallel.</b>
  !
  ! 海面温度や地表面諸量を設定します. 
  !
  ! Data about sea surface temperature (SST) or various values on surface
  ! are set. 
  !
  !== Procedures List
  ! SetSurfaceProperties  :: 惑星表面特性の設定
  !--
!!$  ! GroundFileOpen   :: 地表面データファイルのオープン
!!$  ! GroundFileOutput :: 地表面データファイルへのデータ出力
!!$  ! GroundFileClose  :: 地表面データファイルのクローズ
  !++
  ! ------------     :: ------------
  ! SetSurfaceProperties  :: Setting surface properties
  !--
!!$  ! GroundFileOpen   :: Open ground data file
!!$  ! GroundFileOutput :: Data output to ground data file
!!$  ! GroundFileClose  :: Close ground data file
  !++
  !
  !== NAMELIST
  !
  ! NAMELIST#surface_properties_nml
  !

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

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

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

  ! gtool5 データ出力
  ! Gtool5 data output
  !
  use gtool_history, only: GT_HISTORY

  ! 格子点設定
  ! 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

  ! 宣言文 ; Declaration statements
  !
  implicit none
  private

  ! 公開手続き
  ! Public procedure
  !
  public:: SetSurfaceProperties
  public:: SurfacePropertiesInit

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

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

  ! 非公開変数
  ! Private variables
  !
  logical          , save:: FlagSlabOcean
                              ! スラブオーシャン オン／オフ.
                              ! flag for use of slab ocean on/off

  character(STRING), save:: SurfTempSetting
                              ! 地表面温度の設定方法
                              ! Setting of surface temperature
  character(STRING), save:: SurfTempFile
                              ! 地表面温度のファイル名. 
                              ! File name of surface temperature
  character(TOKEN) , save:: SurfTempName
                              ! 地表面温度の変数名. 
                              ! Variable name of surface temperature

  character(STRING), save:: SeaIceSetting
                              ! 海氷面密度の設定方法
                              ! Setting of sea ice concentration
  character(STRING), save:: SeaIceFile
                              ! 海氷面密度のファイル名. 
                              ! File name of sea ice concentration
  character(TOKEN) , save:: SeaIceName
                              ! 海氷面密度の変数名. 
                              ! Variable name of sea ice concentration

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

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

  character(STRING), save:: RoughLengthSetting
                              ! 地表粗度長の設定方法
                              ! Setting of surface rough length
  character(STRING), save:: RoughLengthFile
                              ! 地表粗度長のファイル名. 
                              ! File name of surface rough length
  character(TOKEN) , save:: RoughLengthName
                              ! 地表粗度長の変数名. 
                              ! Variable name of surface rough length
  character(STRING), save:: HeatCapacitySetting
                              ! 地表熱容量の設定方法
                              ! Setting of surface heat capacity
  character(STRING), save:: HeatCapacityFile
                              ! 地表熱容量のファイル名. 
                              ! File name of surface heat capacity
  character(TOKEN) , save:: HeatCapacityName
                              ! 地表熱容量の変数名. 
                              ! Variable name of surface heat capacity

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

  character(STRING), save:: SurfCondSetting
                              ! 惑星表面状態の設定方法
                              ! Setting of surface condition
  character(STRING), save:: SurfCondFile
                              ! 惑星表面状態のファイル名. 
                              ! File name of surface condition
  character(TOKEN) , save:: SurfCondName
                              ! 惑星表面状態の変数名. 
                              ! Variable name of surface condition

  character(STRING), save:: SurfTypeSetting
                              ! 惑星表面タイプ (土地利用) の設定方法
                              ! Setting of surface type (land use)
  character(STRING), save:: SurfTypeFile
                              ! 惑星表面タイプ (土地利用) のファイル名. 
                              ! File name of surface type (land use)
  character(TOKEN) , save:: SurfTypeName
                              ! 惑星表面タイプ (土地利用) の変数名. 
                              ! Variable name of surface type (land use)

  character(STRING), save:: SurfCulIntSetting
                              ! ... の設定方法
                              ! Setting of surface cultivation intensity
  character(STRING), save:: SurfCulIntFile
                              ! ... のファイル名. 
                              ! File name of surface cultivation intensity
  character(TOKEN) , save:: SurfCulIntName
                              ! ... の変数名. 
                              ! Variable name of surface cultivation intensity

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

  character(STRING), save:: SurfHeightStdSetting
                              ! 
                              ! Setting of surface height standard deviation
  character(STRING), save:: SurfHeightStdFile
                              ! 
                              ! File name of surface height standard deviation
  character(TOKEN) , save:: SurfHeightStdName
                              ! 
                              ! Variable name of surface height standard deviation

  character(STRING), save:: SoilHeatCapSetting
                              ! 土壌熱容量の設定方法
                              ! Setting of heat conduction coefficient of soil
  character(STRING), save:: SoilHeatCapFile
                              ! 土壌熱容量のファイル名. 
                              ! File name of heat conduction coefficient of soil
  character(TOKEN) , save:: SoilHeatCapName
                              ! 土壌熱容量の変数名. 
                              ! Variable name of heat conduction coefficient of soil

  character(STRING), save:: SoilHeatDiffCoefSetting
                              ! 土壌熱伝導率の設定方法
                              ! Setting of heat conduction coefficient of soil
  character(STRING), save:: SoilHeatDiffCoefFile
                              ! 土壌熱伝導率のファイル名. 
                              ! File name of heat conduction coefficient of soil
  character(TOKEN) , save:: SoilHeatDiffCoefName
                              ! 土壌熱伝導率の変数名. 
                              ! Variable name of heat conduction coefficient of soil

  real(DP), save:: RoughLenHeatFactor
                              ! 運動量と熱の地表粗度長の比.
                              ! Ratio of roughness length for momentum and heat

  logical, save:: FlagUseBucket



!!$  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 = 'surface_properties'
                              ! モジュールの名称. 
                              ! Module name
  character(*), parameter:: version = &
    & '$Name:  $' // &
    & '$Id: surface_properties.f90,v 1.20 2025/09/17 22:00:00 takepiro Exp $'
                              ! モジュールのバージョン
                              ! Module version


contains

  subroutine SetSurfaceProperties(                       &
    & xy_SurfMajCompIceB, xy_SoilMoistB, xy_SurfSnowB,   & ! (in)    optional
    & xy_SOSeaIceMassB,                                  & ! (in)    optional
    & xy_SurfTemp, xy_SurfAlbedo, xy_SurfHumidCoef,      & ! (inout) optional
    & xy_SurfRoughLenMom, xy_SurfRoughLenHeat,           & ! (inout) optional
    & xy_SurfHeatCapacity,                               & ! (inout) optional
    & xy_DeepSubSurfHeatFlux, xy_SurfCond, xy_SurfType,  & ! (inout) optional
    & xy_SurfHeight, xy_SurfHeightStd,                   & ! (inout) optional
    & xy_SeaIceConc,                                     & ! (inout) optional
    & xy_SoilHeatCap, xy_SoilHeatDiffCoef                & ! (inout) optional
    & )
    !
    ! 惑星表面特性を設定します. 
    !
    ! Set surface properties. 
    !

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

    ! MPI
    !
    use mpi_wrapper, only : flag_mpi_init

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

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

    ! ヒストリデータ出力
    ! History data output
    !
    use gtool_historyauto, only: HistoryAutoPut

    ! 時系列データの読み込み
    ! Reading time series
    !
    use read_time_series, only: SetValuesFromTimeSeriesWrapper

    ! 時刻管理
    ! Time control
    !
    use timeset, only: &
      & TimeN, &              ! ステップ $ t $ の時刻.
                              ! Time of step $ t $.
      & TimesetClockStart, TimesetClockStop

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

    !
    ! Routines for GABLS tests
    !
    use gabls, only : SetGabls2SurfTemp

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

    ! バケツモデル
    ! Bucket model
    !
    use Bucket_Model, only : BucketSetFlagOceanFromMatthews, BucketModHumidCoef

    ! 雪と海氷によるアルベド変化
    ! modification of surface albedo on the snow covered ground and on the sea ice
    !
    use modify_albedo_snowseaice, only: ModAlbedoDueToSnowSeaIce

    ! アルベド, 粗度長の設定, 陸面と海洋の差のみ考慮
    ! Set albedo and roughness length, only considering land-ocean contrast
    !
    use surface_properties_lo, only: &
      & SetAlbedoLO, SetRoughLenLO

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

    ! 土壌熱伝導係数の設定
    ! set soil thermal diffusion coefficient
    !
    use soil_thermdiffcoef, only : SetSoilThermDiffCoefSimple

    ! 雪, 氷の割合
    ! snow/ice fraction
    !
    use snowice_frac, only : SeaIceAboveThreshold

    ! 宣言文 ; Declaration statements
    !
    real(DP), intent(in   ), optional:: xy_SurfMajCompIceB(0:imax-1, 1:jmax)
                              ! $ M_mcs (t-\Delta t) $ .
                              ! Surface major component ice amount (kg m-2)
    real(DP), intent(in   ), optional:: xy_SoilMoistB(0:imax-1, 1:jmax)
                              ! $ M_ws (t-\Delta t) $ . 土壌水分 (kg m-2)
                              ! Soil moisture (kg m-2)
    real(DP), intent(in   ), optional:: xy_SurfSnowB(0:imax-1, 1:jmax)
                              ! $ M_ss (t-\Delta t) $ . 積雪量 (kg m-2)
                              ! Surface snow amount (kg m-2)
    real(DP), intent(in   ), optional:: xy_SOSeaIceMassB(0:imax-1, 1:jmax)
                              ! $ M_si (t-\Delta t) $ . 
                              ! Slab seaice mass (kg m-2)
    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_SurfRoughLenMom (0:imax-1, 1:jmax)
                              ! 地表粗度長. 
                              ! Surface rough length for momentum
    real(DP), intent(inout), optional:: xy_SurfRoughLenHeat(0:imax-1, 1:jmax)
                              ! 地表粗度長. 
                              ! Surface rough length for heat
    real(DP), intent(inout), optional:: xy_SurfHeatCapacity (0:imax-1, 1:jmax)
                              ! 地表熱容量. 
                              ! Surface heat capacity
    real(DP), intent(inout), optional:: xy_DeepSubSurfHeatFlux (0:imax-1, 1:jmax)
                              ! 地中熱フラックス. 
                              ! "Deep subsurface heat flux"
                              ! Heat flux at the bottom of surface/soil layer.
    integer , intent(inout), optional:: xy_SurfCond (0:imax-1, 1:jmax)
                              ! 惑星表面状態 (0: 固定, 1: 可変). 
                              ! Surface condition (0: fixed, 1: variable)
    integer , intent(inout), optional:: xy_SurfType (0:imax-1, 1:jmax)
                              ! 惑星表面タイプ (土地利用)
                              ! Surface type (land use)
    real(DP), intent(inout), optional:: xy_SurfHeight   (0:imax-1, 1:jmax)
                              ! $ z_s $ . 地表面高度. 
                              ! Surface height. 
    real(DP), intent(inout), optional:: xy_SurfHeightStd(0:imax-1, 1:jmax)
                              ! $ z_s $ . 地表面高度. 
                              ! Surface height. 
    real(DP), intent(inout), optional:: xy_SeaIceConc(0:imax-1,1:jmax)
                              ! 海氷密度 (0 <= xy_SeaIceConc <= 1)
                              ! Sea ice concentration (0 <= xy_SeaIceConc <= 1)
    real(DP), intent(inout), optional:: xy_SoilHeatCap(0:imax-1,1:jmax)
                              ! 土壌熱容量 (J K-1 kg-1)
                              ! Specific heat of soil (J K-1 kg-1)
    real(DP), intent(inout), optional:: xy_SoilHeatDiffCoef(0:imax-1,1:jmax)
                              ! 土壌熱伝導率 (W m-1 K-1)
                              ! Heat conduction coefficient of soil (W m-1 K-1)

    ! 作業変数
    ! Work variables
    !
    real(DP), allocatable, save:: xy_SurfTempSave (:,:)
                              ! 地表面温度の保存値 (K)
                              ! Saved values of surface temperature (K)
    real(DP), allocatable, save:: xy_SeaIceConcSave(:,:)
                              ! 海氷面密度の保存値
                              ! Saved values of sea ice concentration
    real(DP), allocatable, save:: xy_SurfAlbedoSave(:,:)
                              ! アルベドの保存値
                              ! Saved values of albedo

    logical      :: xy_BucketFlagOceanGrid(0:imax-1,1:jmax)
                              !
                              ! Flag for ocean grid point used in bucket model
    real(DP), allocatable, save:: xy_SurfCulIntSave(:,:)
    real(DP)                   :: xy_SurfCulInt    (0:imax-1,1:jmax)
                              !
                              ! Surface cultivation intensity

    logical, save:: flag_first_SurfCond            = .true.
                              ! 初回を示すフラグ. 
                              ! Flag that indicates first loop
                              !
    logical, save:: flag_first_SurfType            = .true.
    logical, save:: flag_first_SurfCulInt          = .true.
    logical, save:: flag_first_SeaIceConc          = .true.
    logical, save:: flag_first_SurfTemp            = .true.
    logical, save:: flag_first_SurfHeight          = .true.
    logical, save:: flag_first_SurfHeightStd       = .true.
    logical, save:: flag_first_SurfAlbedo          = .true.
    logical, save:: flag_first_SurfHumidCoef       = .true.
    logical, save:: flag_first_SurfRoughLen        = .true.
    logical, save:: flag_first_SurfHeatCapacity    = .true.
    logical, save:: flag_first_DeepSubSurfHeatFlux = .true.
    logical, save:: flag_first_SoilHeatCap         = .true.
    logical, save:: flag_first_SoilHeatDiffCoef    = .true.

    logical :: FlagSetSurfType
    logical :: FlagSetSeaIceConc
    logical :: FlagSetSurfCond
    logical :: FlagSetSurfCulInt
    logical :: FlagSetSurfTemp
    logical :: FlagSetSurfHeight
    logical :: FlagSetSurfHeightStd
    logical :: FlagSetSurfAlbedo
    logical :: FlagSetSurfHumidCoef
    logical :: FlagSetSurfRoughLenMom
    logical :: FlagSetSurfRoughLenHeat
    logical :: FlagSetSurfHeatCapacity
    logical :: FlagSetDeepSubSurfHeatFlux
    logical :: FlagSetSoilHeatCap
    logical :: FlagSetSoilHeatDiffCoef

    integer:: i               ! 経度方向に回る DO ループ用作業変数
                              ! Work variables for DO loop in longitude
    integer:: j               ! 緯度方向に回る DO ループ用作業変数
                              ! Work variables for DO loop in latitude


    ! 実行文 ; Executable statement
    !

    ! 初期化確認
    ! Initialization check
    !
    if ( .not. surface_properties_inited ) then
      call MessageNotify( 'E', module_name, 'This module has not been initialized.' )
    end if


    ! 計算時間計測開始
    ! Start measurement of computation time
    !
    call TimesetClockStart( module_name )

    FlagSetSurfType            = .false.
    FlagSetSeaIceConc          = .false.
    FlagSetSurfCond            = .false.
    FlagSetSurfCulInt          = .false.
    FlagSetSurfTemp            = .false.
    FlagSetSurfHeight          = .false.
    FlagSetSurfHeightStd       = .false.
    FlagSetSurfAlbedo          = .false.
    FlagSetSurfHumidCoef       = .false.
    FlagSetSurfRoughLenMom     = .false.
    FlagSetSurfRoughLenHeat    = .false.
    FlagSetSurfHeatCapacity    = .false.
    FlagSetDeepSubSurfHeatFlux = .false.
    FlagSetSoilHeatCap         = .false.
    FlagSetSoilHeatDiffCoef    = .false.


    ! NOTICE:
    ! The surface condition has to be set, before other fields are set.
    !
    ! 惑星表面タイプ (土地利用)
    ! Surface type (land use)
    !
    if ( present(xy_SurfType) ) then

      if ( SurfTypeSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SurfType ) then
          call HistoryGet( &
            & SurfTypeFile, SurfTypeName, &     ! (in)
            & xy_SurfType, &                    ! (out)
            & flag_mpi_split = flag_mpi_init )  ! (in) optional
        end if
        if ( SurfCondSetting /= 'generate_from_SurfType' ) then
          call MessageNotify( 'E', module_name, &
            & " SurfCond has to be 'generate_from_SurfType', if SurfTypeSetting = %c.", &
            & c1 = trim(SurfTypeSetting) )
        end if
      else if ( SurfTypeSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_SurfType ) then
          call SetSurfData( &
            & xy_SurfType = xy_SurfType &                   ! (out)
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' SurfTypeSetting = %c is not appropriate.', &
          & c1 = trim(SurfTypeSetting) )
      end if

      FlagSetSurfType = .true.

      flag_first_SurfType = .false.

    end if


    ! NOTICE:
    ! The sea ice distribution has to be set, 
    ! before set SurfTemp (surface temperature) and SurfCond. 
    !
    ! 海氷面密度
    ! Sea ice concentration
    !
    if ( present(xy_SeaIceConc) ) then

      if ( flag_first_SeaIceConc ) then
        ! 保存用変数の割付
        ! Allocate a variable for save
        !
        allocate( xy_SeaIceConcSave(0:imax-1, 1:jmax) )
      end if
      if ( SeaIceSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !

        ! This will be deleted near future (yot, 2010/10/11)
!!$        if ( flag_first_SeaIceConc ) then
!!$          call HistoryGet( &
!!$            & SeaIceFile, SeaIceName,          & ! (in)
!!$            & xy_SeaIceConcSave,               & ! (out)
!!$            & flag_mpi_split = flag_mpi_init )   ! (in) optional
!!$        end if
        call SetValuesFromTimeSeriesWrapper(    &
          & 'SIC',                              &
          & SeaIceFile, SeaIceName,             &
          & xy_SeaIceConcSave                   &               ! (inout)
          & )
      else if ( SeaIceSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_SeaIceConc ) then
          call SetSurfData( &
            & xy_SeaIceConc = xy_SeaIceConcSave &                   ! (out)
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' SeaIceSetting = %c is not appropriate.', &
          & c1 = trim(SeaIceSetting) )
      end if
      ! 海氷面密度の設定 ( xy_SurfCond == 0 の場所のみ )
      ! Setting of sea ice concentration ( where xy_SurfCond == 0 only )
      !
      xy_SeaIceConc = xy_SeaIceConcSave

      FlagSetSeaIceConc = .true.

      flag_first_SeaIceConc = .false.

    end if


    ! 惑星表面状態
    ! Surface condition
    ! Flag whether surface temperature is calculated or not
    ! 0 : surface temperature is not calculated
    ! 1 : surface temperature is     calculated
    !
    if ( present(xy_SurfCond) ) then

      ! NOTICE:
      ! Before set SurfCond, SeaIceConc has to be set.
      if ( .not. FlagSetSeaIceConc ) then
        call MessageNotify( 'E', module_name, &
          & " SeaIceConc has to be set before setting SurfCond is set." )
      end if

      if ( SurfCondSetting == 'generate_from_SurfType' ) then
        if ( flag_first_SurfCond ) then
!!$          if ( ( SurfTypeSetting /= 'file' ) .and. ( SurfTypeSetting /= 'generate_internally' ) ) then
!!$            call MessageNotify( 'E', module_name, &
!!$              & " SurfCond has to be 'generate_from_SurfType' or 'generate_internally', if SurfTypeSetting = %c.", &
!!$              & c1 = trim(SurfTypeSetting) )
!!$          end if
          call MessageNotify( 'M', module_name, &
            & ' xy_SurfCond is constructed by use of xy_SurfType values because SurfTypeSetting = %c.', &
            & c1 = trim(SurfTypeSetting) )
        end if
        do j = 1, jmax
          do i = 0, imax-1
            if ( xy_SurfType(i,j) == 0 ) then
              if ( SeaIceAboveThreshold( xy_SeaIceConc(i,j) ) ) then
                xy_SurfCond(i,j) = 1
              else if ( FlagSlabOcean ) then
                xy_SurfCond(i,j) = 1
              else
                xy_SurfCond(i,j) = 0
              end if
            else
              xy_SurfCond(i,j) = 1
            end if
          end do
        end do

      else if ( SurfCondSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SurfCond ) then
          call HistoryGet( &
            & SurfCondFile, SurfCondName, &     ! (in)
            & xy_SurfCond, &                    ! (out)
            & flag_mpi_split = flag_mpi_init )  ! (in) optional
        end if
      else if ( SurfCondSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_SurfCond ) then
          call SetSurfData( &
            & xy_SurfCond = xy_SurfCond &                   ! (out)
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' SurfCondSetting = %c is not appropriate.', &
          & c1 = trim(SurfCondSetting) )
      end if

      ! Check of SurfCond values
      !
      do j = 1, jmax
        do i = 0, imax-1
          if ( ( xy_SurfCond(i,j) < 0 ) .or. ( xy_SurfCond(i,j) > 1 ) ) then
            call MessageNotify( 'E', module_name, &
              & ' SurfCond value of %d is not appropriate.', &
              & i = (/ xy_SurfCond(i,j) /) )
          end if
        end do
      end do

      FlagSetSurfCond = .true.

      flag_first_SurfCond = .false.

    end if


    ! 
    ! Surface cultivation index
    !
    ! Cultivation intensity is set only when xy_SurfType is present.
    if ( present( xy_SurfType ) ) then

      ! NOTICE:
      ! Before set SurfCulInt, SurfType has to be set.
      if ( .not. FlagSetSurfType ) then
        call MessageNotify( 'E', module_name, &
          & " SurfType has to be set before setting SurfCulInt is set." )
      end if

      if ( flag_first_SurfCulInt ) then
        ! 保存用変数の割付
        ! Allocate a variable for save
        !
        allocate( xy_SurfCulIntSave(0:imax-1, 1:jmax) )
      end if
      if ( SurfCulIntSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( SurfTypeSetting /= 'file' ) then
          call MessageNotify( 'E', module_name, &
            & " SurfType has to be 'file', when SurfCulIntSetting = %c.", &
            & c1 = trim(SurfCulIntSetting) )
        end if
        call SetValuesFromTimeSeriesWrapper(    &
          & 'CI',                               &
          & SurfCulIntFile, SurfCulIntName,     &
          & xy_SurfCulIntSave                   &               ! (inout)
          & )
      else if ( SurfCulIntSetting == 'generate_internally' ) then
        xy_SurfCulIntSave = 0.0_DP
      else
        call MessageNotify( 'E', module_name, &
          & ' SurfCulIntSetting = %c is not appropriate.', &
          & c1 = trim(SurfCulIntSetting) )
      end if
      !
      xy_SurfCulInt = xy_SurfCulIntSave

      FlagSetSurfCulInt = .true.
      flag_first_SurfCulInt = .false.
    else
      xy_SurfCulInt = 0.0_DP

      FlagSetSurfCulInt = .true.
    end if



    ! 地表面温度
    ! surface temperature
    !
    if ( present(xy_SurfTemp) ) then

      ! NOTICE:
      ! Before set surface temperature, sea ice distribution has to be set.
      if ( .not. FlagSetSeaIceConc ) then
        call MessageNotify( 'E', module_name, &
          & " SeaIceConc has to be set before setting SurfTemp is set." )
      end if

      if ( flag_first_SurfTemp ) then
        ! 保存用変数の割付
        ! Allocate a variable for save
        !
        allocate( xy_SurfTempSave  (0:imax-1, 1:jmax) )
      end if
      if ( SurfTempSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !

        ! This will be deleted near future (yot, 2010/10/11)
!!$        if ( flag_first_SurfTemp ) then
!!$          call HistoryGet( &
!!$            & SurfTempFile, SurfTempName, &    ! (in)
!!$            & xy_SurfTempSave, &               ! (out)
!!$            & flag_mpi_split = flag_mpi_init ) ! (in) optional
!!$        end if
        call SetValuesFromTimeSeriesWrapper(    &
          & 'SST',                              &
          & SurfTempFile, SurfTempName,         &
          & xy_SurfTempSave                     &               ! (inout)
          & )
      else if ( SurfTempSetting == 'GABLS2' ) then
        !
        ! Routines for GABLS tests
        !
        call SetGabls2SurfTemp(     &
          & xy_SurfTempSave         & ! (out)
          & )
      else if ( SurfTempSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_SurfTemp ) then
          call SetSurfData( &
            & xy_SurfTemp = xy_SurfTempSave & ! (out) optional
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' SurfTempSetting = %c is not appropriate.', &
          & c1 = trim(SurfTempSetting) )
      end if
      ! 地表面温度を SST で置き換え ( xy_SurfCond <=0 の場所のみ )
      ! Surface temperature is replaced with SST ( only xy_SurfCond <=0 )
      !
      if ( present(xy_SurfTemp) ) then

        if ( .not. present( xy_SurfCond ) ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfCond has to be present to set xy_SurfTemp.' )
        end if
        if ( .not. present( xy_SeaIceConc ) ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SeaIceConc has to be present to set xy_SurfTemp.' )
        end if

        do j = 1, jmax
          do i = 0, imax-1
            if ( xy_SurfCond(i,j) == 0 ) then
              xy_SurfTemp(i,j) = xy_SurfTempSave(i,j)
            end if
          end do
        end do

      end if

      FlagSetSurfTemp = .true.

      flag_first_SurfTemp = .false.
    end if


    ! 地形
    ! Topography
    !
    if ( present(xy_SurfHeight) ) then

      if ( SurfHeightSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SurfHeight ) then
          call HistoryGet( &
            & SurfHeightFile, SurfHeightName, &  ! (in)
            & xy_SurfHeight, &                   ! (out)
            & flag_mpi_split = flag_mpi_init )   ! (in) optional
        end if
      else if ( SurfHeightSetting == 'generate_internally' ) then
        if ( flag_first_SurfHeight ) then
          xy_SurfHeight = 0.0_DP
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' SurfHeightSetting = %c is not appropriate.', &
          & c1 = trim(SurfHeightSetting) )
      end if

      FlagSetSurfHeight = .true.

      flag_first_SurfHeight = .false.
    end if

    ! 
    ! Surface height standard deviation
    !
    if ( present(xy_SurfHeightStd) ) then

      if ( SurfHeightStdSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SurfHeightStd ) then
          call HistoryGet( &
            & SurfHeightStdFile, SurfHeightStdName, & ! (in)
            & xy_SurfHeightStd, &                     ! (out)
            & flag_mpi_split = flag_mpi_init )        ! (in) optional
        end if
      else if ( SurfHeightStdSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        ! 
        if ( flag_first_SurfHeightStd ) then
          call SetSurfData( &
            & xy_SurfHeightStd = xy_SurfHeightStd  & ! (out)
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' SurfHeightStdSetting = %c is not appropriate.', &
          & c1 = trim(SurfHeightStdSetting) )
      end if

      FlagSetSurfHeightStd = .true.

      flag_first_SurfHeightStd = .false.
    end if


    ! アルベド
    ! Albedo
    !
    if ( present(xy_SurfAlbedo) ) then

      ! NOTICE:
      ! The surface condition and sea ice concentration have to be set, 
      ! before albedo is set.
      if ( ( .not. FlagSetSurfCond ) .or. ( .not. FlagSetSeaIceConc ) ) then
        call MessageNotify( 'E', module_name, &
          & " SurfCond and SeaIceConc have to be set before setting SurfAlbedo is set." )
      end if

      if ( flag_first_SurfAlbedo ) then
        ! 保存用変数の割付
        ! Allocate a variable for save
        !
        allocate( xy_SurfAlbedoSave(0:imax-1, 1:jmax) )
      end if
      if ( AlbedoSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SurfAlbedo ) then
          call HistoryGet( &
            & AlbedoFile, AlbedoName, &        ! (in)
            & xy_SurfAlbedoSave,      &        ! (out)
            & flag_mpi_split = flag_mpi_init ) ! (in) optional
        end if
!!$        call SetValuesFromTimeSeriesWrapper(    &
!!$          & 'surface_albedo',                   &
!!$          & AlbedoFile, AlbedoName,             &
!!$          & xy_SurfAlbedoSave                   &               ! (inout)
!!$          & )
      else if ( AlbedoSetting == 'Matthews' ) then
        ! アルベドを Matthews のデータをもとに設定
        ! Surface albedo is set based on Matthews' data
        !
        if ( .not. present( xy_SurfType ) ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfType has to be present to set xy_SurfAlbedo.' )
        end if
        if ( SurfTypeSetting /= 'file' ) then
          call MessageNotify( 'E', module_name, &
            & " SurfType has to be 'file', when AlbedoSetting = %c.", &
            & c1 = trim(AlbedoSetting) )
        end if
        call SetAlbedoMatthews( &
          & xy_SurfType,      &
          & xy_SurfAlbedoSave &
          & )
        ! Modify albedo due to cultivation
        call ModAlbedoMatthewsCultivation( &
          & xy_SurfType, xy_SurfCulInt,    &
          & xy_SurfAlbedoSave              &
          & )
      else if ( AlbedoSetting == 'LOContrast' ) then
        ! アルベドの設定, 陸面と海洋の差のみ考慮
        ! Set albedo, only considering land-ocean contrast
        !
        if ( .not. present( xy_SurfType ) ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfType has to be present to set xy_SurfAlbedo.' )
        end if
        if ( SurfTypeSetting /= 'file' ) then
          call MessageNotify( 'E', module_name, &
            & " SurfType has to be 'file', when AlbedoSetting = %c.", &
            & c1 = trim(AlbedoSetting) )
        end if
        call SetAlbedoLO(      &
          & xy_SurfType,       &
          & xy_SurfAlbedoSave  &
          & )
      else if ( AlbedoSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        ! 
        if ( flag_first_SurfAlbedo ) then
          call SetSurfData( &
            & xy_SurfAlbedo = xy_SurfAlbedoSave  & ! (out)
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' AlbedoSetting = %c is not appropriate.', &
          & c1 = trim(AlbedoSetting) )
      end if
      ! アルベドの設定
      ! Setting of albedo
      !
      xy_SurfAlbedo = xy_SurfAlbedoSave


      if ( present( xy_SurfType ) ) then
        ! 雪と海氷によるアルベド変化
        ! modification of surface albedo on the snow covered ground and on the sea ice
        !

        if ( .not. present( xy_SurfMajCompIceB ) ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfMajCompIceB has to be present to set xy_SurfAlbedo.' )
        end if
        if ( .not. present( xy_SurfSnowB ) ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfSnowB has to be present to set xy_SurfAlbedo.' )
        end if
        if ( .not. present( xy_SeaIceConc ) ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SeaIceConc has to be present to set xy_SurfAlbedo.' )
        end if

        if ( .not. present( xy_SurfType ) ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfType has to be present to set xy_SurfAlbedo.' )
        end if
!!$        if ( SurfTypeSetting /= 'file' ) then
!!$          call MessageNotify( 'E', module_name, &
!!$            & " SurfType has to be 'file'." )
!!$        end if

        call ModAlbedoDueToSnowSeaIce(                                         &
          & xy_SurfType,                                                       &
          & xy_SurfMajCompIceB, xy_SurfSnowB, xy_SeaIceConc, xy_SOSeaIceMassB, & ! (in   ) optional
          & xy_SurfTemp,                                                       & ! (in)
          & xy_SurfAlbedo                                                      & ! (inout)
          & )
      else
        call MessageNotify( 'E', module_name, &
          & ' xy_SurfType has to be present to modify albedo due to snow and sea ice.' )
      end if

      FlagSetSurfAlbedo = .true.

      flag_first_SurfAlbedo = .false.
    end if


    ! 惑星表面湿潤度
    ! Surface humidity coefficient
    !
    if ( present(xy_SurfHumidCoef) ) then

      ! NOTICE:
      ! The surface condition has to be set, before humidity coefficient 
      ! is set.
      if ( .not. FlagSetSurfCond ) then
        call MessageNotify( 'E', module_name, &
          & " SurfCond has to be set before setting SurfHumidCoef is set." )
      end if

      if ( HumidCoefSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SurfHumidCoef ) then
          call HistoryGet( &
            & HumidcoefFile, HumidcoefName, &  ! (in)
            & xy_SurfHumidcoef, &              ! (out)
            & flag_mpi_split = flag_mpi_init ) ! (in) optional
        end if
      else if ( HumidCoefSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_SurfHumidCoef ) then
          call SetSurfData( &
            & xy_SurfHumidCoef = xy_SurfHumidCoef  & ! (out)
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' HumidCoefSetting = %c is not appropriate.', &
          & c1 = trim(HumidCoefSetting) )
      end if

      if ( FlagUseBucket ) then
        if ( &
          & ( present( xy_SurfType   ) ) .and. &
          & ( present( xy_SoilMoistB ) ) .and. &
          & ( present( xy_SurfSnowB  ) )       &
          & ) then
          ! バケツモデルに関わる地表面湿潤度の設定
          ! Setting of surface humidity coefficient
          !
          call BucketSetFlagOceanFromMatthews( &
            & xy_SurfType,                     & ! (in)
            & xy_BucketFlagOceanGrid           & ! (out)
            & )
          call BucketModHumidCoef(                                 &
            & xy_BucketFlagOceanGrid, xy_SoilMoistB, xy_SurfSnowB, & ! (in   )
            & xy_SurfHumidCoef                                     & ! (inout)
            & )
        else
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfType, xy_SoilMoistB and xy_SurfSnowB have to be present to modify humidity coefficient with bucket model.' )
        end if
      end if

      FlagSetSurfHumidCoef = .true.

      flag_first_SurfHumidCoef = .false.
    end if


    ! 粗度長
    ! Roughness length
    !
    if ( present(xy_SurfRoughLenMom) ) then
      if ( .not. present(xy_SurfRoughLenHeat) ) then
        call MessageNotify( 'E', module_name, &
          & ' xy_SurfRoughLenHeat has to be present if xy_SurfRoughLenMom is present.' )
      end if
    else
      if ( present(xy_SurfRoughLenHeat) ) then
        call MessageNotify( 'E', module_name, &
          & ' xy_SurfRoughLenMom has to be present if xy_SurfRoughLenHeat is present.' )
      end if
    end if
    if ( present(xy_SurfRoughLenMom) .and. present(xy_SurfRoughLenHeat) ) then

      if ( RoughLengthSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SurfRoughLen ) then
          call HistoryGet( &
            & RoughLengthFile, RoughLengthName, & ! (in)
            & xy_SurfRoughLenMom, &               ! (out)
            & flag_mpi_split = flag_mpi_init )    ! (in) optional
          ! set roughness length for heat
          xy_SurfRoughLenHeat = xy_SurfRoughLenMom * RoughLenHeatFactor
        end if
      else if ( RoughLengthSetting == 'LOContrast' ) then
        ! 粗度長の設定, 陸面と海洋の差のみ考慮
        ! Set roughness length, only considering land-ocean contrast
        !
        if ( .not. present( xy_SurfType ) ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfType has to be present to set xy_SurfAlbedo.' )
        end if
        if ( SurfTypeSetting /= 'file' ) then
          call MessageNotify( 'E', module_name, &
            & " SurfType has to be 'file', when RoughLengthSetting = %c.", &
            & c1 = trim(RoughLengthSetting) )
        end if
        call SetRoughLenLO(    &
          & xy_SurfType,       &
          & xy_SurfRoughLenMom &
          & )
        ! set roughness length for heat
        xy_SurfRoughLenHeat = xy_SurfRoughLenMom * RoughLenHeatFactor
      else if ( RoughLengthSetting == 'Matthews' ) then
        ! 粗度長の設定, Matthews のデータに基づく
        ! Set roughness length based on Matthews dataset
        !
        if ( .not. FlagSetSurfType ) then
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfType has to be set to set xy_SurfRoughLenMom.' )
        end if
        if ( SurfTypeSetting /= 'file' ) then
          call MessageNotify( 'E', module_name, &
            & " SurfType has to be 'file', when RoughLengthSetting = %c.", &
            & c1 = trim(RoughLengthSetting) )
        end if
        call SetRoughLenLandMatthews( &
          & "Mom", xy_SurfType,       &
          & xy_SurfRoughLenMom        &
          & )
        ! Modify albedo due to cultivation
        call ModRoughLenMatthewsCultivation(   &
          & "Mom", xy_SurfType, xy_SurfCulInt, &
          & xy_SurfRoughLenMom                 &
          & )

        ! set roughness length for heat
        call SetRoughLenLandMatthews( &
          & "Heat", xy_SurfType,      &
          & xy_SurfRoughLenHeat       &
          & )
        ! Modify albedo due to cultivation
        call ModRoughLenMatthewsCultivation(    &
          & "Heat", xy_SurfType, xy_SurfCulInt, &
          & xy_SurfRoughLenHeat                 &
          & )

      else if ( RoughLengthSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_SurfRoughLen ) then
          call SetSurfData( &
            & xy_SurfRoughLength = xy_SurfRoughLenMom &          ! (out)
            & )
          ! set roughness length for heat
          xy_SurfRoughLenHeat = xy_SurfRoughLenMom * RoughLenHeatFactor
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' RoughLengthSetting = %c is not appropriate.', &
          & c1 = trim(RoughLengthSetting) )
      end if

      FlagSetSurfRoughLenMom  = .true.
      FlagSetSurfRoughLenHeat = .true.

      flag_first_SurfRoughLen = .false.
    end if


    ! 地表熱容量
    ! Surface heat capacity
    !
    if ( present(xy_SurfHeatCapacity) ) then

      if ( HeatCapacitySetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SurfHeatCapacity ) then
          call HistoryGet( &
            & HeatCapacityFile, HeatCapacityName, & ! (in)
            & xy_SurfHeatCapacity, &                ! (out)
            & flag_mpi_split = flag_mpi_init )      ! (in) optional
        end if
      else if ( HeatCapacitySetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_SurfHeatCapacity ) then
          call SetSurfData( &
            & xy_SurfHeatCapacity = xy_SurfHeatCapacity &          ! (out)
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' HeatCapacitySetting = %c is not appropriate.', &
          & c1 = trim(HeatCapacitySetting) )
      end if

      FlagSetSurfHeatCapacity = .true.

      flag_first_SurfHeatCapacity = .false.
    end if


    ! 地中熱フラックス
    ! Ground temperature flux
    !
    if ( present(xy_DeepSubSurfHeatFlux) ) then

      if ( TempFluxSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_DeepSubSurfHeatFlux ) then
          call HistoryGet( &
            & TempFluxFile, TempFluxName, &     ! (in)
            & xy_DeepSubSurfHeatFlux, &              ! (out)
            & flag_mpi_split = flag_mpi_init )  ! (in) optional
        end if
      else if ( TempFluxSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_DeepSubSurfHeatFlux ) then
          call SetSurfData( &
            & xy_DeepSubSurfHeatFlux = xy_DeepSubSurfHeatFlux &          ! (out)
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' TempFluxSetting = %c is not appropriate.', &
          & c1 = trim(TempFluxSetting) )
      end if

      FlagSetDeepSubSurfHeatFlux = .true.

      flag_first_DeepSubSurfHeatFlux = .false.
    end if


    ! 土壌熱容量 (J K-1 kg-1)
    ! Specific heat of soil (J K-1 kg-1)
    !
    if ( present(xy_SoilHeatCap) ) then

      if ( SoilHeatCapSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SoilHeatCap ) then
          call HistoryGet( &
            & SoilHeatCapFile, SoilHeatCapName, &     ! (in)
            & xy_SoilHeatCap, &              ! (out)
            & flag_mpi_split = flag_mpi_init )  ! (in) optional
        end if
      else if ( SoilHeatCapSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_SoilHeatCap ) then
          call SetSurfData( &
            & xy_SoilHeatCap = xy_SoilHeatCap &          ! (out)
            & )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' SoilHeatCapSetting = %c is not appropriate.', &
          & c1 = trim(SoilHeatCapSetting) )
      end if

      FlagSetSoilHeatCap = .true.

      flag_first_SoilHeatCap = .false.
    end if


    ! 土壌熱伝導率 (W m-1 K-1)
    ! Heat conduction coefficient of soil (W m-1 K-1)
    !
    if ( present(xy_SoilHeatDiffCoef) ) then

      if ( SoilHeatDiffCoefSetting == 'file' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SoilHeatDiffCoef ) then
          call HistoryGet( &
            & SoilHeatDiffCoefFile, SoilHeatDiffCoefName, &     ! (in)
            & xy_SoilHeatDiffCoef, &              ! (out)
            & flag_mpi_split = flag_mpi_init )  ! (in) optional
        end if
      else if ( SoilHeatDiffCoefSetting == 'file_thermal_inertia' ) then
        ! データをファイルから取得
        ! Data is input from files
        !
        if ( flag_first_SoilHeatDiffCoef ) then
          call HistoryGet( &
            & SoilHeatDiffCoefFile, SoilHeatDiffCoefName, &     ! (in)
            & xy_SoilHeatDiffCoef, &              ! (out)
            & flag_mpi_split = flag_mpi_init )  ! (in) optional

          if ( present( xy_SoilHeatCap ) ) then
            xy_SoilHeatDiffCoef = xy_SoilHeatDiffCoef**2 / xy_SoilHeatCap
          else
            call MessageNotify( 'E', module_name, &
              & ' xy_SoilHeatCap has to be present to calculate heat diffusion coefficient of soil from thermal inertia.' )
          end if
        end if
      else if ( SoilHeatDiffCoefSetting == 'generate_internally' ) then
        ! データ (デフォルト値) を surface_data モジュールから取得
        ! Data (default values) is input from "surface_data" module
        !
        if ( flag_first_SoilHeatDiffCoef ) then
          call SetSurfData( &
            & xy_SoilHeatDiffCoef = xy_SoilHeatDiffCoef &          ! (out)
            & )
        end if
      else if ( SoilHeatDiffCoefSetting == 'simple' ) then
        if ( .not. FlagUseBucket ) then
          call MessageNotify( 'E', module_name, &
            & ' FlagUseBucket has to be .true. to set soil thermal diffusion coefficient.' )
        end if
        if ( &
          & ( FlagSetSurfType          ) .and. &
          & ( present( xy_SoilMoistB ) )       &
          & ) then
          ! 土壌熱伝導係数の設定
          ! set soil thermal diffusion coefficient
          !
          call SetSoilThermDiffCoefSimple( &
            & xy_SurfType, xy_SoilMoistB,  & ! (in )
            & xy_SoilHeatDiffCoef          & ! (out)
            & )
        else
          call MessageNotify( 'E', module_name, &
            & ' xy_SurfType and xy_SoilMoistB have to be present to set soil thermal diffusion coefficient.' )
        end if
      else
        call MessageNotify( 'E', module_name, &
          & ' SoilHeatDiffCoefSetting = %c is not appropriate.', &
          & c1 = trim(TempFluxSetting) )
      end if

      FlagSetSoilHeatDiffCoef = .true.

      flag_first_SoilHeatDiffCoef = .false.
    end if


    ! ヒストリデータ出力
    ! History data output
    !
    call HistoryAutoPut( TimeN, 'SurfCulInt', xy_SurfCulInt )


    ! 計算時間計測一時停止
    ! Pause measurement of computation time
    !
    call TimesetClockStop( module_name )


  end subroutine SetSurfaceProperties

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

!!$  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 SurfacePropertiesInit(                     &
    & ArgFlagSlabOcean, ArgFlagUseBucket, ArgFlagSnow   & ! (in)
    & )
    !
    ! surface_properties モジュールの初期化を行います. 
    ! NAMELIST#surface_properties_nml の読み込みはこの手続きで行われます. 
    !
    ! "surface_properties" module is initialized. 
    ! "NAMELIST#surface_properties_nml" is loaded in this procedure. 
    !

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

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

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

    ! ヒストリデータ出力
    ! History data output
    !
    use gtool_historyauto, only: HistoryAutoAddVariable

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

    !
    ! Routines for GABLS tests
    !
    use gabls, only : GablsInit

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

    ! バケツモデル
    ! Bucket model
    !
    use Bucket_Model, only : BucketModelInit

    ! 雪と海氷によるアルベド変化
    ! modification of surface albedo on the snow covered ground and on the sea ice
    !
    use modify_albedo_snowseaice, only : ModAlbedoSnowSeaIceInit

    ! アルベド, 粗度長の設定, 陸面と海洋の差のみ考慮
    ! Set albedo and roughness length, only considering land-ocean contrast
    !
    use surface_properties_lo, only : SurfacePropertiesLOInit

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

    ! 土壌熱伝導係数の設定
    ! set soil thermal diffusion coefficient
    !
    use soil_thermdiffcoef, only : SoilThermDiffCoefInit

    ! メッセージ制御
    ! Message control
    !
    use mpi_messagecntl, only : DoesOutputMPIMessage


    ! 宣言文 ; Declaration statements
    !
    logical, intent(in ) :: ArgFlagSlabOcean
                              ! スラブオーシャン オン／オフ.
                              ! flag for use of slab ocean on/off
    logical, intent(in ) :: ArgFlagUseBucket
                              ! 
                              ! flag for bucket model
    logical, intent(in ) :: ArgFlagSnow
                              ! 
                              ! flag for snow

    ! 作業変数
    ! 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 /surface_properties_nml/ &
      & SurfTempSetting,     &
      & SurfTempFile,        &
      & SurfTempName,        &
      & SeaIceSetting,       &
      & SeaIceFile,          &
      & SeaIceName,          &
      & AlbedoSetting,       &
      & AlbedoFile,          &
      & AlbedoName,          &
      & HumidCoefSetting,    &
      & HumidCoefFile,       &
      & HumidCoefName,       &
      & RoughLengthSetting,  &
      & RoughLengthFile,     &
      & RoughLengthName,     &
      & HeatCapacitySetting, &
      & HeatCapacityFile,    &
      & HeatCapacityName,    &
      & TempFluxSetting,     &
      & TempFluxFile,        &
      & TempFluxName,        &
      & SurfCondSetting,     &
      & SurfCondFile,        &
      & SurfCondName,        &
      & SurfTypeSetting,     &
      & SurfTypeFile,        &
      & SurfTypeName,        &
      & SurfCulIntSetting,   &
      & SurfCulIntFile,      &
      & SurfCulIntName,      &
      & SurfHeightSetting,   &
      & SurfHeightFile,      &
      & SurfHeightName,      &
      & SurfHeightStdSetting,&
      & SurfHeightStdFile,   &
      & SurfHeightStdName,   &
      & SoilHeatCapSetting,  &
      & SoilHeatCapFile,     &
      & SoilHeatCapName,     &
      & SoilHeatDiffCoefSetting, &
      & SoilHeatDiffCoefFile,    &
      & SoilHeatDiffCoefName,    &
      & RoughLenHeatFactor

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

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


    ! 実行文 ; Executable statement
    !

    if ( surface_properties_inited ) return


    ! Set flag for slab ocean
    FlagUseBucket = ArgFlagUseBucket

    FlagSlabOcean = ArgFlagSlabOcean


    ! デフォルト値の設定
    ! Default values settings
    !
    SurfTempSetting         = 'generate_internally'
    SurfTempFile            = ''
    SurfTempName            = ''
    SeaIceSetting           = 'generate_internally'
    SeaIceFile              = ''
    SeaIceName              = ''
    AlbedoSetting           = 'generate_internally'
    AlbedoFile              = ''
    AlbedoName              = ''
    HumidCoefSetting        = 'generate_internally'
    HumidCoefFile           = ''
    HumidCoefName           = ''
    RoughLengthSetting      = 'generate_internally'
    RoughLengthFile         = ''
    RoughLengthName         = ''
    HeatCapacitySetting     = 'generate_internally'
    HeatCapacityFile        = ''
    HeatCapacityName        = ''
    TempFluxSetting         = 'generate_internally'
    TempFluxFile            = ''
    TempFluxName            = ''
    SurfCondSetting         = 'generate_internally'
    SurfCondFile            = ''
    SurfCondName            = ''
    SurfTypeSetting         = 'generate_internally'
    SurfTypeFile            = ''
    SurfTypeName            = ''
    SurfCulIntSetting       = 'generate_internally'
    SurfCulIntFile          = ''
    SurfCulIntName          = ''
    SurfHeightSetting       = 'generate_internally'
    SurfHeightFile          = ''
    SurfHeightName          = ''
    SurfHeightStdSetting    = 'generate_internally'
    SurfHeightStdFile       = ''
    SurfHeightStdName       = ''
    SoilHeatCapSetting      = 'generate_internally'
    SoilHeatCapFile         = ''
    SoilHeatCapName         = ''
    SoilHeatDiffCoefSetting = 'generate_internally'
    SoilHeatDiffCoefFile    = ''
    SoilHeatDiffCoefName    = ''

    RoughLenHeatFactor = 1.0_DP

!!$    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 = surface_properties_nml, &  ! (out)
        & iostat = iostat_nml           &  ! (out)
        & )
      close( unit_nml )

      call NmlutilMsg( iostat_nml, module_name ) ! (in)
      if ( iostat_nml == 0 .AND. DoesOutputMPIMessage() ) write( STDOUT, nml = surface_properties_nml )
    end if

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


    ! A Value of "SurfTempSetting" is checked.
    !
!!$    if ( ( SurfTempSetting == 'file' ) .and. ( FlagSlabOcean ) ) then
!!$      call MessageNotify( 'E', module_name, &
!!$        & "If FlagSlabOcean is .true., SurfTempSetting must not be 'file'." )
!!$    end if


    ! Initialization of modules used in this module
    !

    ! Matthews のデータに基づく惑星表面アルベド設定
    ! set surface albedo based on data by Matthews
    !
    call AlbedoMatthewsInit

    if ( FlagUseBucket ) then
      ! バケツモデル
      ! Bucket model
      !
      call BucketModelInit( &
        & ArgFlagSnow       &
        & )
    end if

    !
    ! Routines for GABLS tests
    !
    call GablsInit

    ! 雪と海氷によるアルベド変化
    ! modification of surface albedo on the snow covered ground and on the sea ice
    !
    call ModAlbedoSnowSeaIceInit

    ! アルベド, 粗度長の設定, 陸面と海洋の差のみ考慮
    ! Set albedo and roughness length, only considering land-ocean contrast
    !
    call SurfacePropertiesLOInit

    ! Matthews のデータに基づく地面粗度の設定
    ! set roughness length on land surface based on data by Matthews
    !
    call RoughLenMatthewsInit

    ! 土壌熱伝導係数の設定
    ! set soil thermal diffusion coefficient
    !
    call SoilThermDiffCoefInit( &
      & ArgFlagSnow &
      & )


    ! ヒストリデータ出力のためのへの変数登録
    ! Register of variables for history data output
    !
    call HistoryAutoAddVariable( 'SurfCulInt' , &  ! (in)
      & (/ 'lon ', 'lat ', 'time' /),           &  ! (in)
      & 'cultivation intensity', '1' )             ! (in)


    ! 印字 ; Print
    !
    call MessageNotify( 'M', module_name, '----- Initialization Messages -----' )
    call MessageNotify( 'M', module_name, 'Input:: ' )
    call MessageNotify( 'M', module_name, '  SurfTempSetting         = %c', c1 = trim(SurfTempSetting) )
    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, '  SeaIceSetting           = %c', c1 = trim(SeaIceSetting) )
    call MessageNotify( 'M', module_name, '  SeaIceFile              = %c', c1 = trim(SeaIceFile) )
    call MessageNotify( 'M', module_name, '  SeaIceName              = %c', c1 = trim(SeaIceName        ) )
    call MessageNotify( 'M', module_name, '  AlbedoSetting           = %c', c1 = trim(AlbedoSetting      ) )
    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, '  HumidCoefSetting        = %c', c1 = trim(HumidCoefSetting ) )
    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, '  RoughLengthSetting      = %c', c1 = trim(RoughLengthSetting ) )
    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, '  HeatCapacitySetting     = %c', c1 = trim(HeatCapacitySetting) )
    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, '  TempFluxSetting         = %c', c1 = trim(TempFluxSetting  ) )
    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, '  SurfCondSetting         = %c', c1 = trim(SurfCondSetting   ) )
    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, '  SurfTypeSetting         = %c', c1 = trim(SurfTypeSetting   ) )
    call MessageNotify( 'M', module_name, '  SurfTypeFile            = %c', c1 = trim(SurfTypeFile   ) )
    call MessageNotify( 'M', module_name, '  SurfTypeName            = %c', c1 = trim(SurfTypeName   ) )
    call MessageNotify( 'M', module_name, '  SurfCulIntSetting       = %c', c1 = trim(SurfCulIntSetting   ) )
    call MessageNotify( 'M', module_name, '  SurfCulIntFile          = %c', c1 = trim(SurfCulIntFile   ) )
    call MessageNotify( 'M', module_name, '  SurfCulIntName          = %c', c1 = trim(SurfCulIntName   ) )
    call MessageNotify( 'M', module_name, '  SurfHeightSetting       = %c', c1 = trim(SurfHeightSetting   ) )
    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, '  SurfHeightStdSetting    = %c', c1 = trim(SurfHeightStdSetting   ) )
    call MessageNotify( 'M', module_name, '  SurfHeightStdFile       = %c', c1 = trim(SurfHeightStdFile   ) )
    call MessageNotify( 'M', module_name, '  SurfHeightStdName       = %c', c1 = trim(SurfHeightStdName   ) )
    call MessageNotify( 'M', module_name, '  SoilHeatCapSetting      = %c', c1 = trim(SoilHeatCapSetting   ) )
    call MessageNotify( 'M', module_name, '  SoilHeatCapFile         = %c', c1 = trim(SoilHeatCapFile   ) )
    call MessageNotify( 'M', module_name, '  SoilHeatCapName         = %c', c1 = trim(SoilHeatCapName   ) )
    call MessageNotify( 'M', module_name, '  SoilHeatDiffCoefSetting = %c', c1 = trim(SoilHeatDiffCoefSetting   ) )
    call MessageNotify( 'M', module_name, '  SoilHeatDiffCoefFile    = %c', c1 = trim(SoilHeatDiffCoefFile   ) )
    call MessageNotify( 'M', module_name, '  SoilHeatDiffCoefName    = %c', c1 = trim(SoilHeatDiffCoefName   ) )

    call MessageNotify( 'M', module_name, '  RoughLenHeatFactor      = %f', d = (/RoughLenHeatFactor/) )


!!$    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) )

    surface_properties_inited = .true.

  end subroutine SurfacePropertiesInit

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

end module surface_properties
