!= Module StoreKm
!
! Authors::   SUGIYAMA Ko-ichiro
! Version::   $Id: storepottemp.f90,v 1.5 2011-02-28 12:00:25 sugiyama Exp $ 
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2006. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
!== Overview 
!
!温位に関する積算値を保管するための変数型モジュール
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!== Future Plans
!

module StoreKm
  !
  !温位に関する積算値を保管するための変数型モジュール.
  !

  !モジュールの読み込み
  use gridset, only:   DimXMin,     & ! x 方向の配列の下限
    &                  DimXMax,     & ! x 方向の配列の上限
    &                  DimZMin,     & ! z 方向の配列の下限
    &                  DimZMax,     & ! z 方向の配列の上限
    &                  SpcNum,      & ! number of species
    &                  RegXMin,     & ! x 方向の物理領域の下限
    &                  RegXMax        ! x 方向の物理領域の上限
  use TimeSet, only:   TimeDisp,    & ! 出力時間間隔
    &                  DelTimeLong    ! 長い時間ステップ

  !暗黙の型宣言禁止
  implicit none

  !属性の指定
  private

  !公開要素
  public StoreKm_Init, StoreKmMeanX, StoreKmClean
  public z_KmAdv,  z_KmTurb, z_KmDisp, z_KmDiff, z_KmShear, z_KmBuoyT, z_KmBuoyM
  public xz_KmAdv,  xz_KmTurb, xz_KmDisp, xz_KmDiff, xz_KmShear, xz_KmBuoyT, xz_KmBuoyM
  public StoreKmAdv,  StoreKmTurb, StoreKmDisp, StoreKmDiff, StoreKmShear, StoreKmBuoyT, StoreKmBuoyM

  !変数
  real(8), allocatable :: z_KmAdv(:)
  real(8), allocatable :: z_KmTurb(:)
  real(8), allocatable :: z_KmDisp(:)
  real(8), allocatable :: z_KmDiff(:)
  real(8), allocatable :: z_KmShear(:)
  real(8), allocatable :: z_KmBuoyT(:)
  real(8), allocatable :: z_KmBuoyM(:)
  real(8), allocatable :: xz_KmAdv(:,:)
  real(8), allocatable :: xz_KmTurb(:,:)
  real(8), allocatable :: xz_KmDisp(:,:)
  real(8), allocatable :: xz_KmDiff(:,:)
  real(8), allocatable :: xz_KmShear(:,:)
  real(8), allocatable :: xz_KmBuoyT(:,:)
  real(8), allocatable :: xz_KmBuoyM(:,:)

  !save 属性
  save xz_KmAdv,  xz_KmTurb, xz_KmDisp, xz_KmDiff, xz_KmShear, &
    &  xz_KmBuoyT, xz_KmBuoyM
  save z_KmAdv,  z_KmTurb, z_KmDisp, z_KmDiff, z_KmShear, &
    &  z_KmBuoyT, z_KmBuoyM

contains

  subroutine StoreKm_Init( )
    !初期化ルーチン

    allocate(     &
      & z_KmAdv(DimZMin:DimZMax),  & 
      & z_KmTurb(DimZMin:DimZMax), &
      & z_KmDisp(DimZMin:DimZMax), &
      & z_KmDiff(DimZMin:DimZMax), &
      & z_KmShear(DimZMin:DimZMax),  &
      & z_KmBuoyT(DimZMin:DimZMax), &
      & z_KmBuoyM(DimZMin:DimZMax), &
      & xz_KmAdv(DimXMin:DimXMax, DimZMin:DimZMax),  & 
      & xz_KmTurb(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_KmDisp(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_KmDiff(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_KmShear(DimXMin:DimXMax, DimZMin:DimZMax),  &
      & xz_KmBuoyT(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_KmBuoyM(DimXMin:DimXMax, DimZMin:DimZMax)  &
      &  )

    call StoreKmClean

  end subroutine StoreKm_Init


  subroutine StoreKmClean( )
    !保管した値のクリアー
    
    z_KmAdv  = 0.0d0
    z_KmTurb = 0.0d0
    z_KmDiff = 0.0d0
    z_KmDisp = 0.0d0
    z_KmShear  = 0.0d0
    z_KmBuoyT = 0.0d0
    z_KmBuoyM = 0.0d0

    xz_KmAdv  = 0.0d0
    xz_KmTurb = 0.0d0
    xz_KmDiff = 0.0d0
    xz_KmDisp = 0.0d0
    xz_KmShear  = 0.0d0
    xz_KmBuoyT = 0.0d0
    xz_KmBuoyM = 0.0d0
   
!    CalNum  = 1.0d-40    !ゼロ割を禁止. 
  end subroutine StoreKmClean


  subroutine StoreKmMeanX( )
    !保管した値の水平平均値 [K/s]
    real(8) :: CalNum

    CalNum = TimeDisp / DelTimeLong 
    
    z_KmAdv  = a_MeanX_aa( xz_KmAdv )   / CalNum
    z_KmTurb = a_MeanX_aa( xz_KmTurb )  / CalNum
    z_KmDiff = a_MeanX_aa( xz_KmDiff )  / CalNum
    z_KmDisp = a_MeanX_aa( xz_KmDisp )  / CalNum
    z_KmShear  = a_MeanX_aa( xz_KmShear )  / CalNum
    z_KmBuoyT = a_MeanX_aa( xz_KmBuoyT )  / CalNum
    z_KmBuoyM = a_MeanX_aa( xz_KmBuoyM )  / CalNum

!    xz_KmAdv  = xz_KmAdv / CalNum
!    xz_KmTurb = xz_KmTurb / CalNum
!    xz_KmDiff = xz_KmDiff / CalNum
!    xz_KmDisp = xz_KmDisp / CalNum
!    xz_KmShear = xz_KmShear / CalNum
!    xz_KmBuoyT = xz_KmBuoyT / CalNum
!    xz_KmBuoyM = xz_KmBuoyM / CalNum

  end subroutine StoreKmMeanX


  subroutine StoreKmAdv( Work )
    !移流項の保管

    implicit none

    real(8), intent(in)  :: Work(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)              :: Work2(DimXMin:DimXMax, DimZMin:DimZMax)

!    Work2  = xz_KmAdv + Work
!    xz_KmAdv = Work2
    xz_KmAdv = Work


  end subroutine StoreKmAdv


  subroutine StoreKmTurb( Work )
    !乱流項の保管

    implicit none

    real(8), intent(in)  :: Work(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)              :: Work2(DimXMin:DimXMax, DimZMin:DimZMax)

!    Work2   = xz_KmTurb + Work
!    xz_KmTurb = Work2
    xz_KmTurb = Work

  end subroutine StoreKmTurb


  subroutine StoreKmDiff( Work )
    !数値拡散項の保管

    implicit none
    
    real(8), intent(in)  :: Work(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)              :: Work2(DimXMin:DimXMax, DimZMin:DimZMax)

!    Work2   = xz_KmDiff + Work
!    xz_KmDiff = Work2
    xz_KmDiff = Work

  end subroutine StoreKmDiff


  subroutine StoreKmDisp( Work )
    !散逸加熱項の保管

    implicit none
    
    real(8), intent(in)  :: Work(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)              :: Work2(DimXMin:DimXMax, DimZMin:DimZMax)

!    Work2   = xz_KmDisp + Work
!    xz_KmDisp = Work2
    xz_KmDisp = Work

  end subroutine StoreKmDisp


  subroutine StoreKmShear( Work )
    !シアー項の保管

    implicit none
    
    real(8), intent(in)  :: Work(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)              :: Work2(DimXMin:DimXMax, DimZMin:DimZMax)

!    Work2  = xz_KmShear + Work
!    xz_KmShear = Work2
    xz_KmShear = Work

  end subroutine StoreKmShear


  subroutine StoreKmBuoyT( Work )
    !潜熱・蒸発熱の保管

    implicit none
    
    real(8), intent(in)  :: Work(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)              :: Work2(DimXMin:DimXMax, DimZMin:DimZMax)

!    Work2   = xz_KmBuoyT + Work
!    xz_KmBuoyT = Work2
    xz_KmBuoyT = Work

  end subroutine StoreKmBuoyT


  subroutine StoreKmBuoyM( Work )
    !地表面フラックスの保管

    implicit none
    
    real(8), intent(in)  :: Work(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)              :: Work2(DimXMin:DimXMax, DimZMin:DimZMax)

!    Work2   = xz_KmBuoyM + Work
!    xz_KmBuoyM = Work2
    xz_KmBuoyM = Work

  end subroutine StoreKmBuoyM


  function a_MeanX_aa( var ) 
    !
    ! 水平平均値の計算
    !
    
    !暗黙の型宣言禁止
    implicit none
    
    !変数定義
    real(8), intent(in)  :: var(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !平均演算の対象となる変数
    real(8)              :: a_MeanX_aa(DimZMin:DimZMax)
                                     !水平平均値

    a_MeanX_aa = sum( var(RegXMin+1:RegXMax, :), 1 ) &
      &           / real(RegXMax - RegXMin, 8) 

  end function a_MeanX_aa


  function aa_MeanX_aaa( var ) 
    !
    ! 水平平均値の計算
    !
    
    !暗黙の型宣言禁止
    implicit none
    
    !変数定義
    real(8), intent(in)  :: var(DimXMin:DimXMax, DimZMin:DimZMax, 1:SpcNum)
                                     !平均演算の対象となる変数
    real(8)              :: aa_MeanX_aaa(DimZMin:DimZMax, 1:SpcNum)
                                     !水平平均値

    aa_MeanX_aaa = sum( var(RegXMin+1:RegXMax, :, :), 1 ) &
      &           / real(RegXMax - RegXMin, 8) 

  end function aa_MeanX_aaa
  

end module StoreKm
