Class | vdiffusion_my |
In: |
vdiffusion/vdiffusion_my.f90
|
Note that Japanese and English are described in parallel.
鉛直拡散フラックスを計算します.
Vertical diffusion flux is calculated.
VDiffusion : | 鉛直拡散フラックスの計算 |
VDiffusionOutPut : | フラックスの出力 |
———— : | ———— |
VDiffusion : | Calculate vertical diffusion fluxes |
VDiffusionOutPut : | Output fluxes |
Subroutine : | |||
xyz_U(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyz_V(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) : | real(DP), intent(in)
| ||
xyz_Temp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Temp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_VirTemp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_VirTemp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_Press(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xy_SurfHeight(0:imax-1,1:jmax) : | real(DP), intent(in)
| ||
xyz_Height(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Height(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_Exner(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Exner(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_MomFluxX(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_MomFluxY(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_HeatFlux(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) : | real(DP), intent(out)
| ||
xyr_VelDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_TempDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_QMixDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
|
鉛直拡散フラックスを計算します.
Vertical diffusion flux is calculated by use of MY2 model.
subroutine VDiffusion( xyz_U, xyz_V, xyzf_QMix, xyz_Temp, xyr_Temp, xyz_VirTemp, xyr_VirTemp, xyr_Press, xy_SurfHeight, xyz_Height, xyr_Height, xyz_Exner, xyr_Exner, xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef ) ! ! 鉛直拡散フラックスを計算します. ! ! Vertical diffusion flux is calculated by use of MY2 model. ! ! モジュール引用 ; USE statements ! ! 物理定数設定 ! Physical constants settings ! use constants, only: FKarm, Grav ! $ g $ [m s-2]. ! 重力加速度. ! Gravitational acceleration ! 時刻管理 ! Time control ! use timeset, only: TimeN, TimesetClockStart, TimesetClockStop ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoPut ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in):: xyz_U (0:imax-1, 1:jmax, 1:kmax) ! $ u $ . 東西風速. Eastward wind real(DP), intent(in):: xyz_V (0:imax-1, 1:jmax, 1:kmax) ! $ v $ . 南北風速. Northward wind real(DP), intent(in):: xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) ! $ q $ . 質量混合比. Mass mixing ratio real(DP), intent(in):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax) ! $ T $ . 温度. Temperature real(DP), intent(in):: xyr_Temp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T} $ . 温度 (半整数レベル). ! Temperature (half level) real(DP), intent(in):: xyz_VirTemp (0:imax-1, 1:jmax, 1:kmax) ! $ T_v $ . 仮温度. Virtual temperature real(DP), intent(in):: xyr_VirTemp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T}_v $ . 仮温度 (半整数レベル). ! Virtual temperature (half level) real(DP), intent(in):: xyr_Press (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{p} $ . 気圧 (半整数レベル). ! Air pressure (half level) real(DP), intent(in):: xy_SurfHeight (0:imax-1,1:jmax) ! $ z_s $ . 地表面高度. ! Surface height. real(DP), intent(in):: xyz_Height (0:imax-1, 1:jmax, 1:kmax) ! 高度 (整数レベル). ! Height (full level) real(DP), intent(in):: xyr_Height (0:imax-1, 1:jmax, 0:kmax) ! 高度 (半整数レベル). ! Height (half level) real(DP), intent(in):: xyz_Exner (0:imax-1, 1:jmax, 1:kmax) ! Exner 関数 (整数レベル). ! Exner function (full level) real(DP), intent(in):: xyr_Exner (0:imax-1, 1:jmax, 0:kmax) ! Exner 関数 (半整数レベル). ! Exner function (half level) real(DP), intent(out):: xyr_MomFluxX (0:imax-1, 1:jmax, 0:kmax) ! 東西方向運動量フラックス. ! Eastward momentum flux real(DP), intent(out):: xyr_MomFluxY (0:imax-1, 1:jmax, 0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP), intent(out):: xyr_HeatFlux (0:imax-1, 1:jmax, 0:kmax) ! 熱フラックス. ! Heat flux real(DP), intent(out):: xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) ! 質量フラックス. ! Mass flux of compositions real(DP), intent(out):: xyr_VelDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP), intent(out):: xyr_TempDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:温度. ! Transfer coefficient: temperature real(DP), intent(out):: xyr_QMixDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:比湿. ! Diffusion coefficient: specific humidity ! 作業変数 ! Work variables ! real(DP) :: xyr_DVelDz (0:imax-1, 1:jmax, 0:kmax) ! $ \DD{|\Dvect{v}|}{z} $ real(DP) :: xyr_BulkRiNum (0:imax-1, 1:jmax, 0:kmax) ! バルク $ R_i $ 数. ! Bulk $ R_i $ integer:: k ! 鉛直方向に回る DO ループ用作業変数 ! Work variables for DO loop in vertical direction integer:: n ! 組成方向に回る DO ループ用作業変数 ! Work variables for DO loop in dimension of constituents ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if ! 計算時間計測開始 ! Start measurement of computation time ! call TimesetClockStart( module_name ) ! 拡散係数の計算 ! Calculation of diffusion coefficient ! if ( FlagConstDiffCoef ) then xyr_VelDiffCoef (:,:,0 ) = 0.0_DP xyr_VelDiffCoef (:,:,1:kmax-1) = ConstDiffCoefM xyr_VelDiffCoef (:,:,kmax ) = 0.0_DP xyr_TempDiffCoef(:,:,0 ) = 0.0_DP xyr_TempDiffCoef(:,:,1:kmax-1) = ConstDiffCoefH xyr_TempDiffCoef(:,:,kmax ) = 0.0_DP xyr_QMixDiffCoef(:,:,0 ) = 0.0_DP xyr_QMixDiffCoef(:,:,1:kmax-1) = ConstDiffCoefH xyr_QMixDiffCoef(:,:,kmax ) = 0.0_DP else ! バルク $ R_i $ 数算出 ! Calculate bulk $ R_i $ ! xyr_DVelDz(:,:,0) = 0.0_DP xyr_DVelDz(:,:,kmax) = 0.0_DP xyr_BulkRiNum(:,:,0) = 0.0_DP xyr_BulkRiNum(:,:,kmax) = 0.0_DP do k = 1, kmax-1 xyr_DVelDz(:,:,k) = sqrt( max( SquareVelMin , ( xyz_U(:,:,k+1) - xyz_U(:,:,k) )**2 + ( xyz_V(:,:,k+1) - xyz_V(:,:,k) )**2 ) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) xyr_BulkRiNum(:,:,k) = Grav / ( xyr_VirTemp(:,:,k) / xyr_Exner(:,:,k) ) * ( xyz_VirTemp(:,:,k+1) / xyz_Exner(:,:,k+1) - xyz_VirTemp(:,:,k ) / xyz_Exner(:,:,k ) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) / xyr_DVelDz(:,:,k)**2 xyr_BulkRiNum(:,:,k) = max( xyr_BulkRiNum(:,:,k) , BulkRiNumMin ) end do ! 拡散係数の計算 ! Calculate diffusion coefficients ! call VDiffCoefficient( xy_SurfHeight, xyr_Height, xyr_DVelDz, xyr_BulkRiNum, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef ) end if ! 浅い積雲対流 ! Shallow cumulus convection ! ! (AGCM5 から導入予定) ! 拡散係数の出力 ! Output diffusion coefficients ! ! (上記の「浅い積雲対流」導入後に作成) ! 拡散係数出力 ! Diffusion coeffficients output ! call HistoryAutoPut( TimeN, 'VelDiffCoef', xyr_VelDiffCoef ) call HistoryAutoPut( TimeN, 'TempDiffCoef', xyr_TempDiffCoef ) call HistoryAutoPut( TimeN, 'QVapDiffCoef', xyr_QMixDiffCoef ) ! 輸送係数とフラックスの計算 ! Calculate transfer coefficient and flux ! call VDiffusionCalcFlux( xyz_U, xyz_V, xyzf_QMix, xyz_Temp, xyr_VirTemp, xyr_Press, xyz_Height, xyz_Exner, xyr_Exner, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef, xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux ) ! 計算時間計測一時停止 ! Pause measurement of computation time ! call TimesetClockStop( module_name ) end subroutine VDiffusion
Subroutine : | |||
xyr_Press(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in )
| ||
xyr_MomFluxX(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in ), optional
| ||
xyr_MomFluxY(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in ), optional
| ||
xyr_HeatFlux(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in ), optional
| ||
xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) : | real(DP), intent(in ), optional
| ||
xyz_DUDt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(out), optional
| ||
xyz_DVDt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(out), optional
| ||
xyz_DTempDt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(out), optional
| ||
xyzf_DQMixDt(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) : | real(DP), intent(out), optional
|
時間変化率の計算を行います.
Calculate tendencies.
subroutine VDiffusionExpTendency( xyr_Press, xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux, xyz_DUDt, xyz_DVDt, xyz_DTempDt, xyzf_DQMixDt ) ! ! 時間変化率の計算を行います. ! ! Calculate tendencies. ! ! モジュール引用 ; USE statements ! ! 物理定数設定 ! Physical constants settings ! use constants, only: Grav, CpDry ! $ C_p $ [J kg-1 K-1]. ! 乾燥大気の定圧比熱. ! Specific heat of air at constant pressure ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in ):: xyr_Press (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{p} $ . 気圧 (半整数レベル). ! Air pressure (half level) real(DP), intent(in ), optional :: xyr_MomFluxX (0:imax-1, 1:jmax, 0:kmax) ! 東西方向運動量フラックス. ! Eastward momentum flux real(DP), intent(in ), optional :: xyr_MomFluxY (0:imax-1, 1:jmax, 0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP), intent(in ), optional :: xyr_HeatFlux (0:imax-1, 1:jmax, 0:kmax) ! 熱フラックス. ! Heat flux real(DP), intent(in ), optional :: xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) ! 比湿フラックス. ! Specific humidity flux real(DP), intent(out), optional :: xyz_DUDt (0:imax-1, 1:jmax, 1:kmax) ! $ \DP{u}{t} $ . 東西風速変化. ! Eastward wind tendency real(DP), intent(out), optional :: xyz_DVDt (0:imax-1, 1:jmax, 1:kmax) ! $ \DP{v}{t} $ . 南北風速変化. ! Northward wind tendency real(DP), intent(out), optional :: xyz_DTempDt (0:imax-1, 1:jmax, 1:kmax) ! $ \DP{T}{t} $ . 温度変化. ! Temperature tendency real(DP), intent(out), optional :: xyzf_DQMixDt(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) ! $ \DP{q}{t} $ . 質量混合比変化. ! Mass mixing ratio tendency ! 作業変数 ! Work variables ! integer:: k ! 鉛直方向に回る DO ループ用作業変数 ! Work variables for DO loop in vertical direction integer:: n ! 組成方向に回る DO ループ用作業変数 ! Work variables for DO loop in dimension of constituents ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if ! Check arguments ! if ( present( xyz_DUDt ) ) then if ( .not. present( xyr_MomFluxX ) ) then call MessageNotify( 'E', module_name, 'xyr_MomFluxX has to be present.' ) end if end if if ( present( xyz_DVDt ) ) then if ( .not. present( xyr_MomFluxY ) ) then call MessageNotify( 'E', module_name, 'xyr_MomFluxY has to be present.' ) end if end if if ( present( xyz_DTempDt ) ) then if ( .not. present( xyr_HeatFlux ) ) then call MessageNotify( 'E', module_name, 'xyr_HeatFlux has to be present.' ) end if end if if ( present( xyzf_DQMixDt ) ) then if ( .not. present( xyrf_QMixFlux ) ) then call MessageNotify( 'E', module_name, 'xyrf_QMixFlux has to be present.' ) end if end if if ( present( xyz_DUDt ) ) then do k = 1, kmax xyz_DUDt(:,:,k) = + Grav * ( xyr_MomFluxX(:,:,k) - xyr_MomFluxX(:,:,k-1) ) / ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) end do end if if ( present( xyz_DVDt ) ) then do k = 1, kmax xyz_DVDt(:,:,k) = + Grav * ( xyr_MomFluxY(:,:,k) - xyr_MomFluxY(:,:,k-1) ) / ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) end do end if if ( present( xyz_DTempDt ) ) then do k = 1, kmax xyz_DTempDt(:,:,k) = + Grav / CpDry * ( xyr_HeatFlux(:,:,k) - xyr_HeatFlux(:,:,k-1) ) / ( xyr_Press (:,:,k) - xyr_Press (:,:,k-1) ) end do end if if ( present( xyzf_DQMixDt ) ) then do n = 1, ncmax do k = 1, kmax xyzf_DQMixDt(:,:,k,n) = + Grav * ( xyrf_QMixFlux(:,:,k,n) - xyrf_QMixFlux(:,:,k-1,n) ) / ( xyr_Press (:,:,k) - xyr_Press (:,:,k-1) ) end do end do end if end subroutine VDiffusionExpTendency
Subroutine : |
vdiffusion_my モジュールの初期化を行います. NAMELIST#vdiffusion_my_nml の読み込みはこの手続きで行われます.
"vdiffusion_my" module is initialized. "NAMELIST#vdiffusion_my_nml" is loaded in this procedure.
This procedure input/output NAMELIST#vdiffusion_my_nml .
subroutine VDiffusionInit ! ! vdiffusion_my モジュールの初期化を行います. ! NAMELIST#vdiffusion_my_nml の読み込みはこの手続きで行われます. ! ! "vdiffusion_my" module is initialized. ! "NAMELIST#vdiffusion_my_nml" is loaded in this procedure. ! ! モジュール引用 ; USE statements ! ! NAMELIST ファイル入力に関するユーティリティ ! Utilities for NAMELIST file input ! use namelist_util, only: namelist_filename, NmlutilMsg, NmlutilAryValid ! ファイル入出力補助 ! File I/O support ! use dc_iounit, only: FileOpen ! 種別型パラメタ ! Kind type parameter ! use dc_types, only: STDOUT ! 標準出力の装置番号. Unit number of standard output ! 文字列操作 ! Character handling ! use dc_string, only: StoA ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoAddVariable ! 座標データ設定 ! Axes data settings ! use axesset, only: AxnameX, AxnameY, AxnameZ, AxnameR, AxnameT ! 宣言文 ; Declaration statements ! implicit none integer:: unit_nml ! NAMELIST ファイルオープン用装置番号. ! Unit number for NAMELIST file open integer:: iostat_nml ! NAMELIST 読み込み時の IOSTAT. ! IOSTAT of NAMELIST read ! NAMELIST 変数群 ! NAMELIST group name ! namelist /vdiffusion_my_nml/ FlagConstDiffCoef, ConstDiffCoefM, ConstDiffCoefH, SquareVelMin, BulkRiNumMin, MixLengthMax, ShMin, SmMin, VelDiffCoefMin, TempDiffCoefMin, VelDiffCoefMax, TempDiffCoefMax, MYConstA1, MYConstB1, MYConstA2, MYConstB2, MYConstC1 ! ! デフォルト値については初期化手続 "vdiffusion_my#VDiffInit" ! のソースコードを参照のこと. ! ! Refer to source codes in the initialization procedure ! "vdiffusion_my#VDiffInit" for the default values. ! ! 実行文 ; Executable statement ! if ( vdiffusion_my_inited ) return ! デフォルト値の設定 ! Default values settings ! FlagConstDiffCoef = .false. ConstDiffCoefM = 0.0_DP ConstDiffCoefH = 0.0_DP SquareVelMin = 0.1_DP BulkRiNumMin = - 100.0_DP MixLengthMax = 300.0_DP ShMin = 0.0_DP SmMin = 0.0_DP VelDiffCoefMin = 0.1_DP TempDiffCoefMin = 0.1_DP VelDiffCoefMax = 10000.0_DP TempDiffCoefMax = 10000.0_DP ! Parameters proposed by Mellor and Yamada (1982). ! MYConstA1 = 0.92_DP MYConstB1 = 16.6_DP MYConstA2 = 0.74_DP MYConstB2 = 10.1_DP MYConstC1 = 0.08_DP ! NAMELIST の読み込み ! NAMELIST is input ! if ( trim(namelist_filename) /= '' ) then call FileOpen( unit_nml, namelist_filename, mode = 'r' ) ! (in) rewind( unit_nml ) read( unit_nml, nml = vdiffusion_my_nml, iostat = iostat_nml ) ! (out) close( unit_nml ) call NmlutilMsg( iostat_nml, module_name ) ! (in) if ( iostat_nml == 0 ) write( STDOUT, nml = vdiffusion_my_nml ) end if ! ヒストリデータ出力のためのへの変数登録 ! Register of variables for history data output ! call HistoryAutoAddVariable( 'VelDiffCoef', (/ AxNameX, AxNameY, AxNameR, AxNameT /), 'diffusion coef. momentum', 'm2 s-1' ) call HistoryAutoAddVariable( 'TempDiffCoef', (/ AxNameX, AxNameY, AxNameR, AxNameT /), 'diffusion coef. heat ', 'm2 s-1' ) call HistoryAutoAddVariable( 'QVapDiffCoef', (/ AxNameX, AxNameY, AxNameR, AxNameT /), 'diffusion coef. moisture', 'm2 s-1' ) call HistoryAutoAddVariable( 'MomFluxX', (/ AxNameX, AxNameY, AxNameR, AxNameT /), 'eastward momentum flux', 'N m-2' ) call HistoryAutoAddVariable( 'MomFluxY', (/ AxNameX, AxNameY, AxNameR, AxNameT /), 'northward momentum flux', 'N m-2' ) call HistoryAutoAddVariable( 'HeatFlux', (/ AxNameX, AxNameY, AxNameR, AxNameT /), 'heat flux', 'W m-2' ) call HistoryAutoAddVariable( 'QVapFlux', (/ AxNameX, AxNameY, AxNameR, AxNameT /), 'moisture flux', 'W m-2' ) call HistoryAutoAddVariable( 'DUDtVDiff', (/ AxNameX, AxNameY, AxNameZ, AxNameT /), 'tendency of zonal wind by vertical diffusion', 'm s-2' ) call HistoryAutoAddVariable( 'DVDtVDiff', (/ AxNameX, AxNameY, AxNameZ, AxNameT /), 'tendency of meridional wind by vertical diffusion', 'm s-2' ) call HistoryAutoAddVariable( 'DTempDtVDiff', (/ AxNameX, AxNameY, AxNameZ, AxNameT /), 'tendency of temperature by vertical diffusion', 'K s-1' ) call HistoryAutoAddVariable( 'DQVapDtVDiff', (/ AxNameX, AxNameY, AxNameZ, AxNameT /), 'tendency of specific humidity by vertical diffusion', 's-1' ) call HistoryAutoAddVariable( 'TurKinEne', (/ AxNameX, AxNameY, AxNameR, AxNameT /), 'turbulent kinetic energy', 'm2 s-2' ) call HistoryAutoAddVariable( 'TKEPShear', (/ AxNameX, AxNameY, AxNameZ, AxNameT /), 'turbulent kinetic energy production rate by shear', 'm2 s-3' ) call HistoryAutoAddVariable( 'TKEPBuoy', (/ AxNameX, AxNameY, AxNameZ, AxNameT /), 'turbulent kinetic energy production rate by buoyancy', 'm2 s-3' ) call HistoryAutoAddVariable( 'TKEDiss', (/ AxNameX, AxNameY, AxNameZ, AxNameT /), 'turbulent kinetic energy dissipation rate', 'm2 s-3' ) call HistoryAutoAddVariable( 'MixLength', (/ AxNameX, AxNameY, AxNameZ, AxNameT /), 'mixing length', 'm' ) ! 印字 ; Print ! call MessageNotify( 'M', module_name, '----- Initialization Messages -----' ) call MessageNotify( 'M', module_name, 'For vertical diffusion flux:' ) call MessageNotify( 'M', module_name, ' FlagConstDiffCoef = %b', l = (/ FlagConstDiffCoef /) ) call MessageNotify( 'M', module_name, ' ConstDiffCoefM = %f', d = (/ ConstDiffCoefM /) ) call MessageNotify( 'M', module_name, ' ConstDiffCoefH = %f', d = (/ ConstDiffCoefH /) ) call MessageNotify( 'M', module_name, ' SquareVelMin = %f', d = (/ SquareVelMin /) ) call MessageNotify( 'M', module_name, ' BulkRiNumMin = %f', d = (/ BulkRiNumMin /) ) call MessageNotify( 'M', module_name, 'For diffusion coefficients:' ) call MessageNotify( 'M', module_name, ' MixLengthMax = %f', d = (/ MixLengthMax /) ) call MessageNotify( 'M', module_name, ' ShMin = %f', d = (/ ShMin /) ) call MessageNotify( 'M', module_name, ' SmMin = %f', d = (/ SmMin /) ) call MessageNotify( 'M', module_name, ' VelDiffCoefMin = %f', d = (/ VelDiffCoefMin /) ) call MessageNotify( 'M', module_name, ' TempDiffCoefMin = %f', d = (/ TempDiffCoefMin /) ) call MessageNotify( 'M', module_name, ' VelDiffCoefMax = %f', d = (/ VelDiffCoefMax /) ) call MessageNotify( 'M', module_name, ' TempDiffCoefMax = %f', d = (/ TempDiffCoefMax /) ) call MessageNotify( 'M', module_name, ' MYConstA1 = %f', d = (/ MYConstA1 /) ) call MessageNotify( 'M', module_name, ' MYConstB1 = %f', d = (/ MYConstB1 /) ) call MessageNotify( 'M', module_name, ' MYConstA2 = %f', d = (/ MYConstA2 /) ) call MessageNotify( 'M', module_name, ' MYConstB2 = %f', d = (/ MYConstB2 /) ) call MessageNotify( 'M', module_name, ' MYConstC1 = %f', d = (/ MYConstC1 /) ) call MessageNotify( 'M', module_name, '-- version = %c', c1 = trim(version) ) vdiffusion_my_inited = .true. end subroutine VDiffusionInit
Subroutine : | |||
xyz_U(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyz_V(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) : | real(DP), intent(in)
| ||
xyz_Temp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Temp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_VirTemp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_VirTemp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_Press(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xy_SurfHeight(0:imax-1,1:jmax) : | real(DP), intent(in)
| ||
xyz_Height(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Height(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_Exner(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Exner(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_TurKinEne(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xy_SurfMomFluxX(0:imax-1, 1:jmax) : | real(DP), intent(in)
| ||
xy_SurfMomFluxY(0:imax-1, 1:jmax) : | real(DP), intent(in)
| ||
xyr_MomFluxX(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_MomFluxY(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_HeatFlux(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) : | real(DP), intent(out)
| ||
xyr_VelDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_TempDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_QMixDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyz_DTurKinEneDt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(out)
|
鉛直拡散フラックスを計算します.
Vertical diffusion flux is calculated by use of MY2.5 model.
subroutine VDiffusionMY25( xyz_U, xyz_V, xyzf_QMix, xyz_Temp, xyr_Temp, xyz_VirTemp, xyr_VirTemp, xyr_Press, xy_SurfHeight, xyz_Height, xyr_Height, xyz_Exner, xyr_Exner, xyz_TurKinEne, xy_SurfMomFluxX, xy_SurfMomFluxY, xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef, xyz_DTurKinEneDt ) ! ! 鉛直拡散フラックスを計算します. ! ! Vertical diffusion flux is calculated by use of MY2.5 model. ! ! モジュール引用 ; USE statements ! ! 物理定数設定 ! Physical constants settings ! use constants, only: FKarm, Grav, GasRDry, CpDry ! $ C_p $ [J kg-1 K-1]. ! 乾燥大気の定圧比熱. ! Specific heat of air at constant pressure ! 時刻管理 ! Time control ! use timeset, only: DelTime, TimeN, TimesetClockStart, TimesetClockStop ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoPut ! MPI 関連ルーチン ! MPI related routines ! use mpi_wrapper, only : MPIWrapperChkTrue ! 陰解法による時間積分のためのルーチン ! Routines for time integration with implicit scheme ! use phy_implicit_utils, only : PhyImplLUDecomp3, PhyImplLUSolve3 ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in):: xyz_U (0:imax-1, 1:jmax, 1:kmax) ! $ u $ . 東西風速. Eastward wind real(DP), intent(in):: xyz_V (0:imax-1, 1:jmax, 1:kmax) ! $ v $ . 南北風速. Northward wind real(DP), intent(in):: xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) ! $ q $ . 質量混合比. Mass mixing ratio real(DP), intent(in):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax) ! $ T $ . 温度. Temperature real(DP), intent(in):: xyr_Temp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T} $ . 温度 (半整数レベル). ! Temperature (half level) real(DP), intent(in):: xyz_VirTemp (0:imax-1, 1:jmax, 1:kmax) ! $ T_v $ . 仮温度. Virtual temperature real(DP), intent(in):: xyr_VirTemp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T}_v $ . 仮温度 (半整数レベル). ! Virtual temperature (half level) real(DP), intent(in):: xyr_Press (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{p} $ . 気圧 (半整数レベル). ! Air pressure (half level) real(DP), intent(in):: xy_SurfHeight (0:imax-1,1:jmax) ! $ z_s $ . 地表面高度. ! Surface height. real(DP), intent(in):: xyz_Height (0:imax-1, 1:jmax, 1:kmax) ! 高度 (整数レベル). ! Height (full level) real(DP), intent(in):: xyr_Height (0:imax-1, 1:jmax, 0:kmax) ! 高度 (半整数レベル). ! Height (half level) real(DP), intent(in):: xyz_Exner (0:imax-1, 1:jmax, 1:kmax) ! Exner 関数 (整数レベル). ! Exner function (full level) real(DP), intent(in):: xyr_Exner (0:imax-1, 1:jmax, 0:kmax) ! Exner 関数 (半整数レベル). ! Exner function (half level) real(DP), intent(in):: xyz_TurKinEne(0:imax-1, 1:jmax, 1:kmax) ! ! Turbulent kinetic energy (m2 s-2) real(DP), intent(in):: xy_SurfMomFluxX (0:imax-1, 1:jmax) ! ! Eastward momentum flux at surface real(DP), intent(in):: xy_SurfMomFluxY (0:imax-1, 1:jmax) ! ! Northward momentum flux at surface real(DP), intent(out):: xyr_MomFluxX (0:imax-1, 1:jmax, 0:kmax) ! 東西方向運動量フラックス. ! Eastward momentum flux real(DP), intent(out):: xyr_MomFluxY (0:imax-1, 1:jmax, 0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP), intent(out):: xyr_HeatFlux (0:imax-1, 1:jmax, 0:kmax) ! 熱フラックス. ! Heat flux real(DP), intent(out):: xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) ! 質量フラックス. ! Mass flux of compositions real(DP), intent(out):: xyr_VelDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP), intent(out):: xyr_TempDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:温度. ! Diffusion coefficient: temperature real(DP), intent(out):: xyr_QMixDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:比湿. ! Diffusion coefficient: specific humidity real(DP), intent(out):: xyz_DTurKinEneDt (0:imax-1, 1:jmax, 1:kmax) ! ! Tendency of turbulent kinetic energy ! 作業変数 ! Work variables ! real(DP) :: xyz_MixLength(0:imax-1, 1:jmax, 1:kmax) ! 混合距離. ! Mixing length real(DP) :: xyz_DVelDzSq(0:imax-1, 1:jmax, 1:kmax) ! ! Vertical shear squared (s-2) real(DP) :: xyz_StatStab(0:imax-1, 1:jmax, 1:kmax) ! ! Static stability (s-2) real(DP) :: GhMin ! ! Minimum of G_h real(DP) :: GhMax ! ! Maximum of G_h real(DP) :: xyz_Gm(0:imax-1, 1:jmax, 1:kmax) ! ! G_m real(DP) :: xyz_Gh(0:imax-1, 1:jmax, 1:kmax) ! ! G_h !!$ real(DP) :: xyz_SmHat(0:imax-1, 1:jmax, 1:kmax) !!$ ! !!$ ! \hat{S}_M !!$ real(DP) :: xyz_ShHat(0:imax-1, 1:jmax, 1:kmax) !!$ ! !!$ ! \hat{S}_h !!$ real(DP) :: xyz_DSmHatDTKE(0:imax-1, 1:jmax, 1:kmax) !!$ ! !!$ ! derivative of \hat{S}_M !!$ real(DP) :: xyz_DShHatDTKE(0:imax-1, 1:jmax, 1:kmax) !!$ ! !!$ ! derivative of \hat{S}_h real(DP) :: xyz_Sm(0:imax-1, 1:jmax, 1:kmax) ! ! S_M real(DP) :: xyz_Sh(0:imax-1, 1:jmax, 1:kmax) ! ! S_h real(DP), parameter :: Stke = 0.2_DP ! ! S_{TKE} = 0.2 real(DP) :: xyz_VelDiffCoef (0:imax-1, 1:jmax, 1:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP) :: xyz_TempDiffCoef (0:imax-1, 1:jmax, 1:kmax) ! 拡散係数:温度. ! Transfer coefficient: temperature real(DP) :: xyr_TurKinEneDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! ! Diffusion coefficient: turbulent kinetic energy real(DP) :: xyz_TurKinEneDiffCoef (0:imax-1, 1:jmax, 1:kmax) ! ! Diffusion coefficient: turbulent kinetic energy real(DP) :: xyr_TurKinEneTransCoef(0:imax-1, 1:jmax, 0:kmax) ! ! Transfer coefficient: turbulent kinetic energy real(DP) :: xyr_TurKinEneFlux(0:imax-1, 1:jmax, 0:kmax) ! ! Turbulent energy flux real(DP) :: xyz_CShe1(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_CShe2(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_CBuo1(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_CBuo2(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_CDis1(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_CDis2(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_TurKinEneProShear(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_TurKinEneProBuoya(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xy_FricVelSq (0:imax-1, 1:jmax) real(DP) :: xy_TurKinEneAtLB(0:imax-1, 1:jmax) real(DP) :: xyza_TurKinEneMtx(0:imax-1, 1:jmax, 1:kmax, -1:1) ! ! Implicit matrix for turbulent kinetic energy real(DP) :: xyz_TurKinEneVec(0:imax-1, 1:jmax, 1:kmax) ! ! Implicit vector for turbulent kinetic energy real(DP) :: xyza_TurKinEneLUMtx (0:imax-1, 1:jmax, 1:kmax, -1:1) ! LU 行列. ! LU matrix real(DP) :: xyz_DelTurKinEneLUVec(0:imax-1, 1:jmax, 1:kmax) ! ! Tendency of turbulent kinetic energy real(DP) :: xyz_TurKinEneDiss(0:imax-1, 1:jmax, 1:kmax) ! ! Dissipation rate of turbulent kinetic energy (m2 s-3) real(DP) :: xyz_TurKinEneNonZero(0:imax-1, 1:jmax, 1:kmax) ! ! Turbulent kinetic energy with offset (m2 s-2) real(DP), parameter :: TurKinEneOffset = ( 1.0e-3_DP )**2 / 2.0_DP logical :: FlagReCalc ! ! Flag for recalculation logical :: a_FlagReCalcLocal (1) logical :: a_FlagReCalcGlobal(1) integer :: iloop integer :: nloop 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:: n ! 組成方向に回る DO ループ用作業変数 ! Work variables for DO loop in dimension of constituents ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if ! 計算時間計測開始 ! Start measurement of computation time ! call TimesetClockStart( module_name ) ! Calculate turbulent kinetic energy with offset ! xyz_TurKinEneNonZero = xyz_TurKinEne + TurKinEneOffset ! ! Calculation of vertical shear squared do k = 1, kmax if ( k == 1 ) then xyz_DVelDzSq(:,:,k) = ( ( xyz_U(:,:,k+1) - xyz_U(:,:,k ) )**2 + ( xyz_V(:,:,k+1) - xyz_V(:,:,k ) )**2 ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k ) )**2 !!$ xyz_DVelDzSq(:,:,k) = & !!$ & ( ( xyz_U(:,:,k+1) - 0.0_DP )**2 & !!$ & + ( xyz_V(:,:,k+1) - 0.0_DP )**2 ) & !!$ & / ( xyz_Height(:,:,k+1) - xy_SurfHeight )**2 else if ( k == kmax ) then xyz_DVelDzSq(:,:,k) = ( ( xyz_U(:,:,k ) - xyz_U(:,:,k-1) )**2 + ( xyz_V(:,:,k ) - xyz_V(:,:,k-1) )**2 ) / ( xyz_Height(:,:,k ) - xyz_Height(:,:,k-1) )**2 else xyz_DVelDzSq(:,:,k) = ( ( xyz_U(:,:,k+1) - xyz_U(:,:,k-1) )**2 + ( xyz_V(:,:,k+1) - xyz_V(:,:,k-1) )**2 ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k-1) )**2 end if end do ! Calculation of static stability do k = 1, kmax if ( k == 1 ) then xyz_StatStab(:,:,k) = Grav / ( xyz_VirTemp(:,:,k) / xyz_Exner(:,:,k) ) * ( xyz_VirTemp(:,:,k+1) / xyz_Exner(:,:,k+1) - xyz_VirTemp(:,:,k ) / xyz_Exner(:,:,k ) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k ) ) else if ( k == kmax ) then xyz_StatStab(:,:,k) = Grav / ( xyz_VirTemp(:,:,k) / xyz_Exner(:,:,k) ) * ( xyz_VirTemp(:,:,k ) / xyz_Exner(:,:,k ) - xyz_VirTemp(:,:,k-1) / xyz_Exner(:,:,k-1) ) / ( xyz_Height(:,:,k ) - xyz_Height(:,:,k-1) ) else xyz_StatStab(:,:,k) = Grav / ( xyz_VirTemp(:,:,k) / xyz_Exner(:,:,k) ) * ( xyz_VirTemp(:,:,k+1) / xyz_Exner(:,:,k+1) - xyz_VirTemp(:,:,k-1) / xyz_Exner(:,:,k-1) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k-1) ) end if end do ! 混合距離の算出 ! Calculate mixing length ! do k = 1, kmax xyz_MixLength(:,:,k) = FKarm * ( xyz_Height(:,:,k) - xy_SurfHeight ) / (1.0_DP + FKarm * ( xyz_Height(:,:,k) - xy_SurfHeight ) / MixLengthMax ) end do ! Limit mixing length (Galperin et al., 1988) and avoid zero xyz_MixLength = min( xyz_MixLength, 0.53_DP * sqrt( 2.0_DP * xyz_TurKinEneNonZero / max( xyz_StatStab, 1.0e-10_DP ) ) ) + 1.0e-10_DP xyz_Gh = - xyz_MixLength**2 / ( 2.0_DP * xyz_TurKinEneNonZero ) * xyz_StatStab ! Actually, xyz_Gm is not used below. xyz_Gm = xyz_MixLength**2 / ( 2.0_DP * xyz_TurKinEneNonZero ) * xyz_DVelDzSq ! Limit Gh (Galperin et al., 1988) GhMin = - 0.53_DP**2 GhMax = 1.0_DP / ( MYConstA2 * ( 12.0_DP * MYConstA1 + MYConstB1 + 3.0_DP * MYConstB2 ) ) xyz_Gh = max( GhMin, min( xyz_Gh, GhMax ) ) xyz_Sh = MYConstA2 * ( 1.0_DP - 6.0_DP * MYConstA1 / MYConstB1 ) / ( 1.0_DP - 3.0_DP * MYConstA2 * ( 6.0_DP * MYConstA1 + MYConstB2 ) * xyz_Gh ) xyz_Sm = ( MYConstA1 * ( 1.0_DP - 3.0_DP * MYConstC1 - 6.0_DP * MYConstA1 / MYConstB1 ) + 9.0_DP * MYConstA1 * ( 2.0_DP * MYConstA1 + MYConstA2 ) * xyz_Gh * xyz_Sh ) / ( 1.0_DP - 9.0_DP * MYConstA1 * MYConstA2 * xyz_Gh ) !!$ xyz_DShHatDTKE = & !!$ & - 2.0_DP * MYConstA2 * ( 1.0_DP - 6.0_DP * MYConstA1 / MYConstB1 ) & !!$ & / ( 2.0_DP * xyz_TurKinEneNonZero & !!$ & - 3.0_DP * MYConstA2 * ( 6.0_DP * MYConstA1 + MYConstB2 ) * xyz_GhPrime )**2 !!$ xyz_DSmHatDTKE = & !!$ & ( & !!$ & 9.0_DP * MYConstA1 * ( 2.0_DP * MYConstA1 + MYConstA2 ) & !!$ & * xyz_GhPrime * xyz_DShHatDTKE & !!$ & * ( 2.0_DP * xyz_TurKinEneNonZero & !!$ & - 9.0_DP * MYConstA1 * MYConstA2 * xyz_GhPrime ) & !!$ & - 2.0_DP & !!$ & * ( & !!$ & MYConstA1 * ( 1.0_DP - 3.0_DP * MYConstC1 & !!$ & - 6.0_DP * MYConstA1 / MYConstB1 ) & !!$ & + 9.0_DP * MYConstA1 * ( 2.0_DP * MYConstA1 + MYConstA2 ) & !!$ & * xyz_GhPrime * xyz_ShHat & !!$ & ) & !!$ & ) & !!$ & / ( 2.0_DP * xyz_TurKinEneNonZero & !!$ & - 9.0_DP * MYConstA1 * MYConstA2 * xyz_GhPrime )**2 ! 拡散係数の計算 ! Calculation of diffusion coefficient ! xyz_VelDiffCoef = xyz_MixLength * sqrt( 2.0_DP * xyz_TurKinEneNonZero ) * xyz_Sm xyz_TempDiffCoef = xyz_MixLength * sqrt( 2.0_DP * xyz_TurKinEneNonZero ) * xyz_Sh ! do k = 0, kmax if ( ( k == 0 ) .or. ( k == kmax ) ) then xyr_VelDiffCoef (:,:,k) = 0.0_DP xyr_TempDiffCoef(:,:,k) = 0.0_DP else xyr_VelDiffCoef (:,:,k) = ( xyz_VelDiffCoef (:,:,k) + xyz_VelDiffCoef (:,:,k+1) ) / 2.0_DP xyr_TempDiffCoef(:,:,k) = ( xyz_TempDiffCoef(:,:,k) + xyz_TempDiffCoef(:,:,k+1) ) / 2.0_DP end if end do ! do k = 1, kmax-1 do j = 1, jmax do i = 0, imax-1 xyr_VelDiffCoef(i,j,k) = max( min( xyr_VelDiffCoef(i,j,k), VelDiffCoefMax ), VelDiffCoefMin ) xyr_TempDiffCoef(i,j,k) = max( min( xyr_TempDiffCoef(i,j,k), TempDiffCoefMax ), TempDiffCoefMin ) end do end do end do ! xyr_QMixDiffCoef = xyr_TempDiffCoef ! 輸送係数とフラックスの計算 ! Calculate transfer coefficient and flux ! call VDiffusionCalcFlux( xyz_U, xyz_V, xyzf_QMix, xyz_Temp, xyr_VirTemp, xyr_Press, xyz_Height, xyz_Exner, xyr_Exner, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef, xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux ) ! Calculate tendency of turbulent kinetic energy ! Set diffusion coefficient for turbulent kinetic energy xyz_TurKinEneDiffCoef = xyz_MixLength * sqrt( 2.0_DP * xyz_TurKinEneNonZero ) * Stke ! do k = 0, kmax if ( k == 0 ) then xyr_TurKinEneDiffCoef(:,:,k) = xyz_TurKinEneDiffCoef(:,:,1) else if ( k == kmax ) then xyr_TurKinEneDiffCoef(:,:,k) = xyz_TurKinEneDiffCoef(:,:,kmax) else xyr_TurKinEneDiffCoef(:,:,k) = ( xyz_TurKinEneDiffCoef(:,:,k) + xyz_TurKinEneDiffCoef(:,:,k+1) ) / 2.0_DP end if end do ! Calculate turbulent kinetic energy at lower boundary ! xy_FricVelSq = sqrt( xy_SurfMomFluxX**2 + xy_SurfMomFluxY**2 ) / ( xyr_Press(:,:,0) / ( GasRDry * xyr_VirTemp(:,:,0) ) ) xy_TurKinEneAtLB = MYConstB1**(2.0_DP/3.0_DP) / 2.0_DP * xy_FricVelSq xy_TurKinEneAtLB = xy_TurKinEneAtLB + TurKinEneOffset ! Calculate transfer coefficient and flux of turbulent kinetic energy ! ! When transfer coefficient at lower boundary is calculated, ! diffusion coefficient at mid-point of 1st layer is used. ! In addition, transfer coefficient at upper boundary is assumed ! to be zero. k = 0 xyr_TurKinEneTransCoef(:,:,k) = xyz_TurKinEneDiffCoef(:,:,1) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,1) - xy_SurfHeight ) do k = 1, kmax-1 xyr_TurKinEneTransCoef(:,:,k) = xyr_TurKinEneDiffCoef(:,:,k) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) end do k = kmax xyr_TurKinEneTransCoef(:,:,k) = 0.0_DP ! do k = 1, kmax-1 xyr_TurKinEneFlux(:,:,k) = - xyr_TurKinEneTransCoef(:,:,k) * ( xyz_TurKinEneNonZero(:,:,k+1) - xyz_TurKinEneNonZero(:,:,k) ) end do k = 0 xyr_TurKinEneFlux(:,:,k) = - xyr_TurKinEneTransCoef(:,:,k) * ( xyz_TurKinEneNonZero(:,:,k+1) - xy_TurKinEneAtLB ) k = kmax xyr_TurKinEneFlux(:,:,k) = 0.0_DP !!$ xyz_CShe1 = 2.0d0**1.5 * xyz_MixLength * xyz_SmHat & !!$ & * xyz_DVelDzSq & !!$! & * xyz_TurKinEne**1.5 !!$ & * ( xyz_TurKinEne + TurKinEneNonZero )**1.5 !!$ xyz_CShe2 = 1.5_DP * 2.0d0**1.5 * xyz_MixLength * xyz_SmHat & !!$ & * xyz_DVelDzSq & !!$! & * xyz_TurKinEne**0.5 !!$ & * ( xyz_TurKinEne + TurKinEneNonZero )**0.5 !!$ xyz_CBuo1 = - 2.0d0**1.5 * xyz_MixLength * xyz_ShHat & !!$ & * xyz_StatStab & !!$! & * xyz_TurKinEne**1.5 !!$ & * ( xyz_TurKinEne + TurKinEneNonZero )**1.5 !!$ xyz_CBuo2 = - 1.5_DP * 2.0d0**1.5 * xyz_MixLength * xyz_ShHat & !!$ & * xyz_StatStab & !!$! & * xyz_TurKinEne**0.5 !!$ & * ( xyz_TurKinEne + TurKinEneNonZero )**0.5 !!$ xyz_CDis1 = 2.0_DP**1.5 / ( MYConstB1 * xyz_MixLength ) & !!$! & * xyz_TurKinEne**1.5 !!$ & * ( xyz_TurKinEne + TurKinEneNonZero )**1.5 !!$ xyz_CDis2 = 1.5_DP * 2.0_DP**1.5 / ( MYConstB1 * xyz_MixLength ) & !!$! & * xyz_TurKinEne**0.5 !!$ & * ( xyz_TurKinEne + TurKinEneNonZero )**0.5 !!$! xyz_CShe1 = 2.0d0**1.5 * xyz_MixLength * xyz_SmHat & !!$! & * xyz_DVelDzSq & !!$!! & * xyz_TurKinEne**1.5 !!$! & * ( xyz_TurKinEne + TurKinEneNonZero )**1.5 !!$ xyz_CShe1 = 2.0d0**1.5 * xyz_MixLength * xyz_Sm & !!$ & * xyz_DVelDzSq & !!$! & * xyz_TurKinEne**1.5 !!$ & * ( xyz_TurKinEne + TurKinEneNonZero )**0.5 !!$ xyz_CShe2 = 0.0_DP !!$! xyz_CBuo1 = - 2.0d0**1.5 * xyz_MixLength * xyz_ShHat & !!$! & * xyz_StatStab & !!$!! & * xyz_TurKinEne**1.5 !!$! & * ( xyz_TurKinEne + TurKinEneNonZero )**1.5 !!$ xyz_CBuo1 = - 2.0d0**1.5 * xyz_MixLength * xyz_Sh & !!$ & * xyz_StatStab & !!$! & * xyz_TurKinEne**1.5 !!$ & * ( xyz_TurKinEne + TurKinEneNonZero )**0.5 !!$ xyz_CBuo2 = 0.0_DP !!$ xyz_CDis1 = 2.0_DP**1.5 / ( MYConstB1 * xyz_MixLength ) & !!$ & * xyz_TurKinEne**1.5 !!$! & * ( xyz_TurKinEne + TurKinEneNonZero )**1.5 !!$ xyz_CDis2 = 1.5_DP * 2.0_DP**1.5 / ( MYConstB1 * xyz_MixLength ) & !!$ & * xyz_TurKinEne**0.5 !!$! & * ( xyz_TurKinEne + TurKinEneNonZero )**0.5 !!$ xyz_CShe1 = 2.0d0**1.5 * xyz_MixLength * xyz_DVelDzSq & !!$ & * xyz_SmHat & !!$ & * xyz_TurKinEneNonZero**1.5 !!$ xyz_CShe2 = 2.0d0**1.5 * xyz_MixLength * xyz_DVelDzSq & !!$ & * ( xyz_DSmHatDTKE & !!$ & * xyz_TurKinEneNonZero**1.5 & !!$ & + 1.5_DP * xyz_SmHat & !!$ & * xyz_TurKinEneNonZero**0.5 & !!$ & ) !!$ xyz_CBuo1 = - 2.0d0**1.5 * xyz_MixLength * xyz_StatStab & !!$ & * xyz_ShHat & !!$ & * xyz_TurKinEneNonZero**1.5 !!$ xyz_CBuo2 = - 2.0d0**1.5 * xyz_MixLength * xyz_StatStab & !!$ & * ( xyz_DShHatDTKE & !!$ & * xyz_TurKinEneNonZero**1.5 & !!$ & + 1.5_DP * xyz_ShHat & !!$ & * xyz_TurKinEneNonZero**0.5 & !!$ & ) !!$ xyz_CDis1 = 2.0_DP**1.5 / ( MYConstB1 * xyz_MixLength ) & !!$ & * xyz_TurKinEneNonZero**1.5 !!$ xyz_CDis2 = 1.5_DP * 2.0_DP**1.5 / ( MYConstB1 * xyz_MixLength ) & !!$ & * xyz_TurKinEneNonZero**0.5 xyz_CShe1 = sqrt( 2.0_DP ) * xyz_MixLength * xyz_DVelDzSq * xyz_Sm * sqrt( xyz_TurKinEneNonZero ) !!$ xyz_CShe2 = 0.5_DP * sqrt( 2.0_DP ) * xyz_MixLength * xyz_DVelDzSq & !!$ & * xyz_Sm & !!$ & / sqrt( xyz_TurKinEneNonZero ) xyz_CShe2 = 0.0_DP xyz_CBuo1 = - sqrt( 2.0_DP ) * xyz_MixLength * xyz_StatStab * xyz_Sh * sqrt( xyz_TurKinEneNonZero ) !!$ xyz_CBuo2 = - 0.5_DP * sqrt( 2.0_DP ) * xyz_MixLength * xyz_StatStab & !!$ & * xyz_Sh & !!$ & / sqrt( xyz_TurKinEneNonZero ) xyz_CBuo2 = 0.0_DP xyz_CDis1 = 2.0_DP**1.5_DP / ( MYConstB1 * xyz_MixLength ) * xyz_TurKinEneNonZero**1.5_DP xyz_CDis2 = 1.5_DP * 2.0_DP**1.5_DP / ( MYConstB1 * xyz_MixLength ) * xyz_TurKinEneNonZero**0.5_DP nloop = kmax loop_solve : do iloop = 1, nloop ! ! Construct implicit matrix from transfer coefficient of vertical ! diffusion scheme (turbulent kinetic energy) ! k = 1 xyza_TurKinEneMtx(:,:,k,-1) = 0.0_DP xyza_TurKinEneMtx(:,:,k, 0) = - ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav / ( 2.0_DP * DelTime ) + xyr_TurKinEneTransCoef(:,:,k-1) + xyr_TurKinEneTransCoef(:,:,k ) + ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav * ( xyz_CShe2(:,:,k) + xyz_CBuo2(:,:,k) - xyz_CDis2(:,:,k) ) xyza_TurKinEneMtx(:,:,k, 1) = - xyr_TurKinEneTransCoef(:,:,k ) ! do k = 2, kmax-1 xyza_TurKinEneMtx(:,:,k,-1) = - xyr_TurKinEneTransCoef(:,:,k-1) xyza_TurKinEneMtx(:,:,k, 0) = - ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav / ( 2.0_DP * DelTime ) + xyr_TurKinEneTransCoef(:,:,k-1) + xyr_TurKinEneTransCoef(:,:,k ) + ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav * ( xyz_CShe2(:,:,k) + xyz_CBuo2(:,:,k) - xyz_CDis2(:,:,k) ) xyza_TurKinEneMtx(:,:,k, 1) = - xyr_TurKinEneTransCoef(:,:,k ) end do ! k = kmax xyza_TurKinEneMtx(:,:,k,-1) = - xyr_TurKinEneTransCoef(:,:,k-1) xyza_TurKinEneMtx(:,:,k, 0) = - ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav / ( 2.0_DP * DelTime ) + xyr_TurKinEneTransCoef(:,:,k-1) + xyr_TurKinEneTransCoef(:,:,k ) + ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav * ( xyz_CShe2(:,:,k) + xyz_CBuo2(:,:,k) - xyz_CDis2(:,:,k) ) xyza_TurKinEneMtx(:,:,k, 1) = 0.0_DP do k = 1, kmax xyz_TurKinEneVec(:,:,k) = - ( xyr_TurKinEneFlux(:,:,k) - xyr_TurKinEneFlux(:,:,k-1) ) - ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav * ( xyz_CShe1(:,:,k) + xyz_CBuo1(:,:,k) - xyz_CDis1(:,:,k) ) end do ! ! Solve simultaneous linear equations by use of LU decomposition technique ! xyza_TurKinEneLUMtx = xyza_TurKinEneMtx ! call PhyImplLUDecomp3( xyza_TurKinEneLUMtx, imax * jmax, kmax ) xyz_DelTurKinEneLUVec = xyz_TurKinEneVec ! call PhyImplLUSolve3( xyz_DelTurKinEneLUVec, xyza_TurKinEneLUMtx, 1, imax * jmax , kmax ) xyz_DTurKinEneDt = xyz_DelTurKinEneLUVec / ( 2.0_DP * DelTime ) ! Calculation of dissipation rate of turbulent kinetic energy ! ! Calculate production rate of turbulent kinetic energy ! by shear and buoyancy xyz_TurKinEneProShear = xyz_CShe1 + xyz_CShe2 * xyz_DTurKinEneDt * 2.0_DP * DelTime xyz_TurKinEneProBuoya = xyz_CBuo1 + xyz_CBuo2 * xyz_DTurKinEneDt * 2.0_DP * DelTime xyz_TurKinEneDiss = xyz_CDis1 + xyz_CDis2 * xyz_DTurKinEneDt * 2.0_DP * DelTime ! Check of turbulent kinetic energy dissipation rate ! If it is negative, tendency is recalculated without dissipation. ! FlagReCalc = .false. do k = 1, kmax do j = 1, jmax do i = 0, imax-1 if ( xyz_TurKinEneDiss(i,j,k) < 0.0_DP ) then xyz_CDis1(i,j,k) = 0.0_DP xyz_CDis2(i,j,k) = 0.0_DP FlagReCalc = .true. end if end do end do end do ! Check convergence a_FlagReCalcLocal = FlagReCalc call MPIWrapperChkTrue( 1, a_FlagReCalcLocal, a_FlagReCalcGlobal ) if ( .not. a_FlagReCalcGlobal(1) ) exit loop_solve end do loop_solve !!$ write( 6, * ) TimeN, iloop !!$ write( 6, * ) xyz_TurKinEne(0,jmax/2+1,1:4) !!$ write( 6, * ) xyz_TempDiffCoef(0,jmax/2+1,1:4) !!$ write( 6, * ) xyz_TurKinEneProShear(0,jmax/2+1,1:4) !!$ write( 6, * ) xyz_TurKinEneProBuoya(0,jmax/2+1,1:4) !!$ write( 6, * ) xyz_TurKinEneDiss(0,jmax/2+1,1:4) !!$ write( 6, * ) xyz_DTurKinEneDt(0,jmax/2+1,1:4) ! 拡散係数の出力 ! Output diffusion coefficients ! ! 拡散係数出力 ! Diffusion coeffficients output ! call HistoryAutoPut( TimeN, 'VelDiffCoef', xyr_VelDiffCoef ) call HistoryAutoPut( TimeN, 'TempDiffCoef', xyr_TempDiffCoef ) call HistoryAutoPut( TimeN, 'QVapDiffCoef', xyr_QMixDiffCoef ) call HistoryAutoPut( TimeN, 'TKEPShear', xyz_TurKinEneProShear ) call HistoryAutoPut( TimeN, 'TKEPBuoy' , xyz_TurKinEneProBuoya ) call HistoryAutoPut( TimeN, 'TKEDiss' , xyz_TurKinEneDiss ) call HistoryAutoPut( TimeN, 'MixLength' , xyz_MixLength ) ! 計算時間計測一時停止 ! Pause measurement of computation time ! call TimesetClockStop( module_name ) end subroutine VDiffusionMY25
Subroutine : | |||
xyz_U(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyz_V(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) : | real(DP), intent(in)
| ||
xyz_Temp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Temp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_VirTemp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_VirTemp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_Press(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xy_SurfHeight(0:imax-1,1:jmax) : | real(DP), intent(in)
| ||
xyz_Height(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Height(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_Exner(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Exner(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_TurKinEne(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xy_SurfMomFluxX(0:imax-1, 1:jmax) : | real(DP), intent(in)
| ||
xy_SurfMomFluxY(0:imax-1, 1:jmax) : | real(DP), intent(in)
| ||
xyr_MomFluxX(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_MomFluxY(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_HeatFlux(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) : | real(DP), intent(out)
| ||
xyr_VelDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_TempDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_QMixDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyz_DTurKinEneDt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(out)
|
鉛直拡散フラックスを計算します.
Vertical diffusion flux is calculated by use of MY2.5 model.
subroutine VDiffusionMY251DWrapper3D( xyz_U, xyz_V, xyzf_QMix, xyz_Temp, xyr_Temp, xyz_VirTemp, xyr_VirTemp, xyr_Press, xy_SurfHeight, xyz_Height, xyr_Height, xyz_Exner, xyr_Exner, xyz_TurKinEne, xy_SurfMomFluxX, xy_SurfMomFluxY, xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef, xyz_DTurKinEneDt ) ! ! 鉛直拡散フラックスを計算します. ! ! Vertical diffusion flux is calculated by use of MY2.5 model. ! ! モジュール引用 ; USE statements ! ! 物理定数設定 ! Physical constants settings ! use constants, only: FKarm, Grav, GasRDry, CpDry ! $ C_p $ [J kg-1 K-1]. ! 乾燥大気の定圧比熱. ! Specific heat of air at constant pressure ! 時刻管理 ! Time control ! use timeset, only: DelTime, TimeN, TimesetClockStart, TimesetClockStop ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoPut ! 陰解法による時間積分のためのルーチン ! Routines for time integration with implicit scheme ! use phy_implicit_utils, only : PhyImplLUDecomp3, PhyImplLUSolve3 ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in):: xyz_U (0:imax-1, 1:jmax, 1:kmax) ! $ u $ . 東西風速. Eastward wind real(DP), intent(in):: xyz_V (0:imax-1, 1:jmax, 1:kmax) ! $ v $ . 南北風速. Northward wind real(DP), intent(in):: xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) ! $ q $ . 質量混合比. Mass mixing ratio real(DP), intent(in):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax) ! $ T $ . 温度. Temperature real(DP), intent(in):: xyr_Temp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T} $ . 温度 (半整数レベル). ! Temperature (half level) real(DP), intent(in):: xyz_VirTemp (0:imax-1, 1:jmax, 1:kmax) ! $ T_v $ . 仮温度. Virtual temperature real(DP), intent(in):: xyr_VirTemp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T}_v $ . 仮温度 (半整数レベル). ! Virtual temperature (half level) real(DP), intent(in):: xyr_Press (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{p} $ . 気圧 (半整数レベル). ! Air pressure (half level) real(DP), intent(in):: xy_SurfHeight (0:imax-1,1:jmax) ! $ z_s $ . 地表面高度. ! Surface height. real(DP), intent(in):: xyz_Height (0:imax-1, 1:jmax, 1:kmax) ! 高度 (整数レベル). ! Height (full level) real(DP), intent(in):: xyr_Height (0:imax-1, 1:jmax, 0:kmax) ! 高度 (半整数レベル). ! Height (half level) real(DP), intent(in):: xyz_Exner (0:imax-1, 1:jmax, 1:kmax) ! Exner 関数 (整数レベル). ! Exner function (full level) real(DP), intent(in):: xyr_Exner (0:imax-1, 1:jmax, 0:kmax) ! Exner 関数 (半整数レベル). ! Exner function (half level) real(DP), intent(in):: xyz_TurKinEne(0:imax-1, 1:jmax, 1:kmax) ! ! Turbulent kinetic energy (m2 s-2) real(DP), intent(in):: xy_SurfMomFluxX (0:imax-1, 1:jmax) ! ! Eastward momentum flux at surface real(DP), intent(in):: xy_SurfMomFluxY (0:imax-1, 1:jmax) ! ! Northward momentum flux at surface real(DP), intent(out):: xyr_MomFluxX (0:imax-1, 1:jmax, 0:kmax) ! 東西方向運動量フラックス. ! Eastward momentum flux real(DP), intent(out):: xyr_MomFluxY (0:imax-1, 1:jmax, 0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP), intent(out):: xyr_HeatFlux (0:imax-1, 1:jmax, 0:kmax) ! 熱フラックス. ! Heat flux real(DP), intent(out):: xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) ! 質量フラックス. ! Mass flux of compositions real(DP), intent(out):: xyr_VelDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP), intent(out):: xyr_TempDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:温度. ! Diffusion coefficient: temperature real(DP), intent(out):: xyr_QMixDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:比湿. ! Diffusion coefficient: specific humidity real(DP), intent(out):: xyz_DTurKinEneDt (0:imax-1, 1:jmax, 1:kmax) ! ! Tendency of turbulent kinetic energy ! 作業変数 ! Work variables ! real(DP) :: z_U (1:kmax) real(DP) :: z_V (1:kmax) real(DP) :: zf_QMix(1:kmax, 1:ncmax) real(DP) :: z_Temp (1:kmax) real(DP) :: r_Temp (0:kmax) real(DP) :: z_VirTemp (1:kmax) real(DP) :: r_VirTemp (0:kmax) real(DP) :: r_Press (0:kmax) real(DP) :: SurfHeight real(DP) :: z_Height (1:kmax) real(DP) :: r_Height (0:kmax) real(DP) :: z_Exner (1:kmax) real(DP) :: r_Exner (0:kmax) real(DP) :: z_TurKinEne(1:kmax) real(DP) :: SurfMomFluxX real(DP) :: SurfMomFluxY real(DP) :: r_MomFluxX (0:kmax) real(DP) :: r_MomFluxY (0:kmax) real(DP) :: r_HeatFlux (0:kmax) real(DP) :: rf_QMixFlux(0:kmax, 1:ncmax) real(DP) :: r_VelDiffCoef (0:kmax) real(DP) :: r_TempDiffCoef(0:kmax) real(DP) :: r_QMixDiffCoef(0:kmax) real(DP) :: z_DTurKinEneDt (1:kmax) ! ! Tendency of turbulent kinetic energy integer:: i ! 経度方向に回る DO ループ用作業変数 ! Work variables for DO loop in longitude integer:: j ! 緯度方向に回る DO ループ用作業変数 ! Work variables for DO loop in latitude ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if ! 計算時間計測開始 ! Start measurement of computation time ! call TimesetClockStart( module_name ) do j = 1, jmax do i = 0, imax-1 z_U = xyz_U (i,j,:) z_V = xyz_V (i,j,:) zf_QMix = xyzf_QMix (i,j,:,:) z_Temp = xyz_Temp (i,j,:) r_Temp = xyr_Temp (i,j,:) z_VirTemp = xyz_VirTemp (i,j,:) r_VirTemp = xyr_VirTemp (i,j,:) r_Press = xyr_Press (i,j,:) SurfHeight = xy_SurfHeight (i,j) z_Height = xyz_Height (i,j,:) r_Height = xyr_Height (i,j,:) z_Exner = xyz_Exner (i,j,:) r_Exner = xyr_Exner (i,j,:) z_TurKinEne = xyz_TurKinEne (i,j,:) SurfMomFluxX = xy_SurfMomFluxX(i,j) SurfMomFluxY = xy_SurfMomFluxY(i,j) call VDiffusionMY251D( z_U, z_V, zf_QMix, z_Temp, r_Temp, z_VirTemp, r_VirTemp, r_Press, SurfHeight, z_Height, r_Height, z_Exner, r_Exner, z_TurKinEne, SurfMomFluxX, SurfMomFluxY, r_MomFluxX, r_MomFluxY, r_HeatFlux, rf_QMixFlux, r_VelDiffCoef, r_TempDiffCoef, r_QMixDiffCoef, z_DTurKinEneDt ) xyr_MomFluxX (i,j,:) = r_MomFluxX xyr_MomFluxY (i,j,:) = r_MomFluxY xyr_HeatFlux (i,j,:) = r_HeatFlux xyrf_QMixFlux (i,j,:,:) = rf_QMixFlux xyr_VelDiffCoef (i,j,:) = r_VelDiffCoef xyr_TempDiffCoef(i,j,:) = r_TempDiffCoef xyr_QMixDiffCoef(i,j,:) = r_QMixDiffCoef xyz_DTurKinEneDt (i,j,:) = z_DTurKinEneDt end do end do !!$ ! 拡散係数の出力 !!$ ! Output diffusion coefficients !!$ ! !!$ !!$ ! 拡散係数出力 !!$ ! Diffusion coeffficients output !!$ ! !!$ call HistoryAutoPut( TimeN, 'VelDiffCoef', xyr_VelDiffCoef ) !!$ call HistoryAutoPut( TimeN, 'TempDiffCoef', xyr_TempDiffCoef ) !!$ call HistoryAutoPut( TimeN, 'QVapDiffCoef', xyr_QMixDiffCoef ) !!$ !!$ call HistoryAutoPut( TimeN, 'TKEPShear', xyz_TurKinEneProShear ) !!$ call HistoryAutoPut( TimeN, 'TKEPBuoy' , xyz_TurKinEneProBuoya ) !!$ call HistoryAutoPut( TimeN, 'TKEDiss' , xyz_TurKinEneDiss ) !!$ !!$ call HistoryAutoPut( TimeN, 'MixLength' , xyz_MixLength ) ! 計算時間計測一時停止 ! Pause measurement of computation time ! call TimesetClockStop( module_name ) end subroutine VDiffusionMY251DWrapper3D
Subroutine : | |||
xyz_U(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyz_V(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) : | real(DP), intent(in)
| ||
xyz_Temp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Temp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_VirTemp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_VirTemp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_Press(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xy_SurfHeight(0:imax-1,1:jmax) : | real(DP), intent(in)
| ||
xyz_Height(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Height(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_Exner(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Exner(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_TurKinEne(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xy_SurfMomFluxX(0:imax-1, 1:jmax) : | real(DP), intent(in)
| ||
xy_SurfMomFluxY(0:imax-1, 1:jmax) : | real(DP), intent(in)
| ||
xyr_MomFluxX(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_MomFluxY(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_HeatFlux(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) : | real(DP), intent(out)
| ||
xyr_VelDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_TempDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_QMixDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyz_DTurKinEneDt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(out)
|
鉛直拡散フラックスを計算します.
Vertical diffusion flux is calculated by use of MY2.5 model.
subroutine VDiffusionMY25GBT94( xyz_U, xyz_V, xyzf_QMix, xyz_Temp, xyr_Temp, xyz_VirTemp, xyr_VirTemp, xyr_Press, xy_SurfHeight, xyz_Height, xyr_Height, xyz_Exner, xyr_Exner, xyz_TurKinEne, xy_SurfMomFluxX, xy_SurfMomFluxY, xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef, xyz_DTurKinEneDt ) ! ! 鉛直拡散フラックスを計算します. ! ! Vertical diffusion flux is calculated by use of MY2.5 model. ! ! モジュール引用 ; USE statements ! ! 物理定数設定 ! Physical constants settings ! use constants, only: FKarm, Grav, GasRDry, CpDry ! $ C_p $ [J kg-1 K-1]. ! 乾燥大気の定圧比熱. ! Specific heat of air at constant pressure ! 時刻管理 ! Time control ! use timeset, only: DelTime, TimeN, TimesetClockStart, TimesetClockStop ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoPut ! MPI 関連ルーチン ! MPI related routines ! use mpi_wrapper, only : MPIWrapperChkTrue ! 陰解法による時間積分のためのルーチン ! Routines for time integration with implicit scheme ! use phy_implicit_utils, only : PhyImplLUDecomp3, PhyImplLUSolve3 ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in):: xyz_U (0:imax-1, 1:jmax, 1:kmax) ! $ u $ . 東西風速. Eastward wind real(DP), intent(in):: xyz_V (0:imax-1, 1:jmax, 1:kmax) ! $ v $ . 南北風速. Northward wind real(DP), intent(in):: xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) ! $ q $ . 質量混合比. Mass mixing ratio real(DP), intent(in):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax) ! $ T $ . 温度. Temperature real(DP), intent(in):: xyr_Temp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T} $ . 温度 (半整数レベル). ! Temperature (half level) real(DP), intent(in):: xyz_VirTemp (0:imax-1, 1:jmax, 1:kmax) ! $ T_v $ . 仮温度. Virtual temperature real(DP), intent(in):: xyr_VirTemp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T}_v $ . 仮温度 (半整数レベル). ! Virtual temperature (half level) real(DP), intent(in):: xyr_Press (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{p} $ . 気圧 (半整数レベル). ! Air pressure (half level) real(DP), intent(in):: xy_SurfHeight (0:imax-1,1:jmax) ! $ z_s $ . 地表面高度. ! Surface height. real(DP), intent(in):: xyz_Height (0:imax-1, 1:jmax, 1:kmax) ! 高度 (整数レベル). ! Height (full level) real(DP), intent(in):: xyr_Height (0:imax-1, 1:jmax, 0:kmax) ! 高度 (半整数レベル). ! Height (half level) real(DP), intent(in):: xyz_Exner (0:imax-1, 1:jmax, 1:kmax) ! Exner 関数 (整数レベル). ! Exner function (full level) real(DP), intent(in):: xyr_Exner (0:imax-1, 1:jmax, 0:kmax) ! Exner 関数 (半整数レベル). ! Exner function (half level) real(DP), intent(in):: xyz_TurKinEne(0:imax-1, 1:jmax, 1:kmax) ! ! Turbulent kinetic energy (m2 s-2) real(DP), intent(in):: xy_SurfMomFluxX (0:imax-1, 1:jmax) ! ! Eastward momentum flux at surface real(DP), intent(in):: xy_SurfMomFluxY (0:imax-1, 1:jmax) ! ! Northward momentum flux at surface real(DP), intent(out):: xyr_MomFluxX (0:imax-1, 1:jmax, 0:kmax) ! 東西方向運動量フラックス. ! Eastward momentum flux real(DP), intent(out):: xyr_MomFluxY (0:imax-1, 1:jmax, 0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP), intent(out):: xyr_HeatFlux (0:imax-1, 1:jmax, 0:kmax) ! 熱フラックス. ! Heat flux real(DP), intent(out):: xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) ! 質量フラックス. ! Mass flux of compositions real(DP), intent(out):: xyr_VelDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP), intent(out):: xyr_TempDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:温度. ! Diffusion coefficient: temperature real(DP), intent(out):: xyr_QMixDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:比湿. ! Diffusion coefficient: specific humidity real(DP), intent(out):: xyz_DTurKinEneDt (0:imax-1, 1:jmax, 1:kmax) ! ! Tendency of turbulent kinetic energy ! 作業変数 ! Work variables ! real(DP) :: xyz_MixLength(0:imax-1, 1:jmax, 1:kmax) ! 混合距離. ! Mixing length real(DP) :: xyz_DVelDzSq(0:imax-1, 1:jmax, 1:kmax) ! ! Vertical shear squared (s-2) real(DP) :: xyz_StatStab(0:imax-1, 1:jmax, 1:kmax) ! ! Static stability (s-2) !!$ real(DP) :: GhMin !!$ ! !!$ ! Minimum of G_h !!$ real(DP) :: GhMax !!$ ! !!$ ! Maximum of G_h real(DP) :: xyz_Gm(0:imax-1, 1:jmax, 1:kmax) ! ! G_m real(DP) :: xyz_Gh(0:imax-1, 1:jmax, 1:kmax) ! ! G_h !!$ real(DP) :: xyz_SmHat(0:imax-1, 1:jmax, 1:kmax) !!$ ! !!$ ! \hat{S}_M !!$ real(DP) :: xyz_ShHat(0:imax-1, 1:jmax, 1:kmax) !!$ ! !!$ ! \hat{S}_h !!$ real(DP) :: xyz_DSmHatDTKE(0:imax-1, 1:jmax, 1:kmax) !!$ ! !!$ ! derivative of \hat{S}_M !!$ real(DP) :: xyz_DShHatDTKE(0:imax-1, 1:jmax, 1:kmax) !!$ ! !!$ ! derivative of \hat{S}_h real(DP) :: xyz_Sm(0:imax-1, 1:jmax, 1:kmax) ! ! S_M real(DP) :: xyz_Sh(0:imax-1, 1:jmax, 1:kmax) ! ! S_h real(DP), parameter :: Stke = 0.2_DP ! ! S_{TKE} = 0.2 real(DP) :: xyz_VelDiffCoef (0:imax-1, 1:jmax, 1:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP) :: xyz_TempDiffCoef (0:imax-1, 1:jmax, 1:kmax) ! 拡散係数:温度. ! Transfer coefficient: temperature real(DP) :: xyr_TurKinEneDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! ! Diffusion coefficient: turbulent kinetic energy real(DP) :: xyz_TurKinEneDiffCoef (0:imax-1, 1:jmax, 1:kmax) ! ! Diffusion coefficient: turbulent kinetic energy real(DP) :: xyr_TurKinEneTransCoef(0:imax-1, 1:jmax, 0:kmax) ! ! Transfer coefficient: turbulent kinetic energy real(DP) :: xyr_TurKinEneFlux(0:imax-1, 1:jmax, 0:kmax) ! ! Turbulent energy flux real(DP) :: xy_FricVelSq (0:imax-1, 1:jmax) real(DP) :: xy_TurKinEneAtLB(0:imax-1, 1:jmax) real(DP) :: xyza_TurKinEneMtx(0:imax-1, 1:jmax, 1:kmax, -1:1) ! ! Implicit matrix for turbulent kinetic energy real(DP) :: xyz_TurKinEneVec(0:imax-1, 1:jmax, 1:kmax) ! ! Implicit vector for turbulent kinetic energy real(DP) :: xyza_TurKinEneLUMtx (0:imax-1, 1:jmax, 1:kmax, -1:1) ! LU 行列. ! LU matrix real(DP) :: xyz_DelTurKinEneLUVec(0:imax-1, 1:jmax, 1:kmax) ! ! Tendency of turbulent kinetic energy real(DP) :: xyz_TurKinEneDiss(0:imax-1, 1:jmax, 1:kmax) ! ! Dissipation rate of turbulent kinetic energy (m2 s-3) real(DP) :: xyz_TurKinEneNonZero(0:imax-1, 1:jmax, 1:kmax) ! ! Turbulent kinetic energy with offset (m2 s-2) real(DP), parameter :: TurKinEneOffset = ( 1.0e-3_DP )**2 / 2.0_DP logical :: xyz_FlagUseRiNum (0:imax-1, 1:jmax, 1:kmax) logical :: xyz_FlagTKEAsymptToZero(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_RiNum(0:imax-1, 1:jmax, 1:kmax) real(DP) :: Beta1 real(DP) :: Beta2 real(DP) :: Beta3 real(DP) :: Beta4 real(DP) :: MixLength real(DP) :: xyz_A1 (0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_A2 (0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_R1 (0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_R2 (0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_SqrtA1(0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_TKEInit (0:imax-1, 1:jmax, 1:kmax) ! ! Turbulent kinetic energy for current time step ! with offset (m2 s-2) real(DP) :: xyz_TKEx2 (0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_SqrtTKEx2 (0:imax-1, 1:jmax, 1:kmax) real(DP) :: xyz_TKETentative(0:imax-1, 1:jmax, 1:kmax) real(DP) :: Alpha real(DP) :: BetaSq real(DP) :: StatStab real(DP) :: RiNum real(DP) :: DVelDzSq real(DP), parameter :: Epsilon = 1.0e-10_DP real(DP), parameter :: CrtlRiNum = 0.195_DP real(DP), parameter :: CrtlShear = 0.001_DP / 1000.0_DP !!$ logical :: FlagReCalc !!$ ! !!$ ! Flag for recalculation !!$ logical :: a_FlagReCalcLocal (1) !!$ logical :: a_FlagReCalcGlobal(1) !!$ integer :: iloop !!$ integer :: nloop 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:: n ! 組成方向に回る DO ループ用作業変数 !!$ ! Work variables for DO loop in dimension of constituents ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if ! 計算時間計測開始 ! Start measurement of computation time ! call TimesetClockStart( module_name ) ! ! Calculation of vertical shear squared do k = 1, kmax if ( k == 1 ) then xyz_DVelDzSq(:,:,k) = ( ( xyz_U(:,:,k+1) - xyz_U(:,:,k ) )**2 + ( xyz_V(:,:,k+1) - xyz_V(:,:,k ) )**2 ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k ) )**2 !!$ xyz_DVelDzSq(:,:,k) = & !!$ & ( ( xyz_U(:,:,k+1) - 0.0_DP )**2 & !!$ & + ( xyz_V(:,:,k+1) - 0.0_DP )**2 ) & !!$ & / ( xyz_Height(:,:,k+1) - xy_SurfHeight )**2 else if ( k == kmax ) then xyz_DVelDzSq(:,:,k) = ( ( xyz_U(:,:,k ) - xyz_U(:,:,k-1) )**2 + ( xyz_V(:,:,k ) - xyz_V(:,:,k-1) )**2 ) / ( xyz_Height(:,:,k ) - xyz_Height(:,:,k-1) )**2 else xyz_DVelDzSq(:,:,k) = ( ( xyz_U(:,:,k+1) - xyz_U(:,:,k-1) )**2 + ( xyz_V(:,:,k+1) - xyz_V(:,:,k-1) )**2 ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k-1) )**2 end if end do ! Calculation of static stability do k = 1, kmax if ( k == 1 ) then xyz_StatStab(:,:,k) = Grav / ( xyz_VirTemp(:,:,k) / xyz_Exner(:,:,k) ) * ( xyz_VirTemp(:,:,k+1) / xyz_Exner(:,:,k+1) - xyz_VirTemp(:,:,k ) / xyz_Exner(:,:,k ) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k ) ) else if ( k == kmax ) then xyz_StatStab(:,:,k) = Grav / ( xyz_VirTemp(:,:,k) / xyz_Exner(:,:,k) ) * ( xyz_VirTemp(:,:,k ) / xyz_Exner(:,:,k ) - xyz_VirTemp(:,:,k-1) / xyz_Exner(:,:,k-1) ) / ( xyz_Height(:,:,k ) - xyz_Height(:,:,k-1) ) else xyz_StatStab(:,:,k) = Grav / ( xyz_VirTemp(:,:,k) / xyz_Exner(:,:,k) ) * ( xyz_VirTemp(:,:,k+1) / xyz_Exner(:,:,k+1) - xyz_VirTemp(:,:,k-1) / xyz_Exner(:,:,k-1) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k-1) ) end if end do ! 混合距離の算出 ! Calculate mixing length ! do k = 1, kmax xyz_MixLength(:,:,k) = FKarm * ( xyz_Height(:,:,k) - xy_SurfHeight ) / (1.0_DP + FKarm * ( xyz_Height(:,:,k) - xy_SurfHeight ) / MixLengthMax ) end do !!$ ! Limit mixing length (Galperin et al., 1988) and avoid zero !!$ xyz_MixLength = & !!$ & min( xyz_MixLength, & !!$ & 0.53_DP & !!$ & * sqrt( 2.0_DP * xyz_TurKinEneNonZero / max( xyz_StatStab, 1.0d-10 ) ) ) & !!$ & + 1.0d-10 !******************************************************************** ! Gerrity et al. (1994) ! Set flag for using Richardson number do k = 1, kmax do j = 1, jmax do i = 0, imax-1 if ( xyz_DVelDzSq(i,j,k) < CrtlShear**2 ) then xyz_FlagUseRiNum(i,j,k) = .false. else xyz_FlagUseRiNum(i,j,k) = .true. end if end do end do end do ! Calculation of Richardson number do k = 1, kmax do j = 1, jmax do i = 0, imax-1 if ( xyz_FlagUseRiNum(i,j,k) ) then xyz_RiNum(i,j,k) = xyz_StatStab(i,j,k) / xyz_DVelDzSq(i,j,k) else xyz_RiNum(i,j,k) = - 1.0e100_DP end if end do end do end do ! Set flag for selecting an asymptotic equation do k = 1, kmax do j = 1, jmax do i = 0, imax-1 if ( xyz_FlagUseRiNum(i,j,k) ) then if ( CrtlRiNum <= xyz_RiNum(i,j,k) ) then ! Ric <= Ri xyz_FlagTKEAsymptToZero = .true. else ! Ri < Ric xyz_FlagTKEAsymptToZero = .false. end if else if ( xyz_StatStab(i,j,k) > 0.0_DP ) then xyz_FlagTKEAsymptToZero = .true. else xyz_FlagTKEAsymptToZero = .false. end if end if end do end do end do ! Calculation of roos for equations for steady state do k = 1, kmax do j = 1, jmax do i = 0, imax-1 if ( xyz_FlagUseRiNum(i,j,k) ) then ! Calculation with Richardson number MixLength = xyz_MixLength(i,j,k) DVelDzSq = xyz_DVelDzSq (i,j,k) RiNum = xyz_RiNum (i,j,k) ! Beta1 = - MixLength**2 * DVelDzSq * ( 6.53_DP - 49.0_DP * RiNum ) Beta2 = - MixLength**4 * DVelDzSq**2 * ( 51.2_DP - 262.7_DP * RiNum ) * RiNum Beta3 = MixLength**2 * DVelDzSq * ( 5.08_DP + 36.7_DP * RiNum ) Beta4 = MixLength**4 * DVelDzSq**2 * ( 88.8_DP + 187.4_DP * RiNum ) * RiNum ! xyz_A1(i,j,k) = - Beta1 / 2.0_DP + sqrt( Beta1**2 - 4.0_DP * Beta2 ) / 2.0_DP xyz_A2(i,j,k) = - Beta1 / 2.0_DP - sqrt( Beta1**2 - 4.0_DP * Beta2 ) / 2.0_DP xyz_R1(i,j,k) = - Beta3 / 2.0_DP + sqrt( Beta3**2 - 4.0_DP * Beta4 ) / 2.0_DP xyz_R2(i,j,k) = - Beta3 / 2.0_DP - sqrt( Beta3**2 - 4.0_DP * Beta4 ) / 2.0_DP else ! Calculation without Richardson number MixLength = xyz_MixLength(i,j,k) StatStab = xyz_StatStab (i,j,k) ! xyz_A1(i,j,k) = 24.49_DP * MixLength**2 * ( - StatStab ) + 18.36_DP * MixLength**2 * abs( - StatStab ) xyz_A2(i,j,k) = 24.49_DP * MixLength**2 * ( - StatStab ) - 18.36_DP * MixLength**2 * abs( - StatStab ) xyz_R1(i,j,k) = 18.35_DP * MixLength**2 * ( - StatStab ) + 12.22_DP * MixLength**2 * abs( - StatStab ) xyz_R2(i,j,k) = 18.35_DP * MixLength**2 * ( - StatStab ) - 12.22_DP * MixLength**2 * abs( - StatStab ) end if end do end do end do ! Set turbulent kinetic energy at current time step ! do k = 1, kmax do j = 1, jmax do i = 0, imax-1 if ( xyz_FlagUseRiNum(i,j,k) ) then if ( xyz_RiNum(i,j,k) < 0.0_DP ) then ! Ri < 0 (or CT > 0) xyz_TKEInit(i,j,k) = max( xyz_TurKinEne(i,j,k), xyz_R1(i,j,k) / 2.0_DP ) else if ( xyz_RiNum(i,j,k) < CrtlRiNum ) then ! 0 <= Ri < Ric xyz_TKEInit(i,j,k) = xyz_TurKinEne(i,j,k) else ! Ric <= Ri xyz_TKEInit(i,j,k) = xyz_TurKinEne(i,j,k) end if else if ( xyz_StatStab(i,j,k) < 0.0_DP ) then ! CT > 0 xyz_TKEInit(i,j,k) = max( xyz_TurKinEne(i,j,k), xyz_R1(i,j,k) / 2.0_DP ) else ! CT <= 0 xyz_TKEInit(i,j,k) = xyz_TurKinEne(i,j,k) end if end if xyz_TKEInit(i,j,k) = xyz_TKEInit(i,j,k) + TurKinEneOffset end do end do end do ! xyz_TKEx2 = 2.0_DP * xyz_TKEInit xyz_SqrtTKEx2 = sqrt( xyz_TKEx2 ) do k = 1, kmax do j = 1, jmax do i = 0, imax-1 if ( xyz_FlagTKEAsymptToZero(i,j,k) ) then xyz_SqrtA1(i,j,k) = 1.0e100_DP else xyz_SqrtA1(i,j,k) = sqrt( xyz_A1(i,j,k) ) end if end do end do end do ! do k = 1, kmax do j = 1, jmax do i = 0, imax-1 if ( xyz_FlagTKEAsymptToZero(i,j,k) ) then ! Use equations asymptotic to zero TKE, Eq. (10) ! Eq. (11) BetaSq = ( xyz_TKEx2(i,j,k) - xyz_A1(i,j,k)**2 ) * ( xyz_TKEx2(i,j,k) - xyz_A2(i,j,k)**2 ) / ( MYConstB1 * xyz_MixLength(i,j,k) * ( xyz_TKEx2(i,j,k) - xyz_R1(i,j,k) ) * ( xyz_TKEx2(i,j,k) - xyz_R2(i,j,k) ) ) ! Eq. (10) xyz_TKETentative(i,j,k) = xyz_TKEInit(i,j,k) / 2.0_DP / ( 1.0_DP + xyz_SqrtTKEx2(i,j,k) * BetaSq * ( 2.0_DP * DelTime ) )**2 else ! Use equations asymptotic to certain TKE, Eq. (8) ! Eq. (7b) BetaSq = xyz_TKEx2(i,j,k) * ( xyz_TKEx2(i,j,k) - xyz_A2(i,j,k)**2 ) / ( MYConstB1 * xyz_MixLength(i,j,k) * ( xyz_TKEx2(i,j,k) - xyz_R1(i,j,k) ) * ( xyz_TKEx2(i,j,k) - xyz_R2(i,j,k) ) ) ! Eq. (9) Alpha = ( xyz_SqrtTKEx2(i,j,k) - xyz_SqrtA1(i,j,k) ) / ( xyz_SqrtTKEx2(i,j,k) + xyz_SqrtA1(i,j,k) ) * exp( - 2.0_DP * xyz_SqrtA1(i,j,k) * BetaSq * ( 2.0_DP * DelTime ) ) Alpha = max( min( Alpha, 1.0_DP - Epsilon ), -1.0_DP ) ! Eq. (8) xyz_TKETentative(i,j,k) = xyz_A1(i,j,k) / 2.0_DP * ( ( 1.0_DP + Alpha ) / ( 1.0_DP - Alpha ) )**2 end if end do end do end do !******************************************************************** ! Set turbulent kinetic energy for diffusion calculation ! !!$ xyz_TurKinEneNonZero = xyz_TurKinEne + TurKinEneOffset xyz_TurKinEneNonZero = xyz_TKETentative + TurKinEneOffset xyz_Gh = - xyz_MixLength**2 / ( 2.0_DP * xyz_TurKinEneNonZero ) * xyz_StatStab ! Actually, xyz_Gm is not used below. xyz_Gm = xyz_MixLength**2 / ( 2.0_DP * xyz_TurKinEneNonZero ) * xyz_DVelDzSq ! Limit Gh (Galperin et al., 1988) !!$ GhMin = - 0.53d0**2 !!$ GhMax = 1.0_DP & !!$ & / ( MYConstA2 & !!$ & * ( 12.0_DP * MYConstA1 + MYConstB1 + 3.0_DP * MYConstB2 ) ) !!$ xyz_Gh = max( GhMin, min( xyz_Gh, GhMax ) ) xyz_Sh = MYConstA2 * ( 1.0_DP - 6.0_DP * MYConstA1 / MYConstB1 ) / ( 1.0_DP - 3.0_DP * MYConstA2 * ( 6.0_DP * MYConstA1 + MYConstB2 ) * xyz_Gh ) xyz_Sm = ( MYConstA1 * ( 1.0_DP - 3.0_DP * MYConstC1 - 6.0_DP * MYConstA1 / MYConstB1 ) + 9.0_DP * MYConstA1 * ( 2.0_DP * MYConstA1 + MYConstA2 ) * xyz_Gh * xyz_Sh ) / ( 1.0_DP - 9.0_DP * MYConstA1 * MYConstA2 * xyz_Gh ) ! 拡散係数の計算 ! Calculation of diffusion coefficient ! xyz_VelDiffCoef = xyz_MixLength * sqrt( 2.0_DP * xyz_TurKinEneNonZero ) * xyz_Sm xyz_TempDiffCoef = xyz_MixLength * sqrt( 2.0_DP * xyz_TurKinEneNonZero ) * xyz_Sh ! do k = 0, kmax if ( ( k == 0 ) .or. ( k == kmax ) ) then xyr_VelDiffCoef (:,:,k) = 0.0_DP xyr_TempDiffCoef(:,:,k) = 0.0_DP else xyr_VelDiffCoef (:,:,k) = ( xyz_VelDiffCoef (:,:,k) + xyz_VelDiffCoef (:,:,k+1) ) / 2.0_DP xyr_TempDiffCoef(:,:,k) = ( xyz_TempDiffCoef(:,:,k) + xyz_TempDiffCoef(:,:,k+1) ) / 2.0_DP end if end do ! do k = 1, kmax-1 do j = 1, jmax do i = 0, imax-1 xyr_VelDiffCoef(i,j,k) = max( min( xyr_VelDiffCoef(i,j,k), VelDiffCoefMax ), VelDiffCoefMin ) xyr_TempDiffCoef(i,j,k) = max( min( xyr_TempDiffCoef(i,j,k), TempDiffCoefMax ), TempDiffCoefMin ) end do end do end do ! xyr_QMixDiffCoef = xyr_TempDiffCoef ! 輸送係数とフラックスの計算 ! Calculate transfer coefficient and flux ! call VDiffusionCalcFlux( xyz_U, xyz_V, xyzf_QMix, xyz_Temp, xyr_VirTemp, xyr_Press, xyz_Height, xyz_Exner, xyr_Exner, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef, xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux ) ! Calculate tendency of turbulent kinetic energy ! Set diffusion coefficient for turbulent kinetic energy xyz_TurKinEneDiffCoef = xyz_MixLength * sqrt( 2.0_DP * xyz_TurKinEneNonZero ) * Stke ! do k = 0, kmax if ( k == 0 ) then xyr_TurKinEneDiffCoef(:,:,k) = xyz_TurKinEneDiffCoef(:,:,1) else if ( k == kmax ) then xyr_TurKinEneDiffCoef(:,:,k) = xyz_TurKinEneDiffCoef(:,:,kmax) else xyr_TurKinEneDiffCoef(:,:,k) = ( xyz_TurKinEneDiffCoef(:,:,k) + xyz_TurKinEneDiffCoef(:,:,k+1) ) / 2.0_DP end if end do ! Calculate turbulent kinetic energy at lower boundary ! xy_FricVelSq = sqrt( xy_SurfMomFluxX**2 + xy_SurfMomFluxY**2 ) / ( xyr_Press(:,:,0) / ( GasRDry * xyr_VirTemp(:,:,0) ) ) xy_TurKinEneAtLB = MYConstB1**(2.0_DP/3.0_DP) / 2.0_DP * xy_FricVelSq xy_TurKinEneAtLB = xy_TurKinEneAtLB + TurKinEneOffset ! Calculate transfer coefficient and flux of turbulent kinetic energy ! ! When transfer coefficient at lower boundary is calculated, ! diffusion coefficient at mid-point of 1st layer is used. ! In addition, transfer coefficient at upper boundary is assumed ! to be zero. k = 0 xyr_TurKinEneTransCoef(:,:,k) = xyz_TurKinEneDiffCoef(:,:,1) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,1) - xy_SurfHeight ) do k = 1, kmax-1 xyr_TurKinEneTransCoef(:,:,k) = xyr_TurKinEneDiffCoef(:,:,k) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) end do k = kmax xyr_TurKinEneTransCoef(:,:,k) = 0.0_DP ! do k = 1, kmax-1 xyr_TurKinEneFlux(:,:,k) = - xyr_TurKinEneTransCoef(:,:,k) * ( xyz_TurKinEneNonZero(:,:,k+1) - xyz_TurKinEneNonZero(:,:,k) ) end do k = 0 xyr_TurKinEneFlux(:,:,k) = - xyr_TurKinEneTransCoef(:,:,k) * ( xyz_TurKinEneNonZero(:,:,k+1) - xy_TurKinEneAtLB ) k = kmax xyr_TurKinEneFlux(:,:,k) = 0.0_DP ! ! Construct implicit matrix from transfer coefficient of vertical ! diffusion scheme (turbulent kinetic energy) ! k = 1 xyza_TurKinEneMtx(:,:,k,-1) = 0.0_DP xyza_TurKinEneMtx(:,:,k, 0) = - ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav / ( 2.0_DP * DelTime ) + xyr_TurKinEneTransCoef(:,:,k-1) + xyr_TurKinEneTransCoef(:,:,k ) xyza_TurKinEneMtx(:,:,k, 1) = - xyr_TurKinEneTransCoef(:,:,k ) ! do k = 2, kmax-1 xyza_TurKinEneMtx(:,:,k,-1) = - xyr_TurKinEneTransCoef(:,:,k-1) xyza_TurKinEneMtx(:,:,k, 0) = - ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav / ( 2.0_DP * DelTime ) + xyr_TurKinEneTransCoef(:,:,k-1) + xyr_TurKinEneTransCoef(:,:,k ) xyza_TurKinEneMtx(:,:,k, 1) = - xyr_TurKinEneTransCoef(:,:,k ) end do ! k = kmax xyza_TurKinEneMtx(:,:,k,-1) = - xyr_TurKinEneTransCoef(:,:,k-1) xyza_TurKinEneMtx(:,:,k, 0) = - ( xyr_Press(:,:,k) - xyr_Press(:,:,k-1) ) / Grav / ( 2.0_DP * DelTime ) + xyr_TurKinEneTransCoef(:,:,k-1) + xyr_TurKinEneTransCoef(:,:,k ) xyza_TurKinEneMtx(:,:,k, 1) = 0.0_DP do k = 1, kmax xyz_TurKinEneVec(:,:,k) = - ( xyr_TurKinEneFlux(:,:,k) - xyr_TurKinEneFlux(:,:,k-1) ) end do ! ! Solve simultaneous linear equations by use of LU decomposition technique ! xyza_TurKinEneLUMtx = xyza_TurKinEneMtx ! call PhyImplLUDecomp3( xyza_TurKinEneLUMtx, imax * jmax, kmax ) xyz_DelTurKinEneLUVec = xyz_TurKinEneVec ! call PhyImplLUSolve3( xyz_DelTurKinEneLUVec, xyza_TurKinEneLUMtx, 1, imax * jmax , kmax ) !!$ xyz_DTurKinEneDt = xyz_DelTurKinEneLUVec / ( 2.0_DP * DelTime ) xyz_TKETentative = xyz_TKETentative + xyz_DelTurKinEneLUVec xyz_DTurKinEneDt = ( xyz_TKETentative - xyz_TurKinEne ) / ( 2.0_DP * DelTime ) !!$ write( 6, * ) TimeN, iloop !!$ write( 6, * ) xyz_TurKinEne(0,jmax/2+1,1:4) !!$ write( 6, * ) xyz_TempDiffCoef(0,jmax/2+1,1:4) !!$ write( 6, * ) xyz_DTurKinEneDt(0,jmax/2+1,1:4) ! 拡散係数の出力 ! Output diffusion coefficients ! ! 拡散係数出力 ! Diffusion coeffficients output ! call HistoryAutoPut( TimeN, 'VelDiffCoef', xyr_VelDiffCoef ) call HistoryAutoPut( TimeN, 'TempDiffCoef', xyr_TempDiffCoef ) call HistoryAutoPut( TimeN, 'QVapDiffCoef', xyr_QMixDiffCoef ) call HistoryAutoPut( TimeN, 'MixLength' , xyz_MixLength ) ! 計算時間計測一時停止 ! Pause measurement of computation time ! call TimesetClockStop( module_name ) end subroutine VDiffusionMY25GBT94
Subroutine : | |||
xyr_MomFluxX(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_MomFluxY(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_HeatFlux(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) : | real(DP), intent(in)
| ||
xyz_DUDt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyz_DVDt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyz_DTempDt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyzf_DQMixDt(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) : | real(DP), intent(in)
| ||
xyr_Press(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_Exner(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Exner(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_VirTemp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_Height(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_VelDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_TempDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_QMixDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
|
フラックス (xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux). について, その他の引数を用いて補正し, 出力を行う.
Fluxes (xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux) are corrected by using other arguments, and the corrected values are output.
subroutine VDiffusionOutPut( xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux, xyz_DUDt, xyz_DVDt, xyz_DTempDt, xyzf_DQMixDt, xyr_Press, xyz_Exner, xyr_Exner, xyr_VirTemp, xyz_Height, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef ) ! ! フラックス (xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux). ! について, その他の引数を用いて補正し, 出力を行う. ! ! Fluxes (xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux) are ! corrected by using other arguments, and the corrected values are output. ! ! モジュール引用 ; USE statements ! ! 物理定数設定 ! Physical constants settings ! use constants, only: CpDry, LatentHeat, GasRDry ! $ R $ [J kg-1 K-1]. ! 乾燥大気の気体定数. ! Gas constant of air ! 時刻管理 ! Time control ! use timeset, only: DelTime, TimeN, TimesetClockStart, TimesetClockStop ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoPut ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in):: xyr_MomFluxX (0:imax-1, 1:jmax, 0:kmax) ! 東西方向運動量フラックス. ! Eastward wind flux real(DP), intent(in):: xyr_MomFluxY (0:imax-1, 1:jmax, 0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP), intent(in):: xyr_HeatFlux (0:imax-1, 1:jmax, 0:kmax) ! 熱フラックス. ! Heat flux real(DP), intent(in):: xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) ! 質量フラックス. ! Mass flux of constituents real(DP), intent(in):: xyz_DUDt (0:imax-1, 1:jmax, 1:kmax) ! $ \DP{u}{t} $ . 東西風速変化. ! Eastward wind tendency real(DP), intent(in):: xyz_DVDt (0:imax-1, 1:jmax, 1:kmax) ! $ \DP{v}{t} $ . 南北風速変化. ! Northward wind tendency real(DP), intent(in):: xyz_DTempDt (0:imax-1, 1:jmax, 1:kmax) ! $ \DP{T}{t} $ . 温度変化. ! Temperature tendency real(DP), intent(in):: xyzf_DQMixDt(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) ! $ \DP{q}{t} $ . 混合比変化. ! Mass mixing ratio tendency real(DP), intent(in):: xyr_Press (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{p} $ . 気圧 (半整数レベル). ! Air pressure (half level) real(DP), intent(in):: xyz_Exner (0:imax-1, 1:jmax, 1:kmax) ! Exner 関数 (整数レベル). ! Exner function (full level) real(DP), intent(in):: xyr_Exner (0:imax-1, 1:jmax, 0:kmax) ! Exner 関数 (半整数レベル). ! Exner function (half level) real(DP), intent(in):: xyr_VirTemp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T}_v $ . 仮温度 (半整数レベル). ! Virtual temperature (half level) real(DP), intent(in):: xyz_Height (0:imax-1, 1:jmax, 1:kmax) ! 高度 (整数レベル). ! Height (full level) real(DP), intent(in):: xyr_VelDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP), intent(in):: xyr_TempDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:温度. ! Transfer coefficient: temperature real(DP), intent(in):: xyr_QMixDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:比湿. ! Diffusion coefficient: specific humidity ! 出力のための作業変数 ! Work variables for output ! real(DP):: xyr_MomFluxXCor (0:imax-1, 1:jmax, 0:kmax) ! 東西方向運動量フラックス. ! Eastward momentum flux real(DP):: xyr_MomFluxYCor (0:imax-1, 1:jmax, 0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP):: xyr_HeatFluxCor (0:imax-1, 1:jmax, 0:kmax) ! 熱フラックス. ! Heat flux real(DP):: xyrf_QMixFluxCor(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) ! 質量フラックス. ! Mass flux of constituents ! 作業変数 ! Work variables ! real(DP) :: xyr_VelTransCoef (0:imax-1, 1:jmax, 0:kmax) ! 輸送係数:運動量. ! Transfer coefficient: velocity real(DP) :: xyr_TempTransCoef (0:imax-1, 1:jmax, 0:kmax) ! 輸送係数:温度. ! Transfer coefficient: temperature real(DP) :: xyr_QMixTransCoef(0:imax-1, 1:jmax, 0:kmax) ! 輸送係数:質量. ! Transfer coefficient: mass of constituents 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:: n ! 組成方向に回る DO ループ用作業変数 ! Work variables for DO loop in dimension of constituents real(DP):: LCp ! $ L / C_p $ [K]. ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if ! 計算時間計測開始 ! Start measurement of computation time ! call TimesetClockStart( module_name ) ! 輸送係数の計算 ! Calculate transfer coefficient ! xyr_VelTransCoef (:,:,0) = 0.0_DP xyr_VelTransCoef (:,:,kmax) = 0.0_DP xyr_TempTransCoef(:,:,0) = 0.0_DP xyr_TempTransCoef(:,:,kmax) = 0.0_DP xyr_QMixTransCoef(:,:,0) = 0.0_DP xyr_QMixTransCoef(:,:,kmax) = 0.0_DP do k = 1, kmax-1 xyr_VelTransCoef(:,:,k) = xyr_VelDiffCoef(:,:,k) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) xyr_TempTransCoef(:,:,k) = xyr_TempDiffCoef(:,:,k) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) xyr_QMixTransCoef(:,:,k) = xyr_QMixDiffCoef(:,:,k) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) end do ! 風速, 温度, 比湿フラックス補正 ! Correct fluxes of wind, temperature, specific humidity ! LCp = LatentHeat / CpDry do k = 1, kmax-1 do j = 1, jmax do i = 0, imax-1 xyr_MomFluxXCor( i,j,k ) = xyr_MomFluxX( i,j,k ) + ( xyz_DUDt( i,j,k ) - xyz_DUDt( i,j,k+1 ) ) * xyr_VelTransCoef( i,j,k ) * DelTime xyr_MomFluxYCor( i,j,k ) = xyr_MomFluxY( i,j,k ) + ( xyz_DVDt( i,j,k ) - xyz_DVDt( i,j,k+1 ) ) * xyr_VelTransCoef( i,j,k ) * DelTime xyr_HeatFluxCor( i,j,k ) = xyr_HeatFlux( i,j,k ) + ( xyz_DTempDt( i,j,k ) / xyz_Exner( i,j,k ) - xyz_DTempDt( i,j,k+1 ) / xyz_Exner( i,j,k+1 ) ) * CpDry * xyr_TempTransCoef( i,j,k ) * xyr_Exner( i,j,k ) * DelTime end do end do end do do n = 1, ncmax do k = 1, kmax-1 do j = 1, jmax do i = 0, imax-1 xyrf_QMixFluxCor( i,j,k,n ) = xyrf_QMixFlux( i,j,k,n ) + ( xyzf_DQMixDt( i,j,k,n ) - xyzf_DQMixDt( i,j,k+1,n ) ) * CpDry * xyr_QMixTransCoef( i,j,k ) * LCp * DelTime end do end do end do end do xyr_MomFluxXCor (:,:,0) = 0.0_DP xyr_MomFluxXCor (:,:,kmax) = 0.0_DP xyr_MomFluxYCor (:,:,0) = 0.0_DP xyr_MomFluxYCor (:,:,kmax) = 0.0_DP xyr_HeatFluxCor (:,:,0) = 0.0_DP xyr_HeatFluxCor (:,:,kmax) = 0.0_DP do n = 1, ncmax xyrf_QMixFluxCor(:,:,0,n) = 0.0_DP xyrf_QMixFluxCor(:,:,kmax,n) = 0.0_DP end do ! MEMO ! Output values of surface fluxes in MomFluxX, MomFluxY, HeatFlux, and QVapFlux ! are not correct. (YOT, 2009/08/14) ! Please refer to output variables, 'TauX', 'TauY', 'Sens', and 'Evap' for those ! values. (YOT, 2011/05/28) ! ヒストリデータ出力 ! History data output ! call HistoryAutoPut( TimeN, 'MomFluxX', xyr_MomFluxXCor ) call HistoryAutoPut( TimeN, 'MomFluxY', xyr_MomFluxYCor ) call HistoryAutoPut( TimeN, 'HeatFlux', xyr_HeatFluxCor ) call HistoryAutoPut( TimeN, 'QVapFlux', xyrf_QMixFluxCor ) call HistoryAutoPut( TimeN, 'DUDtVDiff' , xyz_DUDt ) call HistoryAutoPut( TimeN, 'DVDtVDiff' , xyz_DVDt ) call HistoryAutoPut( TimeN, 'DTempDtVDiff', xyz_DTempDt ) call HistoryAutoPut( TimeN, 'DQVapDtVDiff', xyzf_DQMixDt(:,:,:,IndexH2OVap) ) ! 計算時間計測一時停止 ! Pause measurement of computation time ! call TimesetClockStop( module_name ) end subroutine VDiffusionOutPut
Variable : | |||
BulkRiNumMin : | real(DP), save
|
Variable : | |||
ConstDiffCoefH : | real(DP), save
|
Variable : | |||
ConstDiffCoefM : | real(DP), save
|
Variable : | |||
FlagConstDiffCoef : | logical , save
|
Variable : | |||
TempDiffCoefMax : | real(DP), save
|
Variable : | |||
TempDiffCoefMin : | real(DP), save
|
Subroutine : | |||
xy_SurfHeight(0:imax-1,1:jmax) : | real(DP), intent(in)
| ||
xyr_Height(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_DVelDz(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_BulkRiNum(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_VelDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_TempDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_QMixDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
|
鉛直拡散フラックスを計算します.
Vertical diffusion flux is calculated.
subroutine VDiffCoefficient( xy_SurfHeight, xyr_Height, xyr_DVelDz, xyr_BulkRiNum, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef ) ! ! 鉛直拡散フラックスを計算します. ! ! Vertical diffusion flux is calculated. ! ! モジュール引用 ; USE statements ! ! 時刻管理 ! Time control ! use timeset, only: TimeN, TimesetClockStart, TimesetClockStop ! 物理定数設定 ! Physical constants settings ! use constants, only: FKarm ! $ k $ . ! カルマン定数. ! Karman constant ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoPut ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in):: xy_SurfHeight (0:imax-1,1:jmax) ! $ z_s $ . 地表面高度. ! Surface height. real(DP), intent(in):: xyr_Height (0:imax-1, 1:jmax, 0:kmax) ! 高度 (半整数レベル). ! Height (half level) real(DP), intent(in):: xyr_DVelDz (0:imax-1, 1:jmax, 0:kmax) ! $ \DD{|\Dvect{v}|}{z} $ real(DP), intent(in):: xyr_BulkRiNum (0:imax-1, 1:jmax, 0:kmax) ! バルク $ R_i $ 数. ! Bulk $ R_i $ real(DP), intent(out):: xyr_VelDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP), intent(out):: xyr_TempDiffCoef(0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:温度. ! Transfer coefficient: temperature real(DP), intent(out):: xyr_QMixDiffCoef(0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:質量 ! Diffusion coefficient: mass of constituents ! 作業変数 ! Work variables ! real(DP):: xyr_FluxRiNum (0:imax-1, 1:jmax, 0:kmax) ! フラックス $ R_i $ 数. ! Flux $ R_i $ number real(DP):: xyr_Sh (0:imax-1, 1:jmax, 0:kmax) ! $ S_h $ (温度, 比湿). ! $ S_h $ (temperature, specific humidity) real(DP):: xyr_Sm (0:imax-1, 1:jmax, 0:kmax) ! $ S_m $ (運動量). ! $ S_m $ (momentum) real(DP):: xyr_MixLength (0:imax-1, 1:jmax, 0:kmax) ! 混合距離. ! Mixing length real(DP):: Alpha1, Alpha2 real(DP):: Beta1, Beta2, Beta3, Beta4 real(DP):: Gamma1, Gamma2 real(DP):: CrtlFluxRiNum real(DP):: xyr_TurKinEne(0:imax-1, 1:jmax, 0:kmax) ! ! Turbulent kinetic energy 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 ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if ! 定数計算 ! Calculate constants ! Gamma1 = ( 1.0_DP / 3.0_DP ) - ( 2.0_DP * MYConstA1 / MYConstB1 ) Gamma2 = ( MYConstB2 / MYConstB1 ) + ( 6.0_DP * MYConstA1 / MYConstB1 ) Alpha1 = 3.0_DP * MYConstA2 * Gamma1 Alpha2 = 3.0_DP * MYConstA2 * ( Gamma1 + Gamma2 ) Beta1 = MYConstA1 * MYConstB1 * ( Gamma1 - MYConstC1 ) Beta2 = MYConstA1 * ( MYConstB1 * ( Gamma1 - MYConstC1 ) + 6.0_DP * MYConstA1 + 3.0_DP * MYConstA2 ) Beta3 = MYConstA2 * MYConstB1 * Gamma1 Beta4 = MYConstA2 * ( MYConstB1 * ( Gamma1 + Gamma2 ) - 3.0_DP * MYConstA1 ) CrtlFluxRiNum = Gamma1 / ( Gamma1 + Gamma2 ) ! フラックス $ R_i $ 数の算出 ! Calculate flux $ R_i $ number ! xyr_FluxRiNum = ( Beta1 + Beta4 * xyr_BulkRiNum - sqrt( ( Beta1 + Beta4 * xyr_BulkRiNum )**2 - 4.0_DP * Beta2 * Beta3 * xyr_BulkRiNum ) ) / ( 2.0_DP * Beta2 ) ! $ \tilde{S_h} $ と $ \tilde{S_m} $ の算出 ! Calculate $ \tilde{S_h} $ and $ \tilde{S_m} $ ! xyr_Sh(:,:,kmax) = 0.0_DP xyr_Sm(:,:,kmax) = 0.0_DP do k = 0, kmax-1 do i = 0, imax-1 do j = 1, jmax if ( xyr_FluxRiNum(i,j,k) < CrtlFluxRiNum ) then xyr_Sh(i,j,k) = ( Alpha1 - Alpha2 * xyr_FluxRiNum(i,j,k) ) / ( 1.0_DP - 1.0_DP * xyr_FluxRiNum(i,j,k) ) xyr_Sm(i,j,k) = ( Beta1 - Beta2 * xyr_FluxRiNum(i,j,k) ) / ( Beta3 - Beta4 * xyr_FluxRiNum(i,j,k) ) * xyr_Sh(i,j,k) xyr_Sh(i,j,k) = max( xyr_Sh(i,j,k), ShMin ) xyr_Sm(i,j,k) = max( xyr_Sm(i,j,k), SmMin ) else xyr_Sh(i,j,k) = ShMin xyr_Sm(i,j,k) = SmMin end if end do end do end do ! 混合距離の算出 ! Calculate mixing length ! do k = 0, kmax xyr_MixLength(:,:,k) = FKarm * ( xyr_Height(:,:,k) - xy_SurfHeight(:,:) ) / (1.0_DP + FKarm * ( xyr_Height(:,:,k) - xy_SurfHeight(:,:) ) / MixLengthMax ) end do ! 拡散係数の算出 ! Calculate diffusion constants ! xyr_VelDiffCoef = xyr_MixLength**2 * xyr_DVelDz * sqrt ( MYConstB1 * ( 1.0_DP - xyr_FluxRiNum ) * xyr_Sm ) * xyr_Sm xyr_TempDiffCoef = xyr_MixLength ** 2 * xyr_DVelDz * sqrt ( MYConstB1 * ( 1.0_DP - xyr_FluxRiNum ) * xyr_Sm ) * xyr_Sh do k = 0, kmax-1 do i = 0, imax-1 do j = 1, jmax xyr_VelDiffCoef(i,j,k) = max( min( xyr_VelDiffCoef(i,j,k), VelDiffCoefMax ), VelDiffCoefMin ) xyr_TempDiffCoef(i,j,k) = max( min( xyr_TempDiffCoef(i,j,k), TempDiffCoefMax ), TempDiffCoefMin ) end do end do end do xyr_QMixDiffCoef = xyr_TempDiffCoef xyr_VelDiffCoef (:,:,0) = 0.0_DP xyr_VelDiffCoef (:,:,kmax) = 0.0_DP xyr_TempDiffCoef(:,:,0) = 0.0_DP xyr_TempDiffCoef(:,:,kmax) = 0.0_DP xyr_QMixDiffCoef(:,:,0) = 0.0_DP xyr_QMixDiffCoef(:,:,kmax) = 0.0_DP ! Calculation of turbulent kinetic energy ! Turbulent kinetic energy is diagnosed. xyr_TurKinEne = MYConstB1 * xyr_MixLength**2 * ( 1.0_DP - xyr_FluxRiNum ) * xyr_Sm * xyr_DVelDz**2 / 2.0_DP xyr_TurKinEne(:,:,0 ) = 0.0_DP xyr_TurKinEne(:,:,kmax) = 0.0_DP ! ヒストリデータ出力 ! History data output ! call HistoryAutoPut( TimeN, 'TurKinEne', xyr_TurKinEne ) end subroutine VDiffCoefficient
Subroutine : | |||
xyz_U(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyz_V(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) : | real(DP), intent(in)
| ||
xyz_Temp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_VirTemp(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_Press(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyz_Height(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyz_Exner(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in)
| ||
xyr_Exner(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_VelDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_TempDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_QMixDiffCoef(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in)
| ||
xyr_MomFluxX(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_MomFluxY(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyr_HeatFlux(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out)
| ||
xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) : | real(DP), intent(out)
|
鉛直拡散フラックスを計算します.
Vertical diffusion flux is calculated.
subroutine VDiffusionCalcFlux( xyz_U, xyz_V, xyzf_QMix, xyz_Temp, xyr_VirTemp, xyr_Press, xyz_Height, xyz_Exner, xyr_Exner, xyr_VelDiffCoef, xyr_TempDiffCoef, xyr_QMixDiffCoef, xyr_MomFluxX, xyr_MomFluxY, xyr_HeatFlux, xyrf_QMixFlux ) ! ! 鉛直拡散フラックスを計算します. ! ! Vertical diffusion flux is calculated. ! ! モジュール引用 ; USE statements ! ! 物理定数設定 ! Physical constants settings ! use constants, only: FKarm, GasRDry, CpDry ! $ C_p $ [J kg-1 K-1]. ! 乾燥大気の定圧比熱. ! Specific heat of air at constant pressure ! 時刻管理 ! Time control ! use timeset, only: TimeN, TimesetClockStart, TimesetClockStop ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoPut ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in):: xyz_U (0:imax-1, 1:jmax, 1:kmax) ! $ u $ . 東西風速. Eastward wind real(DP), intent(in):: xyz_V (0:imax-1, 1:jmax, 1:kmax) ! $ v $ . 南北風速. Northward wind real(DP), intent(in):: xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax) ! $ q $ . 質量混合比. Mass mixing ratio real(DP), intent(in):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax) ! $ T $ . 温度. Temperature real(DP), intent(in):: xyr_VirTemp (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{T}_v $ . 仮温度 (半整数レベル). ! Virtual temperature (half level) real(DP), intent(in):: xyr_Press (0:imax-1, 1:jmax, 0:kmax) ! $ \hat{p} $ . 気圧 (半整数レベル). ! Air pressure (half level) real(DP), intent(in):: xyz_Height (0:imax-1, 1:jmax, 1:kmax) ! 高度 (整数レベル). ! Height (full level) real(DP), intent(in):: xyz_Exner (0:imax-1, 1:jmax, 1:kmax) ! Exner 関数 (整数レベル). ! Exner function (full level) real(DP), intent(in):: xyr_Exner (0:imax-1, 1:jmax, 0:kmax) ! Exner 関数 (半整数レベル). ! Exner function (half level) real(DP), intent(in):: xyr_VelDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP), intent(in):: xyr_TempDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:温度. ! Transfer coefficient: temperature real(DP), intent(in):: xyr_QMixDiffCoef (0:imax-1, 1:jmax, 0:kmax) ! 拡散係数:比湿. ! Diffusion coefficient: specific humidity real(DP), intent(out):: xyr_MomFluxX (0:imax-1, 1:jmax, 0:kmax) ! 東西方向運動量フラックス. ! Eastward momentum flux real(DP), intent(out):: xyr_MomFluxY (0:imax-1, 1:jmax, 0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP), intent(out):: xyr_HeatFlux (0:imax-1, 1:jmax, 0:kmax) ! 熱フラックス. ! Heat flux real(DP), intent(out):: xyrf_QMixFlux(0:imax-1, 1:jmax, 0:kmax, 1:ncmax) ! 質量フラックス. ! Mass flux of compositions ! 作業変数 ! Work variables ! real(DP) :: xyr_VelTransCoef (0:imax-1, 1:jmax, 0:kmax) ! 輸送係数:運動量. ! Transfer coefficient: velocity real(DP) :: xyr_TempTransCoef(0:imax-1, 1:jmax, 0:kmax) ! 輸送係数:温度. ! Transfer coefficient: temperature real(DP) :: xyr_QMixTransCoef(0:imax-1, 1:jmax, 0:kmax) ! 輸送係数:質量. ! Transfer coefficient: mass (composition) integer:: k ! 鉛直方向に回る DO ループ用作業変数 ! Work variables for DO loop in vertical direction integer:: n ! 組成方向に回る DO ループ用作業変数 ! Work variables for DO loop in dimension of constituents ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if ! 輸送係数の計算 ! Calculate transfer coefficient ! xyr_VelTransCoef (:,:,0) = 0.0_DP xyr_VelTransCoef (:,:,kmax) = 0.0_DP xyr_TempTransCoef(:,:,0) = 0.0_DP xyr_TempTransCoef(:,:,kmax) = 0.0_DP xyr_QMixTransCoef(:,:,0) = 0.0_DP xyr_QMixTransCoef(:,:,kmax) = 0.0_DP do k = 1, kmax-1 xyr_VelTransCoef(:,:,k) = xyr_VelDiffCoef(:,:,k) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) xyr_TempTransCoef(:,:,k) = xyr_TempDiffCoef(:,:,k) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) xyr_QMixTransCoef(:,:,k) = xyr_QMixDiffCoef(:,:,k) * xyr_Press(:,:,k) / ( GasRDry * xyr_VirTemp(:,:,k) ) / ( xyz_Height(:,:,k+1) - xyz_Height(:,:,k) ) end do ! フラックスの計算 ! Calculate fluxes ! xyr_MomFluxX(:,:,0) = 0.0_DP xyr_MomFluxX(:,:,kmax) = 0.0_DP xyr_MomFluxY(:,:,0) = 0.0_DP xyr_MomFluxY(:,:,kmax) = 0.0_DP xyr_HeatFlux(:,:,0) = 0.0_DP xyr_HeatFlux(:,:,kmax) = 0.0_DP do n = 1, ncmax xyrf_QMixFlux(:,:,0,n) = 0.0_DP xyrf_QMixFlux(:,:,kmax,n) = 0.0_DP end do do k = 1, kmax-1 xyr_MomFluxX(:,:,k) = - xyr_VelTransCoef(:,:,k) * ( xyz_U(:,:,k+1) - xyz_U(:,:,k) ) xyr_MomFluxY(:,:,k) = - xyr_VelTransCoef(:,:,k) * ( xyz_V(:,:,k+1) - xyz_V(:,:,k) ) xyr_HeatFlux(:,:,k) = - CpDry * xyr_TempTransCoef(:,:,k) * xyr_Exner(:,:,k) * ( xyz_Temp(:,:,k+1) / xyz_Exner(:,:,k+1) - xyz_Temp(:,:,k) / xyz_Exner(:,:,k) ) end do do n = 1, ncmax do k = 1, kmax-1 xyrf_QMixFlux(:,:,k,n) = - xyr_QMixTransCoef(:,:,k) * ( xyzf_QMix(:,:,k+1,n) - xyzf_QMix(:,:,k,n) ) end do end do end subroutine VDiffusionCalcFlux
Subroutine : | |||
z_U(1:kmax) : | real(DP), intent(in)
| ||
z_V(1:kmax) : | real(DP), intent(in)
| ||
zf_QMix(1:kmax, 1:ncmax) : | real(DP), intent(in)
| ||
z_Temp(1:kmax) : | real(DP), intent(in)
| ||
r_VirTemp(0:kmax) : | real(DP), intent(in)
| ||
r_Press(0:kmax) : | real(DP), intent(in)
| ||
z_Height(1:kmax) : | real(DP), intent(in)
| ||
z_Exner(1:kmax) : | real(DP), intent(in)
| ||
r_Exner(0:kmax) : | real(DP), intent(in)
| ||
r_VelDiffCoef(0:kmax) : | real(DP), intent(in)
| ||
r_TempDiffCoef(0:kmax) : | real(DP), intent(in)
| ||
r_QMixDiffCoef(0:kmax) : | real(DP), intent(in)
| ||
r_MomFluxX(0:kmax) : | real(DP), intent(out)
| ||
r_MomFluxY(0:kmax) : | real(DP), intent(out)
| ||
r_HeatFlux(0:kmax) : | real(DP), intent(out)
| ||
rf_QMixFlux(0:kmax, 1:ncmax) : | real(DP), intent(out)
|
鉛直拡散フラックスを計算します.
Vertical diffusion flux is calculated.
subroutine VDiffusionCalcFlux1D( z_U, z_V, zf_QMix, z_Temp, r_VirTemp, r_Press, z_Height, z_Exner, r_Exner, r_VelDiffCoef, r_TempDiffCoef, r_QMixDiffCoef, r_MomFluxX, r_MomFluxY, r_HeatFlux, rf_QMixFlux ) ! ! 鉛直拡散フラックスを計算します. ! ! Vertical diffusion flux is calculated. ! ! モジュール引用 ; USE statements ! ! 物理定数設定 ! Physical constants settings ! use constants, only: FKarm, GasRDry, CpDry ! $ C_p $ [J kg-1 K-1]. ! 乾燥大気の定圧比熱. ! Specific heat of air at constant pressure ! 時刻管理 ! Time control ! use timeset, only: TimeN, TimesetClockStart, TimesetClockStop ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoPut ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in):: z_U (1:kmax) ! $ u $ . 東西風速. Eastward wind real(DP), intent(in):: z_V (1:kmax) ! $ v $ . 南北風速. Northward wind real(DP), intent(in):: zf_QMix(1:kmax, 1:ncmax) ! $ q $ . 質量混合比. Mass mixing ratio real(DP), intent(in):: z_Temp (1:kmax) ! $ T $ . 温度. Temperature real(DP), intent(in):: r_VirTemp (0:kmax) ! $ \hat{T}_v $ . 仮温度 (半整数レベル). ! Virtual temperature (half level) real(DP), intent(in):: r_Press (0:kmax) ! $ \hat{p} $ . 気圧 (半整数レベル). ! Air pressure (half level) real(DP), intent(in):: z_Height (1:kmax) ! 高度 (整数レベル). ! Height (full level) real(DP), intent(in):: z_Exner (1:kmax) ! Exner 関数 (整数レベル). ! Exner function (full level) real(DP), intent(in):: r_Exner (0:kmax) ! Exner 関数 (半整数レベル). ! Exner function (half level) real(DP), intent(in):: r_VelDiffCoef (0:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP), intent(in):: r_TempDiffCoef (0:kmax) ! 拡散係数:温度. ! Transfer coefficient: temperature real(DP), intent(in):: r_QMixDiffCoef (0:kmax) ! 拡散係数:比湿. ! Diffusion coefficient: specific humidity real(DP), intent(out):: r_MomFluxX (0:kmax) ! 東西方向運動量フラックス. ! Eastward momentum flux real(DP), intent(out):: r_MomFluxY (0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP), intent(out):: r_HeatFlux (0:kmax) ! 熱フラックス. ! Heat flux real(DP), intent(out):: rf_QMixFlux(0:kmax, 1:ncmax) ! 質量フラックス. ! Mass flux of compositions ! 作業変数 ! Work variables ! real(DP) :: r_VelTransCoef (0:kmax) ! 輸送係数:運動量. ! Transfer coefficient: velocity real(DP) :: r_TempTransCoef(0:kmax) ! 輸送係数:温度. ! Transfer coefficient: temperature real(DP) :: r_QMixTransCoef(0:kmax) ! 輸送係数:質量. ! Transfer coefficient: mass (composition) integer:: k ! 鉛直方向に回る DO ループ用作業変数 ! Work variables for DO loop in vertical direction integer:: n ! 組成方向に回る DO ループ用作業変数 ! Work variables for DO loop in dimension of constituents ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if ! 輸送係数の計算 ! Calculate transfer coefficient ! r_VelTransCoef (0) = 0.0_DP r_VelTransCoef (kmax) = 0.0_DP r_TempTransCoef(0) = 0.0_DP r_TempTransCoef(kmax) = 0.0_DP r_QMixTransCoef(0) = 0.0_DP r_QMixTransCoef(kmax) = 0.0_DP do k = 1, kmax-1 r_VelTransCoef(k) = r_VelDiffCoef(k) * r_Press(k) / ( GasRDry * r_VirTemp(k) ) / ( z_Height(k+1) - z_Height(k) ) r_TempTransCoef(k) = r_TempDiffCoef(k) * r_Press(k) / ( GasRDry * r_VirTemp(k) ) / ( z_Height(k+1) - z_Height(k) ) r_QMixTransCoef(k) = r_QMixDiffCoef(k) * r_Press(k) / ( GasRDry * r_VirTemp(k) ) / ( z_Height(k+1) - z_Height(k) ) end do ! フラックスの計算 ! Calculate fluxes ! r_MomFluxX(0) = 0.0_DP r_MomFluxX(kmax) = 0.0_DP r_MomFluxY(0) = 0.0_DP r_MomFluxY(kmax) = 0.0_DP r_HeatFlux(0) = 0.0_DP r_HeatFlux(kmax) = 0.0_DP do n = 1, ncmax rf_QMixFlux(0,n) = 0.0_DP rf_QMixFlux(kmax,n) = 0.0_DP end do do k = 1, kmax-1 r_MomFluxX(k) = - r_VelTransCoef(k) * ( z_U(k+1) - z_U(k) ) r_MomFluxY(k) = - r_VelTransCoef(k) * ( z_V(k+1) - z_V(k) ) r_HeatFlux(k) = - CpDry * r_TempTransCoef(k) * r_Exner(k) * ( z_Temp(k+1) / z_Exner(k+1) - z_Temp(k) / z_Exner(k) ) end do do n = 1, ncmax do k = 1, kmax-1 rf_QMixFlux(k,n) = - r_QMixTransCoef(k) * ( zf_QMix(k+1,n) - zf_QMix(k,n) ) end do end do end subroutine VDiffusionCalcFlux1D
Subroutine : | |||
z_U(1:kmax) : | real(DP), intent(in)
| ||
z_V(1:kmax) : | real(DP), intent(in)
| ||
zf_QMix(1:kmax, 1:ncmax) : | real(DP), intent(in)
| ||
z_Temp(1:kmax) : | real(DP), intent(in)
| ||
r_Temp(0:kmax) : | real(DP), intent(in)
| ||
z_VirTemp(1:kmax) : | real(DP), intent(in)
| ||
r_VirTemp(0:kmax) : | real(DP), intent(in)
| ||
r_Press(0:kmax) : | real(DP), intent(in)
| ||
SurfHeight : | real(DP), intent(in)
| ||
z_Height(1:kmax) : | real(DP), intent(in)
| ||
r_Height(0:kmax) : | real(DP), intent(in)
| ||
z_Exner(1:kmax) : | real(DP), intent(in)
| ||
r_Exner(0:kmax) : | real(DP), intent(in)
| ||
z_TurKinEne(1:kmax) : | real(DP), intent(in)
| ||
SurfMomFluxX : | real(DP), intent(in)
| ||
SurfMomFluxY : | real(DP), intent(in)
| ||
r_MomFluxX(0:kmax) : | real(DP), intent(out)
| ||
r_MomFluxY(0:kmax) : | real(DP), intent(out)
| ||
r_HeatFlux(0:kmax) : | real(DP), intent(out)
| ||
rf_QMixFlux(0:kmax, 1:ncmax) : | real(DP), intent(out)
| ||
r_VelDiffCoef(0:kmax) : | real(DP), intent(out)
| ||
r_TempDiffCoef(0:kmax) : | real(DP), intent(out)
| ||
r_QMixDiffCoef(0:kmax) : | real(DP), intent(out)
| ||
z_DTurKinEneDt(1:kmax) : | real(DP), intent(out)
|
鉛直拡散フラックスを計算します.
Vertical diffusion flux is calculated by use of MY2.5 model.
subroutine VDiffusionMY251D( z_U, z_V, zf_QMix, z_Temp, r_Temp, z_VirTemp, r_VirTemp, r_Press, SurfHeight, z_Height, r_Height, z_Exner, r_Exner, z_TurKinEne, SurfMomFluxX, SurfMomFluxY, r_MomFluxX, r_MomFluxY, r_HeatFlux, rf_QMixFlux, r_VelDiffCoef, r_TempDiffCoef, r_QMixDiffCoef, z_DTurKinEneDt ) ! ! 鉛直拡散フラックスを計算します. ! ! Vertical diffusion flux is calculated by use of MY2.5 model. ! ! モジュール引用 ; USE statements ! ! 物理定数設定 ! Physical constants settings ! use constants, only: FKarm, Grav, GasRDry, CpDry ! $ C_p $ [J kg-1 K-1]. ! 乾燥大気の定圧比熱. ! Specific heat of air at constant pressure ! 時刻管理 ! Time control ! use timeset, only: DelTime, TimeN, TimesetClockStart, TimesetClockStop ! ヒストリデータ出力 ! History data output ! use gtool_historyauto, only: HistoryAutoPut ! 陰解法による時間積分のためのルーチン ! Routines for time integration with implicit scheme ! use phy_implicit_utils, only : PhyImplLUDecomp3, PhyImplLUSolve3 ! 宣言文 ; Declaration statements ! implicit none real(DP), intent(in):: z_U (1:kmax) ! $ u $ . 東西風速. Eastward wind real(DP), intent(in):: z_V (1:kmax) ! $ v $ . 南北風速. Northward wind real(DP), intent(in):: zf_QMix(1:kmax, 1:ncmax) ! $ q $ . 質量混合比. Mass mixing ratio real(DP), intent(in):: z_Temp (1:kmax) ! $ T $ . 温度. Temperature real(DP), intent(in):: r_Temp (0:kmax) ! $ \hat{T} $ . 温度 (半整数レベル). ! Temperature (half level) real(DP), intent(in):: z_VirTemp (1:kmax) ! $ T_v $ . 仮温度. Virtual temperature real(DP), intent(in):: r_VirTemp (0:kmax) ! $ \hat{T}_v $ . 仮温度 (半整数レベル). ! Virtual temperature (half level) real(DP), intent(in):: r_Press (0:kmax) ! $ \hat{p} $ . 気圧 (半整数レベル). ! Air pressure (half level) real(DP), intent(in):: SurfHeight ! $ z_s $ . 地表面高度. ! Surface height. real(DP), intent(in):: z_Height (1:kmax) ! 高度 (整数レベル). ! Height (full level) real(DP), intent(in):: r_Height (0:kmax) ! 高度 (半整数レベル). ! Height (half level) real(DP), intent(in):: z_Exner (1:kmax) ! Exner 関数 (整数レベル). ! Exner function (full level) real(DP), intent(in):: r_Exner (0:kmax) ! Exner 関数 (半整数レベル). ! Exner function (half level) real(DP), intent(in):: z_TurKinEne(1:kmax) ! ! Turbulent kinetic energy (m2 s-2) real(DP), intent(in):: SurfMomFluxX ! ! Eastward momentum flux at surface real(DP), intent(in):: SurfMomFluxY ! ! Northward momentum flux at surface real(DP), intent(out):: r_MomFluxX (0:kmax) ! 東西方向運動量フラックス. ! Eastward momentum flux real(DP), intent(out):: r_MomFluxY (0:kmax) ! 南北方向運動量フラックス. ! Northward momentum flux real(DP), intent(out):: r_HeatFlux (0:kmax) ! 熱フラックス. ! Heat flux real(DP), intent(out):: rf_QMixFlux(0:kmax, 1:ncmax) ! 質量フラックス. ! Mass flux of compositions real(DP), intent(out):: r_VelDiffCoef (0:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP), intent(out):: r_TempDiffCoef(0:kmax) ! 拡散係数:温度. ! Diffusion coefficient: temperature real(DP), intent(out):: r_QMixDiffCoef(0:kmax) ! 拡散係数:比湿. ! Diffusion coefficient: specific humidity real(DP), intent(out):: z_DTurKinEneDt (1:kmax) ! ! Tendency of turbulent kinetic energy ! 作業変数 ! Work variables ! real(DP) :: z_MixLength(1:kmax) ! 混合距離. ! Mixing length real(DP) :: z_DVelDzSq(1:kmax) ! ! Vertical shear squared (s-2) real(DP) :: z_StatStab(1:kmax) ! ! Static stability (s-2) real(DP) :: GhMin ! ! Minimum of G_h real(DP) :: GhMax ! ! Maximum of G_h real(DP) :: z_Gm(1:kmax) ! ! G_m real(DP) :: z_Gh(1:kmax) ! ! G_h real(DP) :: z_Sm(1:kmax) ! ! S_M real(DP) :: z_Sh(1:kmax) ! ! S_h real(DP), parameter :: Stke = 0.2_DP ! ! S_{TKE} = 0.2 real(DP) :: z_VelDiffCoef (1:kmax) ! 拡散係数:運動量. ! Diffusion coefficient: velocity real(DP) :: z_TempDiffCoef (1:kmax) ! 拡散係数:温度. ! Transfer coefficient: temperature real(DP) :: r_TurKinEneDiffCoef (0:kmax) ! ! Diffusion coefficient: turbulent kinetic energy real(DP) :: z_TurKinEneDiffCoef (1:kmax) ! ! Diffusion coefficient: turbulent kinetic energy real(DP) :: r_TurKinEneTransCoef(0:kmax) ! ! Transfer coefficient: turbulent kinetic energy real(DP) :: r_TurKinEneFlux(0:kmax) ! ! Turbulent energy flux real(DP) :: z_CShe1(1:kmax) real(DP) :: z_CShe2(1:kmax) real(DP) :: z_CBuo1(1:kmax) real(DP) :: z_CBuo2(1:kmax) real(DP) :: z_CDis1(1:kmax) real(DP) :: z_CDis2(1:kmax) real(DP) :: z_TurKinEneProShear(1:kmax) real(DP) :: z_TurKinEneProBuoya(1:kmax) real(DP) :: FricVelSq real(DP) :: TurKinEneAtLB real(DP) :: za_TurKinEneMtx(1:kmax, -1:1) ! ! Implicit matrix for turbulent kinetic energy real(DP) :: z_TurKinEneVec(1:kmax) ! ! Implicit vector for turbulent kinetic energy real(DP) :: aaza_TurKinEneLUMtx (1:1, 1:1, 1:kmax, -1:1) ! LU 行列. ! LU matrix real(DP) :: aaz_DelTurKinEneLUVec(1:1, 1:1, 1:kmax) ! ! Tendency of turbulent kinetic energy real(DP) :: z_TurKinEneDiss(1:kmax) ! ! Dissipation rate of turbulent kinetic energy (m2 s-3) real(DP) :: z_TurKinEneNonZero(1:kmax) ! ! Turbulent kinetic energy with offset (m2 s-2) real(DP), parameter :: TurKinEneOffset = ( 1.0e-3_DP )**2 / 2.0_DP logical :: FlagReCalc ! ! Flag for recalculation logical :: a_FlagReCalcLocal (1) logical :: a_FlagReCalcGlobal(1) integer :: iloop integer :: nloop integer:: k ! 鉛直方向に回る DO ループ用作業変数 ! Work variables for DO loop in vertical direction integer:: n ! 組成方向に回る DO ループ用作業変数 ! Work variables for DO loop in dimension of constituents ! 実行文 ; Executable statement ! ! 初期化確認 ! Initialization check ! if ( .not. vdiffusion_my_inited ) then call MessageNotify( 'E', module_name, 'This module has not been initialized.' ) end if !!$ ! 計算時間計測開始 !!$ ! Start measurement of computation time !!$ ! !!$ call TimesetClockStart( module_name ) ! Calculate turbulent kinetic energy with offset ! z_TurKinEneNonZero = z_TurKinEne + TurKinEneOffset ! ! Calculation of vertical shear squared do k = 1, kmax if ( k == 1 ) then z_DVelDzSq(k) = ( ( z_U(k+1) - z_U(k ) )**2 + ( z_V(k+1) - z_V(k ) )**2 ) / ( z_Height(k+1) - z_Height(k ) )**2 else if ( k == kmax ) then z_DVelDzSq(k) = ( ( z_U(k ) - z_U(k-1) )**2 + ( z_V(k ) - z_V(k-1) )**2 ) / ( z_Height(k ) - z_Height(k-1) )**2 else z_DVelDzSq(k) = ( ( z_U(k+1) - z_U(k-1) )**2 + ( z_V(k+1) - z_V(k-1) )**2 ) / ( z_Height(k+1) - z_Height(k-1) )**2 end if end do ! Calculation of static stability do k = 1, kmax if ( k == 1 ) then z_StatStab(k) = Grav / ( z_VirTemp(k) / z_Exner(k) ) * ( z_VirTemp(k+1) / z_Exner(k+1) - z_VirTemp(k ) / z_Exner(k ) ) / ( z_Height(k+1) - z_Height(k ) ) else if ( k == kmax ) then z_StatStab(k) = Grav / ( z_VirTemp(k) / z_Exner(k) ) * ( z_VirTemp(k ) / z_Exner(k ) - z_VirTemp(k-1) / z_Exner(k-1) ) / ( z_Height(k ) - z_Height(k-1) ) else z_StatStab(k) = Grav / ( z_VirTemp(k) / z_Exner(k) ) * ( z_VirTemp(k+1) / z_Exner(k+1) - z_VirTemp(k-1) / z_Exner(k-1) ) / ( z_Height(k+1) - z_Height(k-1) ) end if end do ! 混合距離の算出 ! Calculate mixing length ! do k = 1, kmax z_MixLength(k) = FKarm * ( z_Height(k) - SurfHeight ) / (1.0_DP + FKarm * ( z_Height(k) - SurfHeight ) / MixLengthMax ) end do ! Limit mixing length (Galperin et al., 1988) and avoid zero z_MixLength = min( z_MixLength, 0.53_DP * sqrt( 2.0_DP * z_TurKinEneNonZero / max( z_StatStab, 1.0e-10_DP ) ) ) + 1.0e-10_DP z_Gh = - z_MixLength**2 / ( 2.0_DP * z_TurKinEneNonZero ) * z_StatStab ! Actually, xyz_Gm is not used below. z_Gm = z_MixLength**2 / ( 2.0_DP * z_TurKinEneNonZero ) * z_DVelDzSq ! Limit Gh (Galperin et al., 1988) GhMin = - 0.53_DP**2 GhMax = 1.0_DP / ( MYConstA2 * ( 12.0_DP * MYConstA1 + MYConstB1 + 3.0_DP * MYConstB2 ) ) z_Gh = max( GhMin, min( z_Gh, GhMax ) ) z_Sh = MYConstA2 * ( 1.0_DP - 6.0_DP * MYConstA1 / MYConstB1 ) / ( 1.0_DP - 3.0_DP * MYConstA2 * ( 6.0_DP * MYConstA1 + MYConstB2 ) * z_Gh ) z_Sm = ( MYConstA1 * ( 1.0_DP - 3.0_DP * MYConstC1 - 6.0_DP * MYConstA1 / MYConstB1 ) + 9.0_DP * MYConstA1 * ( 2.0_DP * MYConstA1 + MYConstA2 ) * z_Gh * z_Sh ) / ( 1.0_DP - 9.0_DP * MYConstA1 * MYConstA2 * z_Gh ) ! 拡散係数の計算 ! Calculation of diffusion coefficient ! z_VelDiffCoef = z_MixLength * sqrt( 2.0_DP * z_TurKinEneNonZero ) * z_Sm z_TempDiffCoef = z_MixLength * sqrt( 2.0_DP * z_TurKinEneNonZero ) * z_Sh ! do k = 0, kmax if ( ( k == 0 ) .or. ( k == kmax ) ) then r_VelDiffCoef (k) = 0.0_DP r_TempDiffCoef(k) = 0.0_DP else r_VelDiffCoef (k) = ( z_VelDiffCoef (k) + z_VelDiffCoef (k+1) ) / 2.0_DP r_TempDiffCoef(k) = ( z_TempDiffCoef(k) + z_TempDiffCoef(k+1) ) / 2.0_DP end if end do ! do k = 1, kmax-1 r_VelDiffCoef(k) = max( min( r_VelDiffCoef(k), VelDiffCoefMax ), VelDiffCoefMin ) r_TempDiffCoef(k) = max( min( r_TempDiffCoef(k), TempDiffCoefMax ), TempDiffCoefMin ) end do ! r_QMixDiffCoef = r_TempDiffCoef ! 輸送係数とフラックスの計算 ! Calculate transfer coefficient and flux ! call VDiffusionCalcFlux1D( z_U, z_V, zf_QMix, z_Temp, r_VirTemp, r_Press, z_Height, z_Exner, r_Exner, r_VelDiffCoef, r_TempDiffCoef, r_QMixDiffCoef, r_MomFluxX, r_MomFluxY, r_HeatFlux, rf_QMixFlux ) ! Calculate tendency of turbulent kinetic energy ! Set diffusion coefficient for turbulent kinetic energy z_TurKinEneDiffCoef = z_MixLength * sqrt( 2.0_DP * z_TurKinEneNonZero ) * Stke ! do k = 0, kmax if ( k == 0 ) then r_TurKinEneDiffCoef(k) = z_TurKinEneDiffCoef(1) else if ( k == kmax ) then r_TurKinEneDiffCoef(k) = z_TurKinEneDiffCoef(kmax) else r_TurKinEneDiffCoef(k) = ( z_TurKinEneDiffCoef(k) + z_TurKinEneDiffCoef(k+1) ) / 2.0_DP end if end do ! Calculate turbulent kinetic energy at lower boundary ! FricVelSq = sqrt( SurfMomFluxX**2 + SurfMomFluxY**2 ) / ( r_Press(0) / ( GasRDry * r_VirTemp(0) ) ) TurKinEneAtLB = MYConstB1**(2.0_DP/3.0_DP) / 2.0_DP * FricVelSq TurKinEneAtLB = TurKinEneAtLB + TurKinEneOffset ! Calculate transfer coefficient and flux of turbulent kinetic energy ! ! When transfer coefficient at lower boundary is calculated, ! diffusion coefficient at mid-point of 1st layer is used. ! In addition, transfer coefficient at upper boundary is assumed ! to be zero. k = 0 r_TurKinEneTransCoef(k) = z_TurKinEneDiffCoef(1) * r_Press(k) / ( GasRDry * r_VirTemp(k) ) / ( z_Height(1) - SurfHeight ) do k = 1, kmax-1 r_TurKinEneTransCoef(k) = r_TurKinEneDiffCoef(k) * r_Press(k) / ( GasRDry * r_VirTemp(k) ) / ( z_Height(k+1) - z_Height(k) ) end do k = kmax r_TurKinEneTransCoef(k) = 0.0_DP ! do k = 1, kmax-1 r_TurKinEneFlux(k) = - r_TurKinEneTransCoef(k) * ( z_TurKinEneNonZero(k+1) - z_TurKinEneNonZero(k) ) end do k = 0 r_TurKinEneFlux(k) = - r_TurKinEneTransCoef(k) * ( z_TurKinEneNonZero(k+1) - TurKinEneAtLB ) k = kmax r_TurKinEneFlux(k) = 0.0_DP z_CShe1 = sqrt( 2.0_DP ) * z_MixLength * z_DVelDzSq * z_Sm * sqrt( z_TurKinEneNonZero ) z_CShe2 = 0.0_DP z_CBuo1 = - sqrt( 2.0_DP ) * z_MixLength * z_StatStab * z_Sh * sqrt( z_TurKinEneNonZero ) z_CBuo2 = 0.0_DP z_CDis1 = 2.0_DP**1.5_DP / ( MYConstB1 * z_MixLength ) * z_TurKinEneNonZero**1.5_DP z_CDis2 = 1.5_DP * 2.0_DP**1.5_DP / ( MYConstB1 * z_MixLength ) * z_TurKinEneNonZero**0.5_DP nloop = kmax loop_solve : do iloop = 1, nloop ! ! Construct implicit matrix from transfer coefficient of vertical ! diffusion scheme (turbulent kinetic energy) ! k = 1 za_TurKinEneMtx(k,-1) = 0.0_DP za_TurKinEneMtx(k, 0) = - ( r_Press(k) - r_Press(k-1) ) / Grav / ( 2.0_DP * DelTime ) + r_TurKinEneTransCoef(k-1) + r_TurKinEneTransCoef(k ) + ( r_Press(k) - r_Press(k-1) ) / Grav * ( z_CShe2(k) + z_CBuo2(k) - z_CDis2(k) ) za_TurKinEneMtx(k, 1) = - r_TurKinEneTransCoef(k ) ! do k = 2, kmax-1 za_TurKinEneMtx(k,-1) = - r_TurKinEneTransCoef(k-1) za_TurKinEneMtx(k, 0) = - ( r_Press(k) - r_Press(k-1) ) / Grav / ( 2.0_DP * DelTime ) + r_TurKinEneTransCoef(k-1) + r_TurKinEneTransCoef(k ) + ( r_Press(k) - r_Press(k-1) ) / Grav * ( z_CShe2(k) + z_CBuo2(k) - z_CDis2(k) ) za_TurKinEneMtx(k, 1) = - r_TurKinEneTransCoef(k ) end do ! k = kmax za_TurKinEneMtx(k,-1) = - r_TurKinEneTransCoef(k-1) za_TurKinEneMtx(k, 0) = - ( r_Press(k) - r_Press(k-1) ) / Grav / ( 2.0_DP * DelTime ) + r_TurKinEneTransCoef(k-1) + r_TurKinEneTransCoef(k ) + ( r_Press(k) - r_Press(k-1) ) / Grav * ( z_CShe2(k) + z_CBuo2(k) - z_CDis2(k) ) za_TurKinEneMtx(k, 1) = 0.0_DP do k = 1, kmax z_TurKinEneVec(k) = - ( r_TurKinEneFlux(k) - r_TurKinEneFlux(k-1) ) - ( r_Press(k) - r_Press(k-1) ) / Grav * ( z_CShe1(k) + z_CBuo1(k) - z_CDis1(k) ) end do ! ! Solve simultaneous linear equations by use of LU decomposition technique ! aaza_TurKinEneLUMtx(1,1,:,:) = za_TurKinEneMtx ! call PhyImplLUDecomp3( aaza_TurKinEneLUMtx, 1 * 1, kmax ) aaz_DelTurKinEneLUVec(1,1,:) = z_TurKinEneVec ! call PhyImplLUSolve3( aaz_DelTurKinEneLUVec, aaza_TurKinEneLUMtx, 1, 1 * 1 , kmax ) z_DTurKinEneDt = aaz_DelTurKinEneLUVec(1,1,:) / ( 2.0_DP * DelTime ) ! Calculation of dissipation rate of turbulent kinetic energy ! ! Calculate production rate of turbulent kinetic energy ! by shear and buoyancy z_TurKinEneProShear = z_CShe1 + z_CShe2 * z_DTurKinEneDt * 2.0_DP * DelTime z_TurKinEneProBuoya = z_CBuo1 + z_CBuo2 * z_DTurKinEneDt * 2.0_DP * DelTime z_TurKinEneDiss = z_CDis1 + z_CDis2 * z_DTurKinEneDt * 2.0_DP * DelTime ! Check of turbulent kinetic energy dissipation rate ! If it is negative, tendency is recalculated without dissipation. ! FlagReCalc = .false. do k = 1, kmax if ( z_TurKinEneDiss(k) < 0.0_DP ) then z_CDis1(k) = 0.0_DP z_CDis2(k) = 0.0_DP FlagReCalc = .true. end if end do ! Check convergence a_FlagReCalcLocal = FlagReCalc !!$ call MPIWrapperChkTrue( & !!$ & 1, a_FlagReCalcLocal, & ! (in) !!$ & a_FlagReCalcGlobal & ! (out) !!$ & ) a_FlagReCalcGlobal = a_FlagReCalcLocal if ( .not. a_FlagReCalcGlobal(1) ) exit loop_solve end do loop_solve !!$ ! 計算時間計測一時停止 !!$ ! Pause measurement of computation time !!$ ! !!$ call TimesetClockStop( module_name ) end subroutine VDiffusionMY251D
Variable : | |||
VelDiffCoefMax : | real(DP), save
|
Variable : | |||
VelDiffCoefMin : | real(DP), save
|
Constant : | |||
module_name = ‘vdiffusion_my‘ : | character(*), parameter
|
Variable : | |||
vdiffusion_my_inited = .false. : | logical, save
|
Constant : | |||
version = ’$Name: dcpam5-20150213 $’ // ’$Id: vdiffusion_my.f90,v 1.5 2015/01/29 12:09:17 yot Exp $’ : | character(*), parameter
|