!---------------------------------------------------------------------
!     Copyright (C) GFD Dennou Club, 2005. All rights reserved.
!---------------------------------------------------------------------
!= Module LBFlux
!
!   * Developer: SUGIYAMA Ko-ichiro
!   * Version: $Id: $
!   * Tag Name: $Name:  $
!   * Change History: 
!
!== Overview
!
!下部境界でのフラックスの計算モジュール
!
!== Error Handling
!
!== Bugs
!
!== Note
!
!  * 1.5 次のクロージャーを利用する
!  * 定式化は CReSS のマニュアルを参照した
!
!== Future Plans
!
!

module LBFlux
  !
  !下部境界でのフラックスの計算モジュール
  !
  
  !モジュール読み込み
  use gridset,  only: DimXMin,         & !x 方向の配列の下限
    &                 DimXMax,         & !x 方向の配列の上限
    &                 DimZMin,         & !z 方向の配列の下限
    &                 DimZMax,         & !z 方向の配列の上限
    &                 RegZMin,         & !z 方向の物理領域の下限
    &                 DelZ               !z 方向の格子点間隔
  use basicset, only: xz_PotTempBasicZ, &!温位の基本場
    &                 xz_ExnerBasicZ     !エクスナー関数の基本場
  use average,  only: xz_avr_pz

  !暗黙の型宣言禁止
  implicit none

  !属性の指定
  private

  !関数を public に設定
  public xz_HFluxSfc
  public pz_MFluxSfc

  !変数定義
  real(8)  :: Bulk = 1.0d-2        !熱・運動量フラックスのバルク係数
  real(8)  :: TempFlux = 370.0d0   !地表面のフラックス(温度固定)

  !値を保存
  save Bulk, TempFlux

contains

!!!------------------------------------------------------------------------!!!
  function xz_HFluxSfc( pz_VelX, xz_PotTemp, xz_Exner )
    !
    !地表面熱フラックスを計算する. 
    !
    
    !暗黙の型宣言禁止
    implicit none
    
    !変数定義
    real(8), intent(in)   :: pz_VelX(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !水平速度の擾乱成分
    real(8), intent(in)   :: xz_PotTemp(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !温位の擾乱成分    
    real(8), intent(in)   :: xz_Exner(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !エクスナー関数の擾乱成分
    real(8)               :: xz_HFluxSfc(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !地表面熱フラックス
    real(8)               :: xz_TempAll(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !温度 (基本場 + 擾乱成分)

    !モデル最下層での温度を求める
    xz_TempAll =   ( xz_PotTemp + xz_PotTempBasicZ ) &
      &          * ( xz_Exner   + xz_ExnerBasicZ   )
    
    !地表面熱フラックスを計算
    xz_HFluxSfc =                                                            &
      & Bulk * xz_avr_pz( abs( pz_VelX ) ) * ( TempFlux - xz_TempAll ) / DelZ

    !RegZMin + 1 でのみ値を持つようにする
    xz_HFluxSfc(:,DimZMin:RegZMin)   = 0.0d0
    xz_HFluxSfc(:,RegZMin+2:DimZMax) = 0.0d0
    
  end function xz_HFluxSfc
  


!!!------------------------------------------------------------------------!!!
  function pz_MFluxSfc( pz_VelX )    
    !
    !地表面運動量フラックスを計算する
    !
    
    !暗黙の型宣言禁止
    implicit none

    !変数定義
    real(8), intent(in)   :: pz_VelX(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !水平速度の擾乱成分
    real(8)               :: pz_MFluxSfc(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !地表面運動量フラックス

    !地表面運動量フラックスを計算
    pz_MFluxSfc = - Bulk * abs( pz_VelX ) * pz_VelX / DelZ
    
    !RegZMin + 1 でのみ値を持つようにする
    pz_MFluxSfc(:,DimZMin:RegZMin)   = 0.0d0
    pz_MFluxSfc(:,RegZMin+2:DimZMax) = 0.0d0

  end function pz_MFluxSfc

  
end module LBFlux
