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

program intavr_operate_test01

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

  ! 積分と平均の操作
  ! Operation for integral and average
  !
  use intavr_operate, only: &
    & IntLonLat_xy, &
    & y_IntLon_xy, ya_IntLon_xya, IntLon_x, &
    & x_IntLat_xy, xa_IntLat_xya, IntLat_y, &
    & AvrLonLat_xy, &
    & y_AvrLon_xy, ya_AvrLon_xya, AvrLon_x, &
    & x_AvrLat_xy, xa_AvrLat_xya, AvrLat_y

  ! 格子点設定
  ! 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:: xy_Temp (:,:)
                              ! $ T $ .     温度. Temperature
  real(DP), allocatable:: xyz_Temp (:,:,:)
                              ! $ T $ .     温度. Temperature
  real(DP), allocatable:: xz_TempIntLat (:,:)
                              ! $ T $ .     温度の緯度積分. 
                              ! Temperature integration in latitude
  real(DP), allocatable:: yz_TempAvrLon (:,:)
                              ! $ T $ .     温度の経度平均. 
                              ! Meridional mean temperature

  real(DP), allocatable:: x_TempIntLatAns (:)
                              ! $ T $ .     温度の緯度積分. 
                              ! Temperature integration in latitude
  real(DP), allocatable:: y_TempAvrLonAns (:)
                              ! $ T $ .     温度の経度平均. 
                              ! Meridional mean temperature

  real(DP):: TempAvrLonLatAns
                              ! $ T $ .     温度の全領域平均. 
                              ! Global mean temperature

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

  ! 実行文 ; Executable statement
  !

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

  ! サンプルデータの入力
  ! Input sample data
  !
  call HistoryGet( &
    & file = 'intavr_operate_test01-00.nc', & ! (in)
    & varname = 'SurfTemp', &              ! (in)
    & array = xy_Temp )                    ! (out)

  do k = 1, kmax
    call HistoryGet( &
      & file = 'intavr_operate_test01-00.nc', & ! (in)
      & varname = 'SurfTemp', &              ! (in)
      & array = xyz_Temp(:,:,k) )            ! (out)
  end do

  ! 積分テスト
  ! Integration test
  !
  call HistoryGet( &
    & file = 'intavr_operate_test01-01.nc', & ! (in)
    & varname = 'IntLatTemp1', &           ! (in)
    & array = x_TempIntLatAns )            ! (out)

  call AssertEqual( 'integration test 1-2', &
    & answer = x_TempIntLatAns, &
    & check = x_IntLat_xy( xy_Temp ), &
    & significant_digits = 14, ignore_digits = -14 )

  xz_TempIntLat = xa_IntLat_xya( xyz_Temp )
  do k = 1, kmax
    call AssertEqual( 'integration test 2-' // trim(toChar(k)), &
      & answer = x_TempIntLatAns, &
      & check = xz_TempIntLat(:,k), &
      & significant_digits = 14, ignore_digits = -14 )
  end do

  ! 平均テスト 1
  ! Average test 1
  !
  call HistoryGet( &
    & file = 'intavr_operate_test01-01.nc', & ! (in)
    & varname = 'AvrLonTemp0', &           ! (in)
    & array = y_TempAvrLonAns )            ! (out)

  call AssertEqual( 'average test 1-1', &
    & answer = y_TempAvrLonAns, &
    & check = y_AvrLon_xy( xy_Temp ), &
    & significant_digits = 14, ignore_digits = -14 )

  call HistoryGet( &
    & file = 'intavr_operate_test01-01.nc', & ! (in)
    & varname = 'AvrLonTemp1', &           ! (in)
    & array = y_TempAvrLonAns )            ! (out)

  call AssertEqual( 'average test 1-2', &
    & answer = y_TempAvrLonAns, &
    & check = y_AvrLon_xy( xy_Temp ), &
    & significant_digits = 14, ignore_digits = -14 )

  yz_TempAvrLon = ya_AvrLon_xya( xyz_Temp )
  do k = 1, kmax
    call AssertEqual( 'average test 2-' // trim(toChar(k)), &
      & answer = y_TempAvrLonAns, &
      & check = yz_TempAvrLon(:,k), &
      & significant_digits = 14, ignore_digits = -14 )
  end do

  ! 平均テスト 2
  ! Average test 2
  !
  call HistoryGet( &
    & file = 'intavr_operate_test01-01.nc', & ! (in)
    & varname = 'AvrLonLatTemp1', &        ! (in)
    & array = TempAvrLonLatAns )           ! (out)

  call AssertEqual( 'average test 2-2', &
    & answer = TempAvrLonLatAns, &
    & check = AvrLonLat_xy( xy_Temp ), &
    & significant_digits = 14, ignore_digits = -14 )


  ! データ出力 (内部サブルーチン)
  ! 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_Temp         (0:imax-1, 1:jmax)         )
    allocate( xyz_Temp        (0:imax-1, 1:jmax, 1:kmax) )
    allocate( xz_TempIntLat   (0:imax-1,         1:kmax) )
    allocate( yz_TempAvrLon   (          1:jmax, 1:kmax) )
    allocate( x_TempIntLatAns (0:imax-1)                 )
    allocate( y_TempAvrLonAns (          1:jmax)         )

  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 "intavr_operate_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 = 'intavr_operate_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 intavr_operate_test01
