!= Module StoreBuoy_3d
!
! Authors::   SUGIYAMA Ko-ichiro, ODAKA Masatsugu
! Version::   $Id: storebuoy_3d.f90,v 1.1 2008-06-19 16:47:53 odakker Exp $ 
! Tag Name::  $Name: arare4-20080627 $
! Copyright:: Copyright (C) GFD Dennou Club, 2006. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
!== Overview 
!
!浮力に関する積算値を保管するための変数型モジュール
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!== Future Plans
!

module StoreBuoy_3d
  !
  !浮力の積算値を保管するための変数型モジュール.
  !

  !モジュールの読み込み
  use dc_types, only : DP

  use gridset_3d, only : DimXMin,     & ! x 方向の配列の下限
    &                  DimXMax,     & ! x 方向の配列の上限
    &                  DimYMin,     & ! y 方向の配列の下限
    &                  DimYMax,     & ! y 方向の配列の上限
    &                  DimZMin,     & ! z 方向の配列の下限
    &                  DimZMax,     & ! z 方向の配列の上限
    &                  RegXMin,     & ! x 方向の物理領域の下限
    &                  RegXMax,     & ! x 方向の物理領域の上限
    &                  RegYMin,     & ! y 方向の物理領域の下限
    &                  RegYMax        ! y 方向の物理領域の上限
  use TimeSet,  only : TimeDisp,    & ! 出力時間間隔
    &                  DelTimeLong    ! 長い時間ステップ

  !暗黙の型宣言禁止
  implicit none

  !属性の指定
  private

  !公開要素
  public StoreBuoy_Init, StoreBuoyMeanXY, StoreBuoyClean
  public z_BuoyTemp, z_BuoyMolWt, z_BuoyDrag
  public StoreBuoyTemp, StoreBuoyMolWt, StoreBuoyDrag

  !公開変数
  real(DP), allocatable :: z_BuoyTemp (:)
  real(DP), allocatable :: z_BuoyMolWt(:)
  real(DP), allocatable :: z_BuoyDrag (:)
  real(DP), allocatable :: xyz_BuoyTemp (:,:,:)
  real(DP), allocatable :: xyz_BuoyMolWt(:,:,:)
  real(DP), allocatable :: xyz_BuoyDrag (:,:,:)

  save z_BuoyTemp  , z_BuoyMolWt  , z_BuoyDrag
  save xyz_BuoyTemp, xyz_BuoyMolWt, xyz_BuoyDrag

contains

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

    allocate(     &
      & z_BuoyTemp (DimZMin:DimZMax),                                   & 
      & z_BuoyMolWt(DimZMin:DimZMax),                                   &
      & z_BuoyDrag (DimZMin:DimZMax),                                   &
      & xyz_BuoyTemp (DimXMin:DimXMax,DimYMin:DimYMax,DimZMin:DimZMax), & 
      & xyz_BuoyMolWt(DimXMin:DimXMax,DimYMin:DimYMax,DimZMin:DimZMax), &
      & xyz_BuoyDrag (DimXMin:DimXMax,DimYMin:DimYMax,DimZMin:DimZMax)  &
      &  )
    
    call StoreBuoyClean()

  end subroutine StoreBuoy_Init


  subroutine StoreBuoyClean( )
    !保管した値のクリアー
    
    z_BuoyTemp   = 0.0d0
    z_BuoyMolWt  = 0.0d0
    z_BuoyDrag   = 0.0d0
    xyz_BuoyTemp  = 0.0d0
    xyz_BuoyMolWt = 0.0d0
    xyz_BuoyDrag  = 0.0d0
    
  end subroutine StoreBuoyClean


  subroutine StoreBuoyMeanXY( )
    !保管した値の水平平均値
 
    real(DP) :: CalNum

    CalNum = TimeDisp / DelTimeLong
   
    z_BuoyTemp  = a_MeanXY_aaa( xyz_BuoyTemp  ) / CalNum
    z_BuoyMolWt = a_MeanXY_aaa( xyz_BuoyMolWt ) / CalNum
    z_BuoyDrag  = a_MeanXY_aaa( xyz_BuoyDrag  ) / CalNum

  end subroutine StoreBuoyMeanXY
  

  subroutine StoreBuoyTemp( xyz_Work )
    !温度の寄与を保管

    implicit none

    real(DP), intent(in)  :: xyz_Work (DimXMin:DimXMax,DimYMin:DimYMax,DimZMin:DimZMax)
    real(DP)              :: xyz_Work2(DimXMin:DimXMax,DimYMin:DimYMax,DimZMin:DimZMax)
    
    xyz_Work2    = xyz_BuoyTemp + xyz_Work 
    xyz_BuoyTemp = xyz_Work2

  end subroutine StoreBuoyTemp


  subroutine StoreBuoyMolWt( xyz_Work )
    !分子量の寄与を保管

    implicit none

    real(DP), intent(in)  :: xyz_Work (DimXMin:DimXMax,DimYMin:DimYMax,DimZMin:DimZMax)
    real(DP)              :: xyz_Work2(DimXMin:DimXMax,DimYMin:DimYMax,DimZMin:DimZMax)

    xyz_Work2     = xyz_BuoyMolWt + xyz_Work 
    xyz_BuoyMolWt = xyz_Work2

  end subroutine StoreBuoyMolWt


  subroutine StoreBuoyDrag( xyz_Work )
    !数値拡散項の保管

    implicit none
    
    real(DP), intent(in)  :: xyz_Work(DimXMin:DimXMax,DimYMin:DimYMax,DimZMin:DimZMax)
    real(DP)              :: xyz_Work2(DimXMin:DimXMax,DimYMin:DimYMax,DimZMin:DimZMax)

    xyz_Work2    = xyz_BuoyDrag + xyz_Work 
    xyz_BuoyDrag = xyz_Work2

  end subroutine StoreBuoyDrag


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

    a_MeanXY_aaa = sum( aa_work(RegYMin+1:RegYMax,:), 1 ) &
      &           / real(RegYMax - RegYMin, 8) 
    
  end function a_MeanXY_aaa

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

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

  end function aa_MeanX_aaa
 
  
end module StoreBuoy_3d
