!= Module HeatFlux
!
! Authors::   SUGIYAMA Ko-ichiro
! Version::   $Id: heatflux.f90,v 1.12 2006/09/21 02:41:51 odakker Exp $
! Tag Name::  $Name: arare4-20060922 $
! Copyright:: Copyright (C) GFD Dennou Club, 2006. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
!== Overview
!
!下部境界でのフラックスの計算モジュール
!
!== Error Handling
!
!== Bugs
!
!== Note
!
!  * 1.5 次のクロージャーを利用する
!  * 定式化は CReSS のマニュアルを参照した
!
!== Future Plans
!
!

module HeatFlux
  !
  !下部境界でのフラックスの計算モジュール
  !
  
  !モジュール読み込み
  use gridset,  only: DimXMin,         & !x 方向の配列の下限
    &                 DimXMax,         & !x 方向の配列の上限
    &                 DimZMin,         & !z 方向の配列の下限
    &                 DimZMax,         & !z 方向の配列の上限
    &                 RegZMin,         & !z 方向の物理領域の下限
    &                 DelZ               !z 方向の格子点間隔
  use basicset, only: xz_ExnerBasicZ,  & !エクスナー関数の基本場
    &                 xz_PotTempBasicZ,& !温位の基本場
    &                 xza_MixRtBasicZ, & !湿潤量の基本場 
    &                 TempSfc         ,& !地表面温度
    &                 PressSfc        ,& !地表面圧力 [Pa]
    &                 CpDry           ,& !乾燥成分の定圧比熱 [J/K kg]
    &                 GasRDry            !乾燥成分の気体定数 [J/K kg]

  use chemcalc, only: SvapPress, xz_SvapPress

  !暗黙の型宣言禁止
  implicit none

  !属性の指定
  private

  !関数を public に設定
  public xz_HeatFluxBulk
  public xz_MixRtFluxBulk

  !変数定義
  real(8)  :: Bulk = 1.5d-3        !熱・運動量フラックスのバルク係数

  !値を保存
  save Bulk

contains


!!!------------------------------------------------------------------------!!!
  function xz_HeatFluxBulk( xz_PotTemp )
    !
    !地表面熱フラックス(単位は W/m^2)をバルク法で計算する. 
    !大気下部の温度は基本場の温度に固定し, 
    !また水平速度を 100 m/s に固定する. 
    !
    !熱フラックス Cpρ \bar{ wθ} = Cm Cpρ V (Ta-TG)
    !これを変形すると, \bar{ wθ} = Cm V (θa-θG)π
    !\DP{\bar{ wθ}}{z} = Cm V (θa-θG)π /dz
    !
    
    !暗黙の型宣言禁止
    implicit none
    
    !変数定義
    real(8), intent(in)   :: xz_PotTemp(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !温位の擾乱成分    
    real(8)               :: xz_HeatFluxBulk(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !地表面熱フラックス
    real(8)  :: VelX = 1.0d0              !下層での水平速度を決めうち

    !初期化
    !  * 全ての値をゼロに固定
    xz_HeatFluxBulk = 0.0d0
    
    !地表面熱フラックスを計算
    !  * 単位は K/s
    !  * エクスナー関数は基本場の値で代表させる.     
    !  * 格子点 xz では, 物理領域の最下端の添え字は RegZMin+1
    !    フラックスは, RegZMin+1, RegZMin+2 での値の差に比例させる.
    !  * 基準温度(いわゆる地表面温度)は TempSfc にする.    
    !
    xz_HeatFluxBulk(:,RegZMin+1) =                        &
      & max(                                              &
      &         0.0d0,                                    &
      &       - Bulk * VelX * (xz_ExnerBasicZ(:,RegZMin+1)     &
      &          * (xz_PotTemp(:,RegZMin+1)+xz_PotTempBasicZ(:,RegZMin+1)) &
      &          - TempSfc ) / DelZ  &
      &    )


  end function xz_HeatFluxBulk
  
!!!------------------------------------------------------------------------!!!
  function xz_MixRtFluxBulk( xz_MixRt, xz_Exner, ID )
    !
    !地表面 MixRt フラックスをバルク法で計算する. 
    !大気下部の温度は基本場の温度に固定し, 
    !また水平速度を 100 m/s に固定する. 
    !
    
    !暗黙の型宣言禁止
    implicit none
    
    !変数定義
    real(8), intent(in)   :: xz_MixRt(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !温位の擾乱成分    
    real(8), intent(in)   :: xz_Exner(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !圧力の擾乱成分    
    integer, intent(in)   :: ID
    real(8)               :: xz_MixRtFluxBulk(DimXMin:DimXMax,DimZMin:DimZMax)
                                           !地表面熱フラックス
    real(8)  :: VelX = 1.0d0             !下層での水平速度を決めうち

    !初期化
    !  * 全ての値をゼロに固定
    xz_MixRtFluxBulk = 0.0d0
    
    xz_MixRtFluxBulk(:,RegZMin+1) =                        &
      & max(                                               &         
      &         0.0d0,                                     &
      &       - Bulk * VelX * ( xz_MixRt(:,RegZMin+1)      &
      &         - SvapPress( ID, TempSfc ) / (             &
      &           ( xz_Exner(:,RegZMin+1) + xz_ExnerBasicZ(:,RegZMin+1) ) &
      &           **( CpDry / GasRDry )*PressSfc )         &
      &       )/ DelZ                                      &
      &    )

   
  end function xz_MixRtFluxBulk
  
end module HeatFlux
