!= Module StoreDensCloud
!
! Authors::   SUGIYAMA Ko-ichiro
! Version::   $Id: storedenscloud.f90,v 1.1 2011-03-30 13:53:09 sugiyama Exp $ 
! Tag Name::  $Name: arare4-20120911 $
! Copyright:: Copyright (C) GFD Dennou Club, 2006. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
!== Overview 
!
! * 雲密度に関する積算値を保管するための変数型モジュール(主成分凝結計算用). 
! * tendency を x,z,t の関数
! * tendency の算出方法を変更
!   * 短い時間ループ内で和を取り, その平均量を保管するように変更
! * fillnegative で埋めきれずにやむなくゼロに引き戻した量を保存する為の
!   サブルーチンを追加
! * 変化量ではなく, 変化率を出力するよう修正.
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!== Future Plans
!

module StoreDensCloud
  !
  !雲密度に関する積算値を保管するための変数型モジュール.
  !

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

  !暗黙の型宣言禁止
  implicit none

  !属性の指定
  private

  !公開要素
  public StoreDensCloud_Init, StoreDensCloudMean, StoreDensCloudClean
  public xz_DensCloudAdv, xz_DensCloudTurb, xz_DensCloudDiff, &
    &    xz_DensCloudCond, xz_DensCloudFill, xz_DensCloudFillZero
  public xz_DensCloudAdv2, xz_DensCloudTurb2, xz_DensCloudDiff2, &
    &    xz_DensCloudCond2, xz_DensCloudFill2, xz_DensCloudFillZero2
  public StoreDensCloudAdv,  StoreDensCloudTurb, StoreDensCloudDiff, &
    &    StoreDensCloudCond, StoreDensCloudFill, StoreDensCloudFillZero
  public DensCloudAdvTendSum, DensCloudTurbTendSum, DensCloudDiffTendSum, &
    &    DensCloudCondTendSum, DensCloudFillTendSum, DensCloudFillZeroTendSum


  !変数
  real(8), allocatable :: z_DensCloudAdv(:)
  real(8), allocatable :: z_DensCloudTurb(:)
  real(8), allocatable :: z_DensCloudDiff(:)
  real(8), allocatable :: z_DensCloudCond(:)
  real(8), allocatable :: z_DensCloudFill(:)
  real(8), allocatable :: z_DensCloudFillZero(:)
  real(8), allocatable :: xz_DensCloudAdv(:,:)
  real(8), allocatable :: xz_DensCloudTurb(:,:)
  real(8), allocatable :: xz_DensCloudDiff(:,:)
  real(8), allocatable :: xz_DensCloudCond(:,:)
  real(8), allocatable :: xz_DensCloudFill(:,:)
  real(8), allocatable :: xz_DensCloudFillZero(:,:)
  real(8), allocatable :: xz_DensCloudAdv2(:,:)
  real(8), allocatable :: xz_DensCloudTurb2(:,:)
  real(8), allocatable :: xz_DensCloudDiff2(:,:)
  real(8), allocatable :: xz_DensCloudCond2(:,:)
  real(8), allocatable :: xz_DensCloudFill2(:,:)
  real(8), allocatable :: xz_DensCloudFillZero2(:,:)

  !save 属性
  save xz_DensCloudAdv, xz_DensCloudTurb, xz_DensCloudDiff
  save xz_DensCloudCond, xz_DensCloudFill, xz_DensCloudFillZero
  save xz_DensCloudAdv2, xz_DensCloudTurb2, xz_DensCloudDiff2
  save xz_DensCloudCond2, xz_DensCloudFill2, xz_DensCloudFillZero2
  save z_DensCloudAdv, z_DensCloudTurb, z_DensCloudDiff
  save z_DensCloudCond, z_DensCloudFill, z_DensCloudFillZero

contains

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

    allocate(     &
      & z_DensCloudAdv(DimZMin:DimZMax),  & 
      & z_DensCloudTurb(DimZMin:DimZMax), &
      & z_DensCloudDiff(DimZMin:DimZMax), &
      & z_DensCloudCond(DimZMin:DimZMax), &
      & z_DensCloudFill(DimZMin:DimZMax), &
      & z_DensCloudFillZero(DimZMin:DimZMax), &
      & xz_DensCloudAdv(DimXMin:DimXMax, DimZMin:DimZMax),  & 
      & xz_DensCloudTurb(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_DensCloudDiff(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_DensCloudCond(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_DensCloudFill(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_DensCloudFillZero(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_DensCloudAdv2(DimXMin:DimXMax, DimZMin:DimZMax),  & 
      & xz_DensCloudTurb2(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_DensCloudDiff2(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_DensCloudCond2(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_DensCloudFill2(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_DensCloudFillZero2(DimXMin:DimXMax, DimZMin:DimZMax)  &
      &  )

    call StoreDensCloudClean

  end subroutine StoreDensCloud_Init


  subroutine StoreDensCloudClean( )
    !保管した値のクリアー
    
    z_DensCloudAdv  = 0.0d0
    z_DensCloudTurb = 0.0d0
    z_DensCloudDiff = 0.0d0
    z_DensCloudCond = 0.0d0
    z_DensCloudFill = 0.0d0
    z_DensCloudFillZero = 0.0d0

    xz_DensCloudAdv  = 0.0d0
    xz_DensCloudTurb = 0.0d0
    xz_DensCloudDiff = 0.0d0
    xz_DensCloudCond = 0.0d0
    xz_DensCloudFill = 0.0d0
    xz_DensCloudFillZero = 0.0d0

    xz_DensCloudAdv2  = 0.0d0
    xz_DensCloudTurb2 = 0.0d0
    xz_DensCloudDiff2 = 0.0d0
    xz_DensCloudCond2 = 0.0d0
    xz_DensCloudFill2 = 0.0d0
    xz_DensCloudFillZero2 = 0.0d0
   
!    CalNum  = 1.0d-40    !ゼロ割を禁止. 
  end subroutine StoreDensCloudClean


  subroutine StoreDensCloudMean( )

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

    CalNumShort = 2.0d0 * DelTimeLong / DelTimeShort
    
    
    xz_DensCloudAdv  =  xz_DensCloudAdv    / ( CalNumShort * TimeDisp )
    xz_DensCloudTurb =  xz_DensCloudTurb   / ( CalNumShort * TimeDisp )
    xz_DensCloudDiff =  xz_DensCloudDiff   / ( CalNumShort * TimeDisp )
    xz_DensCloudCond =  xz_DensCloudCond   / ( CalNumShort * TimeDisp )
    xz_DensCloudFill =  xz_DensCloudFill   / ( CalNumShort * TimeDisp )
    xz_DensCloudFillZero =  xz_DensCloudFillZero   / ( CalNumShort * TimeDisp )

  end subroutine StoreDensCloudMean


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

    implicit none

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

    Work2  = xz_DensCloudAdv + Work
    xz_DensCloudAdv = Work2

  end subroutine StoreDensCloudAdv


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

    implicit none

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

    Work2   = xz_DensCloudTurb + Work
    xz_DensCloudTurb = Work2

  end subroutine StoreDensCloudTurb


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

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

    Work2   = xz_DensCloudDiff + Work
    xz_DensCloudDiff = Work2

  end subroutine StoreDensCloudDiff

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

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

    Work2   = xz_DensCloudCond + Work
    xz_DensCloudCond = Work2

  end subroutine StoreDensCloudCond

  subroutine StoreDensCloudFill( Work )
    !穴埋めプログラムによる変化

    implicit none

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

    Work2     = Work + xz_DensCloudFill
    xz_DensCloudFill = Work2

  end subroutine StoreDensCloudFill

  subroutine StoreDensCloudFillZero( Work )
    !穴埋めプログラムによる変化

    implicit none

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

    Work2     = Work + xz_DensCloudFillZero
    xz_DensCloudFillZero = Work2

  end subroutine StoreDensCloudFillZero


  subroutine DensCloudAdvTendSum( Work )
    ! 2 \delta t の各時間内で求めた移流項 tendency の足しこみ

    implicit none

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

    Work2  = xz_DensCloudAdv2 + Work
    xz_DensCloudAdv2 = Work2

    xz_DensCloudAdv = 0.0d0

  end subroutine DensCloudAdvTendSum

  subroutine DensCloudTurbTendSum( Work )
    ! 2 \delta t の各時間内で求めた乱流項 tendency の足しこみ

    implicit none

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

    Work2   = xz_DensCloudTurb2 + Work
    xz_DensCloudTurb2 = Work2

    xz_DensCloudTurb = 0.0d0

  end subroutine DensCloudTurbTendSum

  subroutine DensCloudDiffTendSum( Work )
    ! 2 \delta t の各時間内で求めた数値拡散項 tendency の足しこみ.
    ! 短い時間ステップのループ内に行く前に xz_DensCloudxxx  の量を
    ! クリアーしておく.

    implicit none

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

    Work2   = xz_DensCloudDiff2 + Work
    xz_DensCloudDiff2 = Work2

    xz_DensCloudDiff = 0.0d0

  end subroutine DensCloudDiffTendSum

  subroutine DensCloudCondTendSum( Work )
    ! 2 \delta t の各時間内で求めた潜熱加熱項 tendency の足しこみ

    implicit none

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

    Work2   = xz_DensCloudCond2 + Work
    xz_DensCloudCond2 = Work2

    xz_DensCloudCond = 0.0d0

  end subroutine DensCloudCondTendSum

  subroutine DensCloudFillTendSum( Work )
    ! 2 \delta t の各時間内で求めた穴埋め量 tendency の足しこみ

    implicit none

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

    Work2     = Work + xz_DensCloudFill2
    xz_DensCloudFill2 = Work2

    xz_DensCloudFill = 0.0d0

  end subroutine DensCloudFillTendSum

  subroutine DensCloudFillZeroTendSum( Work )
    ! 2 \delta t の各時間内で求めた穴埋め量 tendency の足しこみ

    implicit none

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

    Work2     = Work + xz_DensCloudFillZero2
    xz_DensCloudFillZero2 = Work2

    xz_DensCloudFillZero = 0.0d0

  end subroutine DensCloudFillZeroTendSum


  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
  

end module StoreDensCloud
