!= Module StoreMom
!
! Authors::   SUGIYAMA Ko-ichiro
! Version::   $Id: storemom.f90,v 1.1 2011-02-28 12:19:41 sugiyama Exp $ 
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2006. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
!== Overview 
!
!運動量に関する積算値を保管するための変数型モジュール
!(2010年12月追加)
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!== Future Plans
!

module StoreMom
  !
  !運動量に関する積算値を保管するための変数型モジュール.
  !

  !モジュールの読み込み
  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 StoreMom_Init, StoreMomMeanX, StoreMomClean
  public z_MomAdv,  z_MomTurb, z_MomDiff, z_MomFlux
  public pz_MomAdv,  pz_MomTurb, pz_MomDiff, pz_MomFlux
  public StoreMomAdv, StoreMomTurb, StoreMomDiff, StoreMomFlux

  !変数
  real(8), allocatable :: z_MomAdv(:)
  real(8), allocatable :: z_MomTurb(:)
  real(8), allocatable :: z_MomDiff(:)
  real(8), allocatable :: z_MomFlux(:)
  real(8), allocatable :: pz_MomAdv(:,:)
  real(8), allocatable :: pz_MomTurb(:,:)
  real(8), allocatable :: pz_MomDiff(:,:)
  real(8), allocatable :: pz_MomFlux(:,:)

  !save 属性
  save pz_MomAdv, pz_MomTurb, pz_MomDiff, pz_MomFlux
  save z_MomAdv, z_MomTurb, z_MomDiff, z_MomFlux

contains

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

    allocate(     &
      & z_MomAdv(DimZMin:DimZMax),  & 
      & z_MomTurb(DimZMin:DimZMax), &
      & z_MomDiff(DimZMin:DimZMax), &
      & z_MomFlux(DimZMin:DimZMax), &
      & pz_MomAdv(DimXMin:DimXMax, DimZMin:DimZMax),  & 
      & pz_MomTurb(DimXMin:DimXMax, DimZMin:DimZMax), &
      & pz_MomDiff(DimXMin:DimXMax, DimZMin:DimZMax), &
      & pz_MomFlux(DimXMin:DimXMax, DimZMin:DimZMax)  &
      &  )

    call StoreMomClean

  end subroutine StoreMom_Init


  subroutine StoreMomClean( )
    !保管した値のクリアー
    
    z_MomAdv  = 0.0d0
    z_MomTurb = 0.0d0
    z_MomDiff = 0.0d0
    z_MomFlux = 0.0d0

    pz_MomAdv  = 0.0d0
    pz_MomTurb = 0.0d0
    pz_MomDiff = 0.0d0
    pz_MomFlux = 0.0d0
   
!    CalNum  = 1.0d-40    !ゼロ割を禁止. 
  end subroutine StoreMomClean


  subroutine StoreMomMeanX( )
    !保管した値の水平平均値 [kg.m/s^2]
    real(8) :: CalNum

    CalNum = TimeDisp / DelTimeLong 
    
    z_MomAdv  = a_MeanX_aa( pz_MomAdv )   / CalNum
    z_MomTurb = a_MeanX_aa( pz_MomTurb )  / CalNum
    z_MomDiff = a_MeanX_aa( pz_MomDiff )  / CalNum
    z_MomFlux = a_MeanX_aa( pz_MomFlux )  / CalNum

  end subroutine StoreMomMeanX

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

    implicit none

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

    Work2  = pz_MomAdv + Work
    pz_MomAdv = Work2

  end subroutine StoreMomAdv


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

    implicit none

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

    Work2   = pz_MomTurb + Work
    pz_MomTurb = Work2

  end subroutine StoreMomTurb


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

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

    Work2   = pz_MomDiff + Work
    pz_MomDiff = Work2

  end subroutine StoreMomDiff

  subroutine StoreMomFlux( Work )
    !運動量フラックスの保管

    implicit none

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

    Work2  = pz_MomFlux + Work
    pz_MomFlux = Work2

  end subroutine StoreMomFlux

  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 StoreMom
