!= radiation_band モジュールのテストプログラム
!
!= Test program for "radiation_band"
!
! Authors::   Yasuhiro MORIKAWA
! Version::   $Id: radiation_band_test01.f90,v 1.2 2008-09-23 18:00:33 morikawa Exp $
! Tag Name::  $Name: dcpam5-20080925 $
! Copyright:: Copyright (C) GFD Dennou Club, 2007. All rights reserved.
! License::   See COPYRIGHT[link:../../../COPYRIGHT]
!
! <b>Note that Japanese and English are described in parallel.</b>
!
! radiation_band モジュールの動作テストを行うためのプログラムです. 
! このプログラムがコンパイルできること, および実行時に 
! プログラムが正常終了することを確認してください. 
!
! This program checks the operation of "radiation_band" module. 
! Confirm compilation and execution of this program. 
!

program radiation_band_test01

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

  ! 放射フラックス
  ! Radiation flux
  !
  use radiation_band, only: RadiationFlux, RadiationCorrect, RadiationDTempDt

  ! 格子点設定
  ! Grid points settings
  !
  use gridset, only: imax, & ! 経度格子点数. 
                             ! Number of grid points in longitude
    &                jmax, & ! 緯度格子点数. 
                             ! Number of grid points in latitude
    &                kmax    ! 鉛直層数. 
  
  ! 時刻管理
  ! Time control
  !
  use timeset, only: DelTime, Cstep, TimesetGetCurrentTime, &
    & TimesetProgress

  ! 座標データ設定
  ! Axes data settings
  !
  use axesset, only: &
    & z_Sigma, &
                              ! $ \sigma $ レベル (整数). 
                              ! Full $ \sigma $ level
    & r_Sigma
                              ! $ \sigma $ レベル (半整数). 
                              ! Half $ \sigma $ level

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

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

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

  ! テスト支援
  ! Support tests
  !
  use dc_test, only: AssertEqual

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

  ! 宣言文 ; Declaration statements
  !
  implicit none

  ! 物理量
  ! Physical values
  !
  real(DP), allocatable:: xy_SurfTemp (:,:)
                              ! 地表面温度. 
                              ! Surface temperature
  real(DP), allocatable:: xy_SurfAlbedo (:,:)
                              ! 地表アルベド. 
                              ! Surface albedo
  real(DP), allocatable:: xyz_Temp (:,:,:)
                              ! $ T $ .     温度. Temperature
  real(DP), allocatable:: xyz_QVap (:,:,:)
                              ! $ q $ .     比湿. Specific humidity
  real(DP), allocatable:: xyr_Press (:,:,:)
                              ! $ p_s $ . 地表面気圧 (半整数レベル). 
                              ! Surface pressure (half level)

  real(DP), allocatable:: xyr_RadLFlux (:,:,:)
                              ! 長波フラックス. 
                              ! Long wave flux
  real(DP), allocatable:: xya_SurfRadLMtx (:,:,:)
                              ! $ T $ 陰解行列: 地表. 
                              ! $ T $ implicit matrix: surface
  real(DP), allocatable:: xyra_DelRadLFlux (:,:,:,:)
                              ! 長波地表温度変化. 
                              ! Surface temperature tendency with long wave
  real(DP), allocatable:: xyr_RadSFlux (:,:,:)
                              ! 短波 (日射) フラックス. 
                              ! Short wave (insolation) flux

  real(DP), allocatable:: xyr_RadLFluxAns (:,:,:)
                              ! 長波フラックス. 
                              ! Long wave flux
  real(DP), allocatable:: xya_SurfRadLMtxAns (:,:,:)
                              ! $ T $ 陰解行列: 地表. 
                              ! $ T $ implicit matrix: surface
  real(DP), allocatable:: xyra_DelRadLFluxAns (:,:,:,:)
                              ! 長波地表温度変化. 
                              ! Surface temperature tendency with long wave
  real(DP), allocatable:: xyr_RadSFluxAns (:,:,:)
                              ! 短波 (日射) フラックス. 
                              ! Short wave (insolation) flux

  real(DP), allocatable:: xyz_DTempDtRadL (:,:,:)
                              ! 長波加熱率. 
                              ! Temperature tendency with long wave
  real(DP), allocatable:: xyz_DTempDtRadS (:,:,:)
                              ! 短波加熱率. 
                              ! Temperature tendency with short wave

  real(DP), allocatable:: xyz_DTempDtRadLAns (:,:,:)
                              ! 長波加熱率. 
                              ! Temperature tendency with long wave
  real(DP), allocatable:: xyz_DTempDtRadSAns (:,:,:)
                              ! 短波加熱率. 
                              ! Temperature tendency with short wave



  ! 作業変数
  ! Work variables
  !
  integer:: i
  real(DP):: time_value
  character(STRING):: time_range

  ! 実行文 ; Executable statement
  !

  ! 主プログラムの初期化 (内部サブルーチン)
  ! Initialization for the main program (Internal subroutine)
  !
  call MainInit

  ! 地表面データの準備
  ! Prepare surface data
  !
  xy_SurfTemp = 273.0_DP
  xy_SurfAlbedo = 0.3_DP

  ! データ入力
  ! Input data
  !
  call HistoryGet ( &
    & file = 'radiation_band_test01-00.nc', varname = 'Temp', & ! (in)
    & array = xyz_Temp, quiet = .true. )                ! (out)
  call HistoryGet ( &
    & file = 'radiation_band_test01-00.nc', varname = 'QVap', & ! (in)
    & array = xyz_QVap, quiet = .true. )                ! (out)
  call HistoryGet ( &
    & file = 'radiation_band_test01-00.nc', varname = 'PressM', & ! (in)
    & array = xyr_Press, quiet = .true. )                ! (out)

  ! RadiationFlux と RadiationDTempDt テスト
  ! Test of "RadiationFlux" and "RadiationDTempDt"
  !
  do i = 1, 4

    call RadiationFlux( &
      & xyz_Temp, xyz_QVap, xyr_Press, &         ! (in)
      & xy_SurfTemp, xy_SurfAlbedo, &            ! (in)
      & xyr_RadLFlux, xyr_RadSFlux, &            ! (out)
      & xya_SurfRadLMtx, xyra_DelRadLFlux )      ! (out)

    call RadiationDTempDt( &
      & xyr_RadLFlux, xyr_RadSFlux, xyr_Press, & ! (in)
      & xyz_DTempDtRadL, xyz_DTempDtRadS )       ! (out)

    xyz_Temp = &
      & xyz_Temp &
      &  * ( 1.0_DP + DelTime * ( xyz_DTempDtRadL + xyz_DTempDtRadL ) )

    xyz_QVap = xyz_QVap * 5.0_DP

    call TimesetGetCurrentTime( time_value, 'min' )
    time_range = 'time=' // toChar( time_value )

    call HistoryGet( &
      & file = 'radiation_band_test01-01.nc', & ! (in)
      & varname = 'RadLFlux', &                  ! (in)
      & range = time_range, &                    ! (in)
      & array = xyr_RadLFluxAns )                ! (out)
    call AssertEqual( 'RadLFlux test 1-' // toChar( i ), &
      & answer = xyr_RadLFluxAns, check = xyr_RadLFlux, &
      & significant_digits = 13, ignore_digits = -15 )

    call HistoryGet( &
      & file = 'radiation_band_test01-01.nc', & ! (in)
      & varname = 'SurfRadLMtx', &            ! (in)
      & range = time_range, &                    ! (in)
      & array = xya_SurfRadLMtxAns )          ! (out)
    call AssertEqual( 'SurfRadLMtx test 1-' // toChar( i ), &
      & answer = xya_SurfRadLMtxAns, check = xya_SurfRadLMtx, &
      & significant_digits = 13, ignore_digits = -15 )

    call HistoryGet( &
      & file = 'radiation_band_test01-01.nc', & ! (in)
      & varname = 'DelRadLFlux', &               ! (in)
      & range = time_range, &                    ! (in)
      & array = xyra_DelRadLFluxAns )           ! (out)
    call AssertEqual( 'DelRadLFlux test 1-' // toChar( i ), &
      & answer = xyra_DelRadLFluxAns, check = xyra_DelRadLFlux, &
      & significant_digits = 13, ignore_digits = -15 )

    call HistoryGet( &
      & file = 'radiation_band_test01-01.nc', & ! (in)
      & varname = 'RadSFlux', &                  ! (in)
      & range = time_range, &                    ! (in)
      & array = xyr_RadSFluxAns )                ! (out)
    call AssertEqual( 'RadSFlux test 1-' // toChar( i ), &
      & answer = xyr_RadSFluxAns, check = xyr_RadSFlux, &
      & significant_digits = 14, ignore_digits = -15 )

    call HistoryGet( &
      & file = 'radiation_band_test01-01.nc', & ! (in)
      & varname = 'DTempDtRadL', &               ! (in)
      & range = time_range, &                    ! (in)
      & array = xyz_DTempDtRadLAns )             ! (out)
    call AssertEqual( 'DTempDtRadL test 1-' // toChar( i ), &
      & answer = xyz_DTempDtRadLAns, check = xyz_DTempDtRadL, &
      & significant_digits = 14, ignore_digits = -15 )

    call HistoryGet( &
      & file = 'radiation_band_test01-01.nc', & ! (in)
      & varname = 'DTempDtRadS', &               ! (in)
      & range = time_range, &                    ! (in)
      & array = xyz_DTempDtRadSAns )             ! (out)
    call AssertEqual( 'DTempDtRadS test 1-' // toChar( i ), &
      & answer = xyz_DTempDtRadSAns, check = xyz_DTempDtRadS, &
      & significant_digits = 14, ignore_digits = -15 )

    call TimesetProgress
    call HistoryAutoProgress

  end do

  ! データ出力 (内部サブルーチン)
  ! Output data (Internal subroutine)
  !
!!$  call HistoryOutput


contains

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

  subroutine MainInit
    !
    ! 主プログラムの初期化手続き. 
    !
    ! Initialization procedure for the main program. 
    !

    ! コマンドライン引数処理
    ! Command line option parser
    !
    use option_parser, only: OptParseInit

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

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

    ! 出力ファイルの基本情報管理
    ! Management basic information for output files
    ! 
    use fileset, only: FilesetInit

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

    ! 物理定数設定
    ! Physical constants settings
    !
    use constants, only: ConstantsInit

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

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

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

    ! 実行文 ; Executable statement
    !

    ! コマンドライン引数処理
    ! Command line option parser
    !
    call OptParseInit

    ! NAMELIST ファイル名入力
    ! Input NAMELIST file name
    !
    call NmlutilInit

    ! 時刻管理
    ! Time control
    !
    call TimesetInit

    ! 出力ファイルの基本情報管理
    ! Management basic information for output files
    ! 
    call FilesetInit

    ! 格子点設定
    ! Grid points settings
    !
    call GridsetInit

    ! 物理定数設定
    ! Physical constants settings
    !
    call ConstantsInit

    ! 座標データ設定
    ! Axes data settings
    !
    call AxessetInit

    ! ヒストリデータファイルの初期化
    ! Initialization of history data files
    !
    call HistoryFileOpen

    ! 割付
    ! Allocation
    !
    allocate( xy_SurfTemp   (0:imax-1, 1:jmax) )
    allocate( xy_SurfAlbedo (0:imax-1, 1:jmax) )

    allocate( xyz_Temp           (0:imax-1, 1:jmax, 1:kmax) )
    allocate( xyz_QVap           (0:imax-1, 1:jmax, 1:kmax) )
    allocate( xyr_Press          (0:imax-1, 1:jmax, 0:kmax) )

    allocate( xyr_RadLFlux       (0:imax-1, 1:jmax, 0:kmax)      )
    allocate( xya_SurfRadLMtx    (0:imax-1, 1:jmax,        -1:1) )
    allocate( xyra_DelRadLFlux   (0:imax-1, 1:jmax, 0:kmax, 0:1) )
    allocate( xyr_RadSFlux       (0:imax-1, 1:jmax, 0:kmax)      )

    allocate( xyr_RadLFluxAns       (0:imax-1, 1:jmax, 0:kmax)      )
    allocate( xya_SurfRadLMtxAns    (0:imax-1, 1:jmax,        -1:1) )
    allocate( xyra_DelRadLFluxAns   (0:imax-1, 1:jmax, 0:kmax, 0:1) )
    allocate( xyr_RadSFluxAns       (0:imax-1, 1:jmax, 0:kmax)      )

    allocate( xyz_DTempDtRadL (0:imax-1, 1:jmax, 1:kmax) )
    allocate( xyz_DTempDtRadS (0:imax-1, 1:jmax, 1:kmax) )

    allocate( xyz_DTempDtRadLAns (0:imax-1, 1:jmax, 1:kmax) )
    allocate( xyz_DTempDtRadSAns (0:imax-1, 1:jmax, 1:kmax) )

  end subroutine MainInit

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

  subroutine MainTerminate
    !
    ! 主プログラムの終了処理手続き. 
    !
    ! Termination procedure for the main program. 
    !

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

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

    ! 実行文 ; Executable statement
    !

    ! 時刻管理終了処理
    ! Termination of time control
    !
    call TimesetClose

  end subroutine MainTerminate

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

  subroutine HistoryOutput

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

    ! 物理定数設定
    ! 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)

    ! gtool4 データ出力
    ! Gtool4 data output
    !
    use gtool_history, only: GT_HISTORY, &
      & HistoryCreate, HistoryAddVariable, HistoryPut, HistoryClose, &
      & HistoryAddAttr

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

    ! 宣言文 ; Declaration statements
    !
    implicit none

    ! データ入出力
    ! Data I/O
    !
    type(GT_HISTORY):: gthist

    ! 実験の表題, モデルの名称, 所属機関名
    ! Title of a experiment, name of model, sub-organ
    ! 
    character(*), parameter:: title = &
      & 'data of answer for a test prorgram "radiation_band_test01"'
    character(*), parameter:: source = &
      & 'dcpam5 ' // &
      & '(See http://www.gfd-dennou.org/library/dcpam)'
    character(*), parameter:: institution = &
      & 'GFD Dennou Club (See http://www.gfd-dennou.org)'

    ! 実行文 ; Executable statement
    !

    call HistoryCreate( &
      & history = gthist, &                                ! (out)
      & file = 'radiation_band_test01-01.tmp.nc', &        ! (in)
      & title = title, &                                   ! (in)
      & source = source, institution = institution, &      ! (in)
      & dims = StoA('lon', 'lat', 'sig', 'sigm'), &        ! (in)
      & dimsizes = (/imax, jmax, kmax, kmax + 1/), &       ! (in)
      & longnames = &
      &  StoA('longitude', 'latitude', &
      &       'sigma at layer midpoints', &
      &       'sigma at layer end-points (half level)'), & ! (in)
      & units = StoA('degree_east', 'degree_north', &
      &              '1', '1') )                           ! (out)

    call HistoryPut( &
      & history = gthist, &               ! (out)
      & varname = 'lon', array = x_Lon * 180.0_DP / PI )  ! (in)

    call HistoryPut( &
      & history = gthist, &               ! (out)
      & varname = 'lat', array = y_Lat * 180.0_DP / PI  ) ! (in)
    call HistoryPut( &
      & history = gthist, &                ! (out)
      & varname = 'sig', array = z_Sigma ) ! (in)
    call HistoryPut( &
      & history = gthist, &                 ! (out)
      & varname = 'sigm', array = r_Sigma ) ! (in)

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

    call HistoryAddAttr( &
      & history = gthist, &                              ! (inout)
      & varname = 'sig', attrname = 'standard_name', &   ! (in)
      & value = 'atmosphere_sigma_coordinate' )          ! (in)
    call HistoryAddAttr( &
      & history = gthist, &                              ! (inout)
      & varname = 'sigm', attrname = 'standard_name', &  ! (in)
      & value = 'atmosphere_sigma_coordinate' )          ! (in)
    call HistoryAddAttr( &
      & history = gthist, &                         ! (inout)
      & varname = 'sig', attrname = 'positive', &   ! (in)
      & value = 'down' )                            ! (in)
    call HistoryAddAttr( &
      & history = gthist, &                         ! (inout)
      & varname = 'sigm', attrname = 'positive', &  ! (in)
      & value = 'down' )                            ! (in)


    call HistoryAddVariable( &
      & history = gthist, &                  ! (inout)
      & varname = 'Temp', &                  ! (in)
      & dims = StoA('lon', 'lat', 'sig'), &  ! (in)
      & longname = 'temperature', &          ! (in)
      & units = 'K', xtype = 'double' )      ! (in)
    call HistoryPut( &
      & history = gthist, &                  ! (inout)
      & varname = 'Temp', array = xyz_Temp ) ! (in)

    call HistoryAddVariable( &
      & history = gthist, &                  ! (inout)
      & varname = 'QVap', &                  ! (in)
      & dims = StoA('lon', 'lat', 'sig'), &  ! (in)
      & longname = 'specific humidity', &          ! (in)
      & units = 'kg kg-1', xtype = 'double' )      ! (in)
    call HistoryPut( &
      & history = gthist, &                  ! (inout)
      & varname = 'QVap', array = xyz_QVap ) ! (in)

