!= Module StorePotTemp
!
! 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 StorePotTemp
  !
  !温位に関する積算値を保管するための変数型モジュール.
  !

  !モジュールの読み込み
  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 StorePotTemp_Init, StorePotTempMeanX, StorePotTempClean
  public z_Adv,  z_Turb, z_Disp, z_Diff, z_Rad, &
    &    z_Cond, z_Flux, z_Damp, za_Cond2, z_Cond3, xz_Flux, xz_Rad
  public StorePotTempAdv,  StorePotTempTurb, StorePotTempDisp, StorePotTempDiff, StorePotTempRad, &
    &    StorePotTempCond, StorePotTempFlux, StorePotTempDamp, StorePotTempCond2, StorePotTempCond3

  !変数
  real(8), allocatable :: z_Adv(:)
  real(8), allocatable :: z_Turb(:)
  real(8), allocatable :: z_Disp(:)
  real(8), allocatable :: z_Diff(:)
  real(8), allocatable :: z_Rad(:)
  real(8), allocatable :: z_Damp(:)
  real(8), allocatable :: z_Cond(:)
  real(8), allocatable :: za_Cond2(:,:)
  real(8), allocatable :: z_Cond3(:)
  real(8), allocatable :: z_Flux(:)
  real(8), allocatable :: xz_Adv(:,:)
  real(8), allocatable :: xz_Turb(:,:)
  real(8), allocatable :: xz_Disp(:,:)
  real(8), allocatable :: xz_Diff(:,:)
  real(8), allocatable :: xz_Rad(:,:)
  real(8), allocatable :: xz_Damp(:,:)
  real(8), allocatable :: xz_Cond(:,:)
  real(8), allocatable :: xza_Cond2(:,:,:)
  real(8), allocatable :: xz_Cond3(:,:)
  real(8), allocatable :: xz_Flux(:,:)

  !save 属性
  save xz_Adv,  xz_Turb, xz_Disp, xz_Diff, xz_Rad, &
    &  xz_Cond, xza_Cond2, xz_Cond3, xz_Flux, xz_Damp
  save z_Adv,  z_Turb, z_Disp, z_Diff, z_Rad, &
    &  z_Cond, za_Cond2, z_Cond3, z_Flux, z_Damp

contains

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

    allocate(     &
      & z_Adv(DimZMin:DimZMax),  & 
      & z_Turb(DimZMin:DimZMax), &
      & z_Disp(DimZMin:DimZMax), &
      & z_Diff(DimZMin:DimZMax), &
      & z_Rad(DimZMin:DimZMax),  &
      & z_Damp(DimZMin:DimZMax), &
      & z_Cond(DimZMin:DimZMax), &
      & za_Cond2(DimZMin:DimZMax, 1:SpcNum), &
      & z_Cond3(DimZMin:DimZMax), &
      & z_Flux(DimZMin:DimZMax), &
      & xz_Adv(DimXMin:DimXMax, DimZMin:DimZMax),  & 
      & xz_Turb(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_Disp(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_Diff(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_Rad(DimXMin:DimXMax, DimZMin:DimZMax),  &
      & xz_Damp(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_Cond(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xza_Cond2(DimXMin:DimXMax, DimZMin:DimZMax, 1:SpcNum), &
      & xz_Cond3(DimXMin:DimXMax, DimZMin:DimZMax), &
      & xz_Flux(DimXMin:DimXMax, DimZMin:DimZMax)  &
      &  )

    call StorePotTempClean

  end subroutine StorePotTemp_Init


  subroutine StorePotTempClean( )
    !保管した値のクリアー
    
    z_Adv  = 0.0d0
    z_Turb = 0.0d0
    z_Diff = 0.0d0
    z_Disp = 0.0d0
    z_Rad  = 0.0d0
    z_Damp = 0.0d0
    z_Cond = 0.0d0
    za_Cond2 = 0.0d0
    z_Cond3 = 0.0d0
    z_Flux = 0.0d0

    xz_Adv  = 0.0d0
    xz_Turb = 0.0d0
    xz_Diff = 0.0d0
    xz_Disp = 0.0d0
    xz_Rad  = 0.0d0
    xz_Damp = 0.0d0
    xz_Cond = 0.0d0
    xza_Cond2 = 0.0d0
    xz_Cond3 = 0.0d0
    xz_Flux = 0.0d0
   
!    CalNum  = 1.0d-40    !ゼロ割を禁止. 
  end subroutine StorePotTempClean


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

    CalNum = TimeDisp / DelTimeLong 
    
    z_Adv  = a_MeanX_aa( xz_Adv )   / CalNum
    z_Turb = a_MeanX_aa( xz_Turb )  / CalNum
    z_Diff = a_MeanX_aa( xz_Diff )  / CalNum
    z_Disp = a_MeanX_aa( xz_Disp )  / CalNum
    z_Rad  = a_MeanX_aa( xz_Rad )  / CalNum
    z_Damp = a_MeanX_aa( xz_Damp )  / CalNum
    z_Cond = a_MeanX_aa( xz_Cond )  / CalNum
    za_Cond2 = aa_MeanX_aaa( xza_Cond2 )  / CalNum
    z_Cond3 = a_MeanX_aa( xz_Cond3 )  / CalNum
    z_Flux = a_MeanX_aa( xz_Flux )  / CalNum

  end subroutine StorePotTempMeanX


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

    implicit none

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

    Work2  = xz_Adv + Work
    xz_Adv = Work2

  end subroutine StorePotTempAdv


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

    implicit none

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

    Work2   = xz_Turb + Work
    xz_Turb = Work2

  end subroutine StorePotTempTurb


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

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

    Work2   = xz_Diff + Work
    xz_Diff = Work2

  end subroutine StorePotTempDiff


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

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

    Work2   = xz_Disp + Work
    xz_Disp = Work2

  end subroutine StorePotTempDisp


  subroutine StorePotTempRad( Work )
    !放射冷却項の保管

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

    Work2  = xz_Rad + Work
    xz_Rad = Work2

  end subroutine StorePotTempRad


  subroutine StorePotTempDamp( Work )
    !ダンピング項の保管

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

    Work2   = xz_Damp + Work
    xz_Damp = Work2

  end subroutine StorePotTempDamp


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

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

    Work2   = xz_Cond + Work
    xz_Cond = Work2

  end subroutine StorePotTempCond

  subroutine StorePotTempCond2( Work, ID )
    !潜熱・蒸発熱の保管

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

    Work2(:,:,ID)    = xza_Cond2(:,:,ID) +  Work 
    xza_Cond2(:,:,ID) = Work2(:,:,ID)

  end subroutine StorePotTempCond2

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

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

    Work2   = xz_Cond3 + Work 
    xz_Cond3 = Work2

  end subroutine StorePotTempCond3


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

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

    Work2   = xz_Flux + Work
    xz_Flux = Work2

  end subroutine StorePotTempFlux


  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 StorePotTemp
