!= negative_moist モジュールのテストプログラム
!
!= Test program for "negative_moist"
!
! Authors::   Yasuhiro MORIKAWA
! Version::   $Id: negative_moist_test01.f90,v 1.2 2008-09-23 18:00:33 morikawa Exp $
! Tag Name::  $Name: dcpam5-20090306 $
! 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>
!
! negative_moist モジュールの動作テストを行うためのプログラムです. 
! このプログラムがコンパイルできること, および実行時に 
! プログラムが正常終了することを確認してください. 
!
! This program checks the operation of "negative_moist" module. 
! Confirm compilation and execution of this program. 
!

program negative_moist_test01

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

  ! 負の水蒸気除去
  ! Remove negative moisture
  !
  use negative_moist, only: RemoveNegMoist

  ! 積分と平均の操作
  ! Operation for integral and average
  !
  use intavr_operate, only: AvrLonLat_xy

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

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

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

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

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

  ! 宣言文 ; Declaration statements
  !
  implicit none

  ! 物理量
  ! Physical values
  !
  real(DP), allocatable:: xyz_QVap (:,:,:)
                              ! $ q $ .     比湿. Specific humidity

  real(DP), allocatable:: xyz_QVapAns (:,:,:)
                              ! $ q $ .     比湿. Specific humidity

  real(DP), allocatable:: xyz_DNegQVapDt (:,:,:)
                              ! 比湿変化率. 
                              ! Specific humidity tendency
  real(DP), allocatable:: xyz_DNegQVapDtAns (:,:,:)
                              ! 比湿変化率. 
                              ! Specific humidity tendency
  real(DP), allocatable:: xyr_Press (:,:,:)
                              ! $ p_s $ . 地表面気圧 (半整数レベル). 
                              ! Surface pressure (half level)

  real(DP):: QVapAvrLonLatSig
                              ! 比湿の全球平均. 
                              ! Global mean specific humidity
  real(DP):: QVapAvrLonLatSigAns
                              ! 比湿の全球平均. 
                              ! Global mean specific humidity

  ! 作業変数
  ! Work variables
  !
  integer:: k                 ! 鉛直方向に回る DO ループ用作業変数
                              ! Work variables for DO loop in vertical direction

  ! 実行文 ; Executable statement
  !

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

  ! 正答の取得
  ! Get correct answer
  !
  call HistoryGet( &
    & file = 'negative_moist_test01-01.nc', & ! (in)
    & varname = 'QVap', &                 ! (in)
    & array = xyz_QVapAns )               ! (out)
  call HistoryGet( &
    & file = 'negative_moist_test01-01.nc', & ! (in)
    & varname = 'DNegQVapDt', &           ! (in)
    & array = xyz_DNegQVapDtAns )         ! (out)

  ! 気圧と比湿の取得
  ! Get pressure and specific humidity
  !
  call HistoryGet( &
    & file = 'negative_moist_test01-00.nc', & ! (in)
    & varname = 'PressM', &               ! (in)
    & array = xyr_Press )                 ! (out)

  call HistoryGet( &
    & file = 'negative_moist_test01-00.nc', & ! (in)
    & varname = 'QVap', &                 ! (in)
    & array = xyz_QVap )                  ! (out)

  ! 負の水蒸気除去
  ! Remove negative moisture
  !
  xyz_DNegQVapDt = 0.0_DP
  call RemoveNegMoist( &
    & xyz_QVap = xyz_QVap, &             ! (inout)
    & xyz_DNegQVapDt = xyz_DNegQVapDt, & ! (inout)
    & xyr_Press = xyr_Press )            ! (in)

  call AssertEqual( 'RemoveNegMoist test 1', &
    & answer = xyz_QVapAns, check = xyz_QVap, &
    & significant_digits = 15, ignore_digits = -15 )

  call AssertEqual( 'RemoveNegMoist test 2', &
    & answer = xyz_DNegQVapDtAns, check = xyz_DNegQVapDt, &
    & significant_digits = 15, ignore_digits = -15 )

  ! データ出力 (内部サブルーチン)
  ! 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( xyz_QVap          (0:imax-1, 1:jmax, 1:kmax) )
    allocate( xyz_QVapAns       (0:imax-1, 1:jmax, 1:kmax) )
    allocate( xyz_DNegQVapDt    (0:imax-1, 1:jmax, 1:kmax) )
    allocate( xyz_DNegQVapDtAns (0:imax-1, 1:jmax, 1:kmax) )
    allocate( xyr_Press         (0:imax-1, 1:jmax, 0: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 "negative_moist_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 = 'negative_moist_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 HistoryClose( history = gthist ) ! (inout)

  end subroutine HistoryOutput

end program negative_moist_test01
