対æ�調ç��¹ã�ã�¼ã��������, æ¸�º¦���湿ã��調ç����¾ã��.
Adjust temperature and specific humidity by convective adjustment scheme.
subroutine Cumulus( xyz_Temp, xyz_QVap, xy_Rain, xyz_DTempDt, xyz_DQVapDt, xyz_Press, xyr_Press, xyz_DDelLWDtCCP )
!
! 対æ�調ç��¹ã�ã�¼ã��������, æ¸�º¦���湿ã��調ç����¾ã��.
!
! Adjust temperature and specific humidity by
! convective adjustment scheme.
!
! �¢ã�¸ã�¥ã�¼ã����� ; USE statements
!
! ����å®��°è¨å®�
! Physical constants settings
!
use constants, only: GasRUniv, Grav, GasRDry, CpDry, GasRWet, LatentHeat, EpsV
! $ \epsilon_v $ .
! æ°´è�¸æ���å��閴�.
! Molecular weight of water vapor
! ���»ç���
! Time control
!
use timeset, only: DelTime, TimeN, TimesetClockStart, TimesetClockStop
! ���¹ã�������¼ã�¿å�ºå��
! History data output
!
use gtool_historyauto, only: HistoryAutoPut
! 宣�� ; Declaration statements
!
implicit none
real(DP), intent(inout):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax)
! $ T $ . æ¸�º¦. Temperature
real(DP), intent(inout):: xyz_QVap (0:imax-1, 1:jmax, 1:kmax)
! $ q $ . ��. Specific humidity
real(DP), intent(inout):: xy_Rain (0:imax-1, 1:jmax)
! ��水�.
! Precipitation
real(DP), intent(inout):: xyz_DTempDt (0:imax-1, 1:jmax, 1:kmax)
! æ¸�º¦å¤�����.
! Temperature tendency
real(DP), intent(inout):: xyz_DQVapDt (0:imax-1, 1:jmax, 1:kmax)
! �湿����.
! Specific humidity tendency
real(DP), intent(in):: xyz_Press (0:imax-1, 1:jmax, 1:kmax)
! $ p $ . æ°��� (�´æ�°ã������).
! Air pressure (full level)
real(DP), intent(in):: xyr_Press (0:imax-1, 1:jmax, 0:kmax)
! $ \hat{p} $ . æ°��� (���´æ�°ã������).
! Air pressure (half level)
real(DP), intent(out), optional:: xyz_DDelLWDtCCP(0:imax-1, 1:jmax, 1:kmax)
! Production rate of liquid water in the layer
! due to condensation in cumulus convection
! parameterization (kg m-2 s-1)
! ä½�æ¥å���
! Work variables
!
real(DP):: xy_RainCumulus (0:imax-1, 1:jmax)
! ��水�.
! Precipitation
real(DP):: xyz_DTempDtCumulus (0:imax-1, 1:jmax, 1:kmax)
! æ¸�º¦å¤�����.
! Temperature tendency
real(DP):: xyz_DQVapDtCumulus (0:imax-1, 1:jmax, 1:kmax)
! �湿����.
! Specific humidity tendency
real(DP):: xyz_QVapB (0:imax-1, 1:jmax, 1:kmax)
! 調������.
! Specific humidity before adjust.
real(DP):: xyz_TempB (0:imax-1, 1:jmax, 1:kmax)
! 調ç�����¸©åº�.
! Temperature before adjust.
logical:: xy_Adjust (0:imax-1, 1:jmax)
! ���調������������?.
! Whether it was adjusted this time or not?
logical:: xy_AdjustB (0:imax-1, 1:jmax)
! ����調������������?.
! Whether it was adjusted last time or not?
real(DP):: xyz_DPressDz (0:imax-1, 1:jmax, 1:kmax)
! $ \DD{p}{z} $
!
real(DP):: xyz_QVapSat (0:imax-1, 1:jmax, 1:kmax)
! 飽���.
! Saturation specific humidity.
real(DP):: xyz_DDPressDDPress (0:imax-1, 1:jmax, 1:kmax)
! $ \DD{p_{k}}{p_{k-1}} $
!
real(DP):: xyz_DPFact (0:imax-1, 1:jmax, 1:kmax)
! $ (R / C_p)
! \frac{p_{k-1} - p_{k}}{2 p_{k-1/2}} $ .
!
! ���¡ã���¿ã��.
! Factor
real(DP):: TempSat ! $ S_t $ .
! 飽å��æ¸�º¦.
! Saturation temperature
real(DP):: DelTempSat
! 調ç�������飽å��æ¸�º¦�������.
! Saturation temperature variation by adjustment
real(DP):: DelQVap
! 調�������湿������.
! Specific humidity variation by adjustment
real(DP):: DelTempUpper
! 調ç�������æ¸�º¦ (k) �������.
! Temperature (k) variation by adjustment
real(DP):: DelTempLower
! 調ç�������æ¸�º¦ (k-1) �������.
! Temperature (k-1) variation by adjustment
real(DP):: DQVapSatDTempUpper
! $ \DD{q^{*}} (k)}{T} $
real(DP):: DQVapSatDTempLower
! $ \DD{q^{*}} (k-1)}{T} $
real(DP):: DHDTempUpper
! $ 1 + \gamma_{k} =
! 1 + \frac{L}{C_p} \DP{q^{*}}{T}_{k} $
real(DP):: DHDTempLower
! $ 1 + \gamma_{k-1} =
! 1 + \frac{L}{C_p} \DP{q^{*}}{T}_{k-1} $
logical:: Adjust
! ä»������������������åº��§ã��調ç�������������?.
! Whether it was adjusted even once in global
! this time or not?
integer:: i ! çµ�åº��¹å�������� DO ���¼ã�����æ¥å���
! Work variables for DO loop in longitude
integer:: j ! ç·�º¦�¹å�������� DO ���¼ã�����æ¥å���
! Work variables for DO loop in latitude
integer:: k ! ���´æ�¹å�������� DO ���¼ã�����æ¥å���
! Work variables for DO loop in vertical direction
integer:: itr ! �¤ã�����¼ã�·ã�§ã�³æ�¹å�������� DO ���¼ã�����æ¥å���
! Work variables for DO loop in iteration direction
real(DP):: xyz_RainCumulus (0:imax-1, 1:jmax, 1:kmax)
! 飽å��æ¯�湿è�ç®������������¢æ�°å�ç¾�
! Declaration of statement function for
! calculation of saturation specific humidity
!
#ifdef LIB_SATURATE_NHA1992
#include "../saturate/saturate_nha1992_sf.f90"
EpsVSF = EpsV
GasRUnivSF = GasRUniv
#elif LIB_SATURATE_T1930
#include "../saturate/saturate_t1930_sf.f90"
EpsVSF = EpsV
LatHeatSF = LatentHeat
GasRWetSF = GasRWet
#else
#include "../saturate/saturate_t1930_sf.f90"
EpsVSF = EpsV
LatHeatSF = LatentHeat
GasRWetSF = GasRWet
#endif
! ���� ; Executable statement
!
! �����������
! Start measurement of computation time
!
call TimesetClockStart( module_name )
! ������
! Initialization
!
if ( .not. cumulus_adjust_inited ) call CumAdjInit
! 調ç��� "QVap", "Temp" ���å�
! Store "QVap", "Temp" before adjustment
!
xyz_QVapB = xyz_QVap
xyz_TempB = xyz_Temp
! ���¡ã���¿ã�¼ã���ç®�
! Calculate factor
!
do k = 1, kmax
xyz_DPressDz(:,:,k) = xyr_Press(:,:,k-1) - xyr_Press(:,:,k)
end do
! 飽å��æ¯�湿è�ç®�
! Calculate saturation specific humidity
!
! Nakajima et al. (1992) ��������飽��湿���
! Calculate saturation specific humidity with Nakajima et al. (1992)
!
do k = 1, kmax
do j = 1, jmax
do i = 0, imax-1
! CalcQVapSatSF �����¢æ��. (å®�è¡������´å���§å�ç¾�)
! "CalcQVapSatSF" is statement function and
! is declared just before executable statement.
!
xyz_QVapSat(i,j,k) = CalcQVapSatSF( xyz_Temp(i,j,k), xyz_Press(i,j,k) )
end do
end do
end do
xyz_DDPressDDPress(:,:,1) = 0.
do k = 2, kmax
xyz_DDPressDDPress(:,:,k) = xyz_DPressDz(:,:,k) / xyz_DPressDz(:,:,k-1)
xyz_DPFact(:,:,k) = GasRDry / CpDry * ( xyz_Press(:,:,k-1) - xyz_Press(:,:,k) ) / xyr_Press(:,:,k-1) / 2.0_DP
end do
! 調ç�
! Adjustment
!
xy_AdjustB = .true.
! �¤ã�����¼ã�·ã�§ã��
! Iteration
!
do itr = 1, ItrtMax
xy_Adjust = .false.
do k = 2, kmax
do j = 1, jmax
do i = 0, imax-1
if ( xy_AdjustB(i,j) ) then
TempSat = xyz_Temp(i,j,k-1) - xyz_Temp(i,j,k) + ( xyz_QVapSat(i,j,k-1) - xyz_QVapSat(i,j,k) ) * LatentHeat / CpDry - xyz_DPFact(i,j,k) * ( xyz_Temp(i,j,k-1) + xyz_Temp(i,j,k) )
! ä¸�å®�å®��§ã����������
! If it is unstable
!
if ( TempSat > TempSatMax(itr) ) then
! .. ����, 飽���������������
! .. and, if it is saturated
!
if ( ( xyz_QVap(i,j,k) / xyz_QVapSat(i,j,k) >= CrtlRH ) .and. ( xyz_QVap(i,j,k-1) / xyz_QVapSat(i,j,k-1) >= CrtlRH ) ) then
DelQVap = xyz_DPressDz(i,j,k-1) * (xyz_QVap(i,j,k-1) - xyz_QVapSat(i,j,k-1) ) + xyz_DPressDz(i,j,k) * (xyz_QVap(i,j,k) - xyz_QVapSat(i,j,k) )
! CalcDQVapSatDTempSF �����¢æ��. (å®�è¡������´å���§å�ç¾�)
! "CalcDQVapSatDTempSF" is statement function and
! is declared just before executable statement.
!
DQVapSatDTempUpper = CalcDQVapSatDTempSF( xyz_Temp(i,j,k), xyz_QVapSat(i,j,k) )
DQVapSatDTempLower = CalcDQVapSatDTempSF( xyz_Temp(i,j,k-1), xyz_QVapSat(i,j,k-1) )
DHDTempUpper = 1.0_DP + LatentHeat/CpDry * DQVapSatDTempUpper
DHDTempLower = 1.0_DP + LatentHeat/CpDry * DQVapSatDTempLower
DelTempSat = TempSat + ( 1.0_DP - xyz_DPFact(i,j,k) / DHDTempLower ) * LatentHeat/CpDry * DelQVap / xyz_DPressDz(i,j,k-1)
! æ¸�º¦���ç¯�
! Adjust temperature
!
DelTempUpper = DelTempSat / ( ( 1.0_DP + xyz_DDPressDDPress(i,j,k) ) * DHDTempUpper + xyz_DPFact(i,j,k) * ( 1.0_DP - xyz_DDPressDDPress(i,j,k) * DHDTempUpper / DHDTempLower ) )
DelTempLower = - DHDTempUpper / DHDTempLower * xyz_DDPressDDPress(i,j,k) * DelTempUpper + LatentHeat / CpDry * DelQVap / ( xyz_DPressDz(i,j,k-1) * DHDTempLower )
xyz_Temp(i,j,k) = xyz_Temp(i,j,k) + DelTempUpper
xyz_Temp(i,j,k-1) = xyz_Temp(i,j,k-1) + DelTempLower
! �湿���
! Adjust specific humidity
!
xyz_QVap(i,j,k) = xyz_QVapSat(i,j,k) + DQVapSatDTempUpper * DelTempUpper
xyz_QVap(i,j,k-1) = xyz_QVapSat(i,j,k-1) + DQVapSatDTempLower * DelTempLower
xyz_QVapSat(i,j,k) = xyz_QVap(i,j,k)
xyz_QVapSat(i,j,k-1) = xyz_QVap(i,j,k-1)
! 調����������?
! Whether it was adjusted or not?
!
xy_Adjust(i,j) = .true.
end if
end if
end if
end do
end do
end do
Adjust = .false.
do i = 0, imax-1
do j = 1, jmax
xy_AdjustB(i,j) = xy_Adjust(i,j)
Adjust = Adjust .or. xy_Adjust(i,j)
end do
end do
if ( .not. Adjust ) exit
end do
! æ¯�湿å�����, æ¸�º¦å¤�����, ��æ°´é������
! Calculate specific humidity tendency, temperature tendency, precipitation
!
xy_RainCumulus = 0.
xyz_DTempDtCumulus = 0.
xyz_DQVapDtCumulus = 0.
xyz_DQVapDtCumulus = xyz_DQVapDtCumulus + ( xyz_QVap - xyz_QVapB ) / ( 2.0_DP * DelTime )
xyz_DTempDtCumulus = xyz_DTempDtCumulus + ( xyz_Temp - xyz_TempB ) / ( 2.0_DP * DelTime )
do k = 1, kmax
xy_RainCumulus = xy_RainCumulus + ( xyz_QVapB(:,:,k) - xyz_QVap(:,:,k) ) * xyz_DPressDz(:,:,k) / Grav / ( 2.0_DP * DelTime )
end do
xy_Rain = xy_Rain + xy_RainCumulus
xyz_DTempDt = xyz_DTempDt + xyz_DTempDtCumulus
xyz_DQVapDt = xyz_DQVapDt + xyz_DQVapDtCumulus
! ���¹ã�������¼ã�¿å�ºå��
! History data output
!
call HistoryAutoPut( TimeN, 'RainCumulus', xy_RainCumulus * LatentHeat )
call HistoryAutoPut( TimeN, 'DTempDtCumulus', xyz_DTempDtCumulus )
call HistoryAutoPut( TimeN, 'DQVapDtCumulus', xyz_DQVapDtCumulus )
if ( present( xyz_DDelLWDtCCP ) ) then
xyz_DDelLWDtCCP = + ( xyz_QVapB - xyz_QVap ) * xyz_DPressDz / Grav / ( 2.0_DP * DelTime )
end if
! è¨�ç®�����è¨�æ¸������æ�
! Pause measurement of computation time
!
call TimesetClockStop( module_name )
end subroutine Cumulus