!= 積分と平均の操作
!
!= Operation for integral and average
!
! Authors::   Shin-ichi Takehiro, Yoshiyuki O. Takahashi, Yasuhiro MORIKAWA
! Version::   $Id: $ 
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2011. All rights reserved.
! License::   See COPYRIGHT[link:../../../COPYRIGHT]
!

module intavr_operate
  !
  != 積分と平均の操作
  !
  != Operation for integral and average
  !
  ! <b>Note that Japanese and English are described in parallel.</b>
  !
  ! 積分で用いる座標重みを考慮した積分や平均操作のための関数を提供します. 
  ! {SPMODEL ライブラリ}[http://www.gfd-dennou.org/library/spmodel]
  ! の eea_integral_module.f90 を参考に作成しました. 
  !
  ! Functions for integral or average operation with weight for integration
  ! are provided
  ! This program is created referring to 
  ! "eea_integral_module.f90" in 
  ! {SPMODEL library}[http://www.gfd-dennou.org/library/spmodel]
  !
  !== Procedures List
  !
  ! IntXY_xy           :: 水平積分
!!$  ! y_IntLon_xy, IntLon_x  :: 経度積分
!!$  ! ya_IntLon_xya          :: 経度積分 (多層用)
!!$  ! x_IntLat_xy, IntLat_y  :: 緯度積分
!!$  ! xa_IntLat_xya          :: 緯度積分 (多層用)
!!$  ! AvrLonLat_xy           :: 緯度経度平均
!!$  ! y_AvrLon_xy, AvrLon_x  :: 経度平均
!!$  ! ya_AvrLon_xya          :: 経度平均 (多層用)
!!$  ! x_AvrLat_xy, AvrLat_y  :: 緯度平均
!!$  ! xa_AvrLat_xya          :: 緯度平均 (多層用)
  ! ---------------------  :: ---------------------
  ! y_IntX_xy, IntX_x  :: integral in x direction
!!$  ! ya_IntLon_xya          :: Meridional integral (for multi layer)
!!$  ! x_IntLat_xy, IntLat_y  :: Zonal integral
!!$  ! xa_IntLat_xya          :: Zonal integral (for multi layer)
!!$  ! AvrLonLat_xy           :: Zonal and meridional average
!!$  ! y_AvrLon_xy, AvrLon_x  :: Meridional average
!!$  ! ya_AvrLon_xya          :: Meridional average (for multi layer)
!!$  ! x_AvrLat_xy, AvrLat_y  :: Zonal average
!!$  ! xa_AvrLat_xya          :: Zonal average (for multi layer)
  !
  !--
  !== NAMELIST
  !
  ! NAMELIST#intavr_operate_nml
  !++

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

  ! 座標データ設定
  ! Axes data settings
  !
  use axesset, only: &
    & x_X_Weight, &
                              ! $ \Delta x$ [m] . 
                              ! X 座標重み. 
                              ! Weight of x cordinate.
    & y_Y_Weight
                              ! $ \Delta y $ [m] . 
                              ! Y 座標重み. 
                              ! Weight of y coordinate.

  ! 格子点設定
  ! Grid points settings
  !
  use gridset, only: imax, & ! X 格子点数. 
                             ! Number of grid points in x direction
    &                jmax, & ! Y 格子点数. 
                             ! Number of grid points in y direction
    &                kmax    ! 鉛直層数. 
                             ! Number of vertical level

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

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

  ! 宣言文 ; Declaration statements
  !
  implicit none
  private

  ! 公開手続き
  ! Public procedure
  !
  public:: IntXY_xy
!!$  public:: y_IntLon_xy, ya_IntLon_xya, IntLon_x
!!$  public:: x_IntLat_xy, xa_IntLat_xya, IntLat_y
!!$  public:: IntLat_y
!!$  public:: AvrLonLat_xy
!!$  public:: y_AvrLon_xy, ya_AvrLon_xya, AvrLon_x
!!$  public:: x_AvrLat_xy, xa_AvrLat_xya, AvrLat_y

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


  ! 非公開変数
  ! Private variables
  !

  character(*), parameter:: module_name = 'intavr_operate'
                              ! モジュールの名称. 
                              ! Module name
  character(*), parameter:: version = &
    & '$Name:  $' // &
    & '$Id:  $'
                              ! モジュールのバージョン
                              ! Module version

  ! INTERFACE 文 ; INTERFACE statements
  !

contains

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

  function IntXY_xy( xy_Data )
    !
    ! 2 次元水平格子点データの全領域積分(1 層用). 
    !
    ! 実際には格子点データ各点毎に x_X_Weight, y_Y_Weight を掛けた
    ! 総和を計算している. 
    !
    ! Global integration of 2-dimensional (horizontal)
    ! grid data.
    !
    ! Practically, the sum total of grid data is calculated
    ! by multiplying in each grid "x_X_Weight" and "y_YWeight".
    !

    real(DP), intent(in) :: xy_Data (0:imax-1, 1:jmax)
    real(DP)             :: IntXY_xy

    ! 実行文 ; Executable statement
    !

    ! Old one to be deleted
!!$    IntLonLat_xy = IntLon_x( x_IntLat_xy( xy_Data ) )

    IntXY_xy = IntY_y( y_IntX_xy( xy_Data ) )

  end function IntXY_xy

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

  function y_IntX_xy( xy_Data )
    !
    ! 2 次元水平格子点データの X 方向積分(1 層用). 
    !
    ! 実際には格子点データ各点毎に x_X_Weight を掛けた
    ! 総和を計算している. 
    !
    ! x integration of 2-dimensional (horizontal)
    ! grid data.
    !
    ! Practically, the sum total of grid data is calculated
    ! by multiplying in each grid "x_X_Weight".
    !

    real(DP), intent(in) :: xy_Data (0:imax-1, 1:jmax)
    real(DP)             :: y_IntX_xy (1:jmax)

    ! 作業変数
    ! Work variables
    !
    integer:: i               ! X 方向に回る DO ループ用作業変数
                              ! Work variables for DO loop in longitudinal direction
    integer:: j               ! Y 方向に回る DO ループ用作業変数
                              ! Work variables for DO loop in latitudinal direction

    ! 実行文 ; Executable statement
    !

    y_IntX_xy = 0.0_DP
    do j = 1, jmax
      do i = 0, imax - 1
        y_IntX_xy(j) = y_IntX_xy(j) + xy_Data (i,j) * x_X_Weight(i)
      end do
    end do

  end function y_IntX_xy

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

  function IntY_y( y_Data )
    !
    ! 1 次元 Y 格子点データの Y 方向積分(1 層用). 
    !
    ! 実際には格子点データ各点毎に y_Y_Weight を掛けた
    ! 総和を計算している. 
    !
    ! Meridonal integration of 1-dimensional (y)
    ! grid data.
    !
    ! Practically, the sum total of grid data is calculated
    ! by multiplying in each grid "y_Y_Weight".
    !
    real(DP), intent(in) :: y_Data (1:jmax)
    real(DP)             :: IntY_y

    ! 作業変数
    ! Work variables
    !

    ! 実行文 ; Executable statement
    !
    IntY_y = sum( y_Data * y_Y_Weight )

  end function IntY_y


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

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

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

    ! 宣言文 ; Declaration statements
    !

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

    ! NAMELIST 変数群
    ! NAMELIST group name
    !
!!$    namelist /intavr_operate_nml/
          !
          ! デフォルト値については初期化手続 "intavr_operate#IntAvrOprInit" 
          ! のソースコードを参照のこと. 
          !
          ! Refer to source codes in the initialization procedure
          ! "intavr_operate#IntAvrOprInit" for the default values. 
          !

    ! 実行文 ; Executable statement
    !

    if ( intavr_operate_inited ) return


    ! デフォルト値の設定
    ! Default values settings
    !

!!$    ! 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 = intavr_operate_nml, &  ! (out)
!!$        & iostat = iostat_nml )   ! (out)
!!$      close( unit_nml )
!!$
!!$      call NmlutilMsg( iostat_nml, module_name ) ! (in)
!!$    end if

    ! 印字 ; Print
    !
    call MessageNotify( 'M', module_name, '----- Initialization Messages -----' )
    call MessageNotify( 'M', module_name, '-- version = %c', c1 = trim(version) )
    intavr_operate_inited = .true.
  end subroutine IntAvrOprInit

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

end module intavr_operate