!!$    call HistoryAddVariable( &
!!$      & history = gthist, &                  ! (inout)
!!$      & varname = 'DTempDtCumulus', &            ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig'), &  ! (in)
!!$      & longname = 'cumulus condensation heating', &          ! (in)
!!$      & units = 'K s-1', xtype = 'double' )      ! (in)
!!$    call HistoryPut( &
!!$      & history = gthist, &                  ! (inout)
!!$      & varname = 'DTempDtCumulus', array = xyz_DTempDtCumulus ) ! (in)
!!$
!!$    call HistoryAddVariable( &
!!$      & history = gthist, &                  ! (inout)
!!$      & varname = 'DQVapDtCumulus', &            ! (in)
!!$      & dims = StoA('lon', 'lat', 'sig'), &  ! (in)
!!$      & longname = 'cumulus condensation moistening', &  ! (in)
!!$      & units = 'kg kg-1 s-1', xtype = 'double' )      ! (in)
!!$    call HistoryPut( &
!!$      & history = gthist, &                  ! (inout)
!!$      & varname = 'DQVapDtCumulus', array = xyz_DQVapDtCumulus ) ! (in)
!!$
!!$    call HistoryAddVariable( &
!!$      & history = gthist, &                  ! (inout)
!!$      & varname = 'RainCumulus', &            ! (in)
!!$      & dims = StoA('lon', 'lat'), &  ! (in)
!!$      & longname = 'precipitation by cumulus scheme', &  ! (in)
!!$      & units = 'W m-2', xtype = 'double' )      ! (in)
!!$    call HistoryPut( &
!!$      & history = gthist, &                  ! (inout)
!!$      & varname = 'RainCumulus', array = xy_RainCumulus ) ! (in)

    call HistoryClose( history = gthist ) ! (inout)

  end subroutine HistoryOutput

end program radiation_band_test01
