| Class | radiation_RL78 |
| In: |
radiation/radiation_RL78.f90
|
Note that Japanese and English are described in parallel.
長波放射モデル.
This is a model of long wave radiation.
Roewe, D., and K.-N. Liou, Influence of cirrus clouds on the infrared cooling rate in the troposphere and lower stratosphere, J. Appl. Met., 17, 92-106, 1978.
| !$ ! RadiationFluxDennouAGCM : | 放射フラックスの計算 |
| !$ ! RadiationDTempDt : | 放射フラックスによる温度変化の計算 |
| !$ ! RadiationFluxOutput : | 放射フラックスの出力 |
| !$ ! RadiationFinalize : | 終了処理 (モジュール内部の変数の割り付け解除) |
| !$ ! ———— : | ———— |
| !$ ! RadiationFluxDennouAGCM : | Calculate radiation flux |
| !$ ! RadiationDTempDt : | Calculate temperature tendency with radiation flux |
| !$ ! RadiationFluxOutput : | Output radiation fluxes |
| !$ ! RadiationFinalize : | Termination (deallocate variables in this module) |
| Subroutine : | |
| xyz_Temp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyz_QVap(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyz_QO3(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyr_Press(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in ) |
| xyz_Press(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xy_SurfTemp(0:imax-1, 1:jmax) : | real(DP), intent(in ) |
| xyr_RadLFlux(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out) |
| xyra_DelRadLFlux(0:imax-1, 1:jmax, 0:kmax, 0:1) : | real(DP), intent(out) |
subroutine RadiationRL78Flux( xyz_Temp, xyz_QVap, xyz_QO3, xyr_Press, xyz_Press, xy_SurfTemp, xyr_RadLFlux, xyra_DelRadLFlux )
! USE statements
!
!
! Grid points settings
!
use gridset, only: imax, jmax, kmax !
! Number of vertical level
!
! Physical constants settings
!
use constants, only: Grav, PI ! $ \pi $ .
! Circular constant
! 時刻管理
! Time control
!
use timeset, only: TimeN, EndTime, TimesetClockStart, TimesetClockStop
use read_time_series, only: SetValuesFromTimeSeriesWrapper
use set_cloud, only : SetCloudLW
! OpenMP
!
!$ use omp_lib
real(DP), intent(in ):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyz_QVap (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyz_QO3 (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyr_Press (0:imax-1, 1:jmax, 0:kmax)
real(DP), intent(in ):: xyz_Press (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xy_SurfTemp (0:imax-1, 1:jmax)
real(DP), intent(out):: xyr_RadLFlux (0:imax-1, 1:jmax, 0:kmax)
real(DP), intent(out):: xyra_DelRadLFlux(0:imax-1, 1:jmax, 0:kmax, 0:1)
!
! Work variables
!
real(DP):: xyz_QCO2 (0:imax-1, 1:jmax, 1:kmax)
real(DP):: xyz_CloudDelOptDep (0:imax-1, 1:jmax, 1:kmax)
logical :: flag_dry_atmosphere
logical :: a_TransFlag(1:nbmax)
integer :: n
integer :: nt
integer :: js
integer :: je
integer :: nthreads
integer, allocatable :: a_js(:)
integer, allocatable :: a_je(:)
! 計算時間計測開始
! Start measurement of computation time
!
call TimesetClockStart( module_name )
if ( sw_fs ) then
call RadiationRoeweLiouInit
end if
nthreads = 1
!$ nthreads = omp_get_max_threads()
allocate( a_js(0:nthreads-1) )
allocate( a_je(0:nthreads-1) )
do n = 0, nthreads-1
if ( n == 0 ) then
a_js(n) = 1
else
a_js(n) = a_je(n-1) + 1
end if
a_je(n) = a_js(n ) + jmax / nthreads - 1
if ( n + 1 <= mod( jmax, nthreads ) ) then
a_je(n) = a_je(n) + 1
end if
end do
!!$ xyz_QCO2(:,:,:) = 382.0d-6 * CO2MolWeight / MeanMolWeight
xyz_QCO2(:,:,:) = VMRCO2 * CO2MolWeight / MeanMolWeight
!!$ xyz_QO3 (:,:,:) = 0.0d0
!!$ xyz_QVap(:,:,:) = 0.0d0
!!$ xyz_QCO2(:,:,:) = 300.0d-6 * CO2MolWeight / MeanMolWeight
!!$ xyz_QCO2(:,:,:) = 0.0d0
!!$ call SetRefAtmPro( &
!!$ & 5, .true., xyz_Press, &
!!$ & xyz_QO3 &
!!$ & )
!!$ if ( .true. ) then
if ( ( TimeN - PrevTimeSave >= IntTimeSave ) .or. ( .not. FlagTransSaved ) ) then
!!$ write( 6, * ) 'CalcTrans'
if ( .not. FlagTransSaved ) then
PrevTimeSave = TimeN
else
PrevTimeSave = PrevTimeSave + IntTimeSave
end if
FlagTransSaved = .true.
! Check for dry atmosphere
!
flag_dry_atmosphere = .false.
if ( flag_save_time ) then
if ( all( xyz_QVap <= 0.0d0 ) ) then
flag_dry_atmosphere = .true.
!!$ write( 6, * ) 'Dry atmosphere'
else
flag_dry_atmosphere = .false.
end if
end if
call SetCloudLW( xyz_CloudDelOptDep )
!$OMP PARALLEL DEFAULT(PRIVATE) &
!$OMP SHARED(nthreads,a_js,a_je, &
!$OMP xyz_QCO2, &
!$OMP xyz_Temp, xyz_QVap, xyz_QO3, xyr_Press, xyz_Press, xy_SurfTemp, &
!$OMP xyz_CloudDelOptDep, &
!$OMP flag_dry_atmosphere)
!$OMP DO
LOOP_thread_trans : do nt = 0, nthreads-1
js = a_js(nt)
je = a_je(nt)
if ( js > je ) cycle
!!$ write( 6, * ) n, js, je
call RadiationRL78CalcTotTrans( xyz_QCO2, xyz_Temp, xyz_QVap, xyz_QO3, xyr_Press, xyz_Press, xyz_CloudDelOptDep, flag_dry_atmosphere, js, je )
end do LOOP_thread_trans
!$OMP END DO
!$OMP END PARALLEL
end if
a_TransFlag = .false.
if ( flag_save_time ) then
do n = 1, nbmax
if ( all( xyrra_TransSave(:,:,0,kmax,n) == 1.0d0 ) ) then
a_TransFlag(n) = .true.
else
a_TransFlag(n) = .false.
end if
end do
end if
!$OMP PARALLEL DEFAULT(PRIVATE) &
!$OMP SHARED(nthreads,a_js,a_je, &
!$OMP a_TransFlag, &
!$OMP xyz_Temp, xy_SurfTemp, &
!$OMP xyr_RadLFlux, xyra_DelRadLFlux)
!$OMP DO
LOOP_thread_RTE : do nt = 0, nthreads-1
js = a_js(nt)
je = a_je(nt)
if ( js > je ) cycle
call RadiationRL78IntegRTE( a_TransFlag, xyz_Temp, xy_SurfTemp, xyr_RadLFlux, xyra_DelRadLFlux, js, je )
end do LOOP_thread_RTE
!$OMP END DO
!$OMP END PARALLEL
deallocate( a_js )
deallocate( a_je )
! 計算時間計測一時停止
! Pause measurement of computation time
!
call TimesetClockStop( module_name )
end subroutine RadiationRL78Flux
| Subroutine : | |
| iband : | integer , intent(in ) |
| xy_IntegPF(0:imax-1, 1:jmax) : | real(DP), intent(out) |
| js : | integer , intent(in ) |
| je : | integer , intent(in ) |
| flag_DPFDT : | logical , intent(in ), optional |
subroutine CalcIntegratedPFWithTable2D( iband, xy_Temp, xy_IntegPF, js, je, flag_DPFDT )
! USE statements
!
!
! Grid points settings
!
use gridset, only: imax, jmax !
! Number of grid points in latitude
integer , intent(in ) :: iband
real(DP), intent(in ) :: xy_temp (0:imax-1, 1:jmax)
real(DP), intent(out) :: xy_IntegPF(0:imax-1, 1:jmax)
integer , intent(in ) :: js
integer , intent(in ) :: je
logical , intent(in ), optional :: flag_DPFDT
!
! local variables
!
real(DP) :: xyz_Temp (0:imax-1, 1:jmax, 1)
real(DP) :: xyz_IntegPF(0:imax-1, 1:jmax, 1)
integer :: j
do j = js, je
xyz_Temp(:,j,1) = xy_Temp(:,j)
end do
call CalcIntegratedPFWithTable3D( iband, 1, xyz_temp, xyz_IntegPF, js, je, flag_DPFDT )
do j = js, je
xy_IntegPF(:,j) = xyz_IntegPF(:,j,1)
end do
end subroutine CalcIntegratedPFWithTable2D
| Subroutine : | |
| iband : | integer , intent(in ) |
| km : | integer , intent(in ) |
| xyz_temp(0:imax-1, 1:jmax, 1:km) : | real(DP), intent(in ) |
| xyz_IntegPF(0:imax-1, 1:jmax, 1:km) : | real(DP), intent(out) |
| js : | integer , intent(in ) |
| je : | integer , intent(in ) |
| flag_DPFDT : | logical , intent(in ), optional |
subroutine CalcIntegratedPFWithTable3D( iband, km, xyz_temp, xyz_IntegPF, js, je, flag_DPFDT )
! USE statements
!
!
! Grid points settings
!
use gridset, only: imax, jmax, kmax !
! Number of vertical level
! メッセージ出力
! Message output
!
use dc_message, only: MessageNotify
integer , intent(in ) :: iband
integer , intent(in ) :: km
real(DP), intent(in ) :: xyz_temp (0:imax-1, 1:jmax, 1:km)
real(DP), intent(out) :: xyz_IntegPF(0:imax-1, 1:jmax, 1:km)
logical , intent(in ), optional :: flag_DPFDT
integer , intent(in ) :: js
integer , intent(in ) :: je
!
! local variables
!
logical :: local_flag_DPFDT
integer :: xyz_TempIndex(0:imax-1, 1:jmax, 1:km)
integer :: i
integer :: j
integer :: k
integer :: m
do k = 1, km
do j = js, je
do i = 0, imax-1
if ( ( xyz_Temp(i,j,k) < a_TableTemp(1) ) .or. ( xyz_Temp(i,j,k) > a_TableTemp(ntmax) ) ) then
call MessageNotify( 'E', module_name, 'Temperature is not appropriate, Temp(%d,%d,%d) = %f.', i = (/i, j, k/), d = (/xyz_Temp(i,j,k)/) )
end if
xyz_TempIndex(i,j,k) = int( ( xyz_Temp(i,j,k) - TableTempMin ) / TableTempIncrement ) + 2
if ( xyz_TempIndex(i,j,k) == 1 ) then
xyz_TempIndex(i,j,k) = 2
else if ( xyz_TempIndex(i,j,k) >= ntmax ) then
xyz_TempIndex(i,j,k) = ntmax - 1
end if
!!$ xyz_TempIndex(i,j,k) = ntmax-1
!!$ search_index: do m = 2, ntmax-1
!!$ if ( a_TableTemp(m) >= xyz_Temp(i,j,k) ) then
!!$ xyz_TempIndex(i,j,k) = m
!!$ exit search_index
!!$ end if
!!$ end do search_index
end do
end do
end do
local_flag_DPFDT = .false.
if ( present( flag_DPFDT ) ) then
if ( flag_DPFDT ) then
local_flag_DPFDT = .true.
end if
end if
if ( .not. local_flag_DPFDT ) then
do k = 1, km
do j = js, je
do i = 0, imax-1
m = xyz_TempIndex(i,j,k)
!!$ xyz_IntegPF(i,j,k) = &
!!$ & ( aa_TableIPF( m, iband ) - aa_TableIPF( m-1, iband ) ) &
!!$ & / ( a_TableTemp( m ) - a_TableTemp( m-1 ) ) &
!!$ & * ( xyz_Temp(i,j,k) - a_TableTemp( m-1 ) ) &
!!$ & + aa_TableIPF( m-1, iband )
xyz_IntegPF(i,j,k) = aa_TableIPF(m-1,iband) * ( xyz_Temp (i,j,k) - a_TableTemp( m ) ) * ( xyz_Temp (i,j,k) - a_TableTemp( m+1 ) ) / ( ( a_TableTemp( m-1 ) - a_TableTemp( m ) ) * ( a_TableTemp( m-1 ) - a_TableTemp( m+1 ) ) ) + aa_TableIPF(m ,iband) * ( xyz_Temp (i,j,k) - a_TableTemp( m-1 ) ) * ( xyz_Temp (i,j,k) - a_TableTemp( m+1 ) ) / ( ( a_TableTemp( m ) - a_TableTemp( m-1 ) ) * ( a_TableTemp( m ) - a_TableTemp( m+1 ) ) ) + aa_TableIPF(m+1,iband) * ( xyz_Temp (i,j,k) - a_TableTemp( m-1 ) ) * ( xyz_Temp (i,j,k) - a_TableTemp( m ) ) / ( ( a_TableTemp( m+1 ) - a_TableTemp( m-1 ) ) * ( a_TableTemp( m+1 ) - a_TableTemp( m ) ) )
end do
end do
end do
else
do k = 1, km
do j = js, je
do i = 0, imax-1
m = xyz_TempIndex(i,j,k)
!!$ xyz_IntegPF(i,j,k) = &
!!$ & ( aa_TableIDPFDT( m, iband ) - aa_TableIDPFDT( m-1, iband ) ) &
!!$ & / ( a_TableTemp ( m ) - a_TableTemp ( m-1 ) ) &
!!$ & * ( xyz_Temp(i,j,k) - a_TableTemp( m-1 ) ) &
!!$ & + aa_TableIDPFDT( m-1, iband )
xyz_IntegPF(i,j,k) = aa_TableIDPFDT(m-1,iband) * ( xyz_Temp (i,j,k) - a_TableTemp( m ) ) * ( xyz_Temp (i,j,k) - a_TableTemp( m+1 ) ) / ( ( a_TableTemp( m-1 ) - a_TableTemp( m ) ) * ( a_TableTemp( m-1 ) - a_TableTemp( m+1 ) ) ) + aa_TableIDPFDT(m ,iband) * ( xyz_Temp (i,j,k) - a_TableTemp( m-1 ) ) * ( xyz_Temp (i,j,k) - a_TableTemp( m+1 ) ) / ( ( a_TableTemp( m ) - a_TableTemp( m-1 ) ) * ( a_TableTemp( m ) - a_TableTemp( m+1 ) ) ) + aa_TableIDPFDT(m+1,iband) * ( xyz_Temp (i,j,k) - a_TableTemp( m-1 ) ) * ( xyz_Temp (i,j,k) - a_TableTemp( m ) ) / ( ( a_TableTemp( m+1 ) - a_TableTemp( m-1 ) ) * ( a_TableTemp( m+1 ) - a_TableTemp( m ) ) )
end do
end do
end do
end if
end subroutine CalcIntegratedPFWithTable3D
| Variable : | |||
| IntTimeSave : | real(DP), save
|
| Variable : | |||
| PrevTimeSave : | real(DP), save
|
| Subroutine : | |
| xyz_QCO2(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyz_Temp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyz_QVap(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyz_QO3(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyr_Press(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(in ) |
| xyz_Press(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyz_CloudDelOptDep(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| flag_dry_atmosphere : | logical , intent(in ) |
| js : | integer , intent(in ) |
| je : | integer , intent(in ) |
subroutine RadiationRL78CalcTotTrans( xyz_QCO2, xyz_Temp, xyz_QVap, xyz_QO3, xyr_Press, xyz_Press, xyz_CloudDelOptDep, flag_dry_atmosphere, js, je )
! USE statements
!
!
! Grid points settings
!
use gridset, only: imax, jmax, kmax !
! Number of vertical level
!
! Physical constants settings
!
use constants, only: Grav ! $ g $ [m s-2].
!
! Gravitational acceleration
real(DP), intent(in ):: xyz_QCO2 (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyz_QVap (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyz_QO3 (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyr_Press (0:imax-1, 1:jmax, 0:kmax)
real(DP), intent(in ):: xyz_Press (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyz_CloudDelOptDep(0:imax-1, 1:jmax, 1:kmax)
logical , intent(in ):: flag_dry_atmosphere
integer , intent(in ):: js
integer , intent(in ):: je
!
! Work variables
!
real(DP):: RefPress
real(DP):: xyz_H2ODelAbsAmt (0:imax-1, 1:jmax, 1:kmax)
real(DP):: xyz_H2ODelScaledAbsAmt(0:imax-1, 1:jmax, 1:kmax)
real(DP):: xyz_CO2DelScaledAbsAmt(0:imax-1, 1:jmax, 1:kmax)
real(DP):: xyz_O3DelScaledAbsAmt (0:imax-1, 1:jmax, 1:kmax)
real(DP):: xyrr_TransCO2 (0:imax-1, 1:jmax, 0:kmax, 0:kmax)
real(DP):: xyz_TransCloudOneLayer(0:imax-1, 1:jmax, 1:kmax)
real(DP):: xyrr_TransCloud (0:imax-1, 1:jmax, 0:kmax, 0:kmax)
real(DP):: xyrr_Trans (0:imax-1, 1:jmax, 0:kmax, 0:kmax)
integer :: j, k, k1, k2
integer :: n
if ( sw_fs ) then
call RadiationRoeweLiouInit
end if
do k = 1, kmax
do j = js, je
xyz_H2ODelAbsAmt(:,j,k) = xyz_QVap(:,j,k) * ( xyr_Press(:,j,k-1) - xyr_Press(:,j,k) ) / Grav
end do
end do
RefPress = 1.0d5
do k = 1, kmax
do j = js, je
xyz_H2ODelScaledAbsAmt(:,j,k) = ( xyz_Press(:,j,k) / RefPress )**H2OScaleIndex * xyz_QVap(:,j,k) * ( xyr_Press(:,j,k-1) - xyr_Press(:,j,k) ) / Grav
end do
end do
do k = 1, kmax
do j = js, je
xyz_CO2DelScaledAbsAmt(:,j,k) = ( xyz_Press(:,j,k) / RefPress )**CO2ScaleIndex * xyz_QCO2(:,j,k) * ( xyr_Press(:,j,k-1) - xyr_Press(:,j,k) ) / Grav
end do
end do
do k = 1, kmax
do j = js, je
xyz_O3DelScaledAbsAmt(:,j,k) = ( xyz_Press(:,j,k) / RefPress )**O3ScaleIndex * xyz_QO3(:,j,k) * ( xyr_Press(:,j,k-1) - xyr_Press(:,j,k) ) / Grav
end do
end do
!-----
! Transmission in CO2 15 micron band
!
call RadiationRoeweLiouCalcCO2Trans( xyz_CO2DelScaledAbsAmt, xyrr_TransCO2, js, je )
!-----
! Transmission by cloud
!!$ if ( all( xyz_CloudDelOptDep <= 0.0d0 ) ) then
!!$
!!$ xyrr_TransCloud(:,:,:,:) = 1.0d0
!!$
!!$ else
do k = 1, kmax
do j = js, je
xyz_TransCloudOneLayer(:,j,k) = exp( - xyz_CloudDelOptDep(:,j,k) * DiffFactor )
end do
end do
do k1 = 0, kmax
k2 = k1
do j = js, je
xyrr_TransCloud(:,j,k1,k2) = 1.0d0
end do
do k2 = k1+1, kmax
do j = js, je
xyrr_TransCloud(:,j,k1,k2) = xyrr_TransCloud(:,j,k1,k2-1) * xyz_TransCloudOneLayer(:,j,k2)
end do
end do
end do
do k1 = 0, kmax
do k2 = 0, k1-1
do j = js, je
xyrr_TransCloud(:,j,k1,k2) = xyrr_TransCloud(:,j,k2,k1)
end do
end do
end do
!!$ end if
!-----
do n = 1, nbmax
if ( n <= 5 ) then
! H2O band
if ( flag_dry_atmosphere ) then
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
else
call RadiationRoeweLiouCalcBandTrans( n, xyz_H2ODelScaledAbsAmt, xyrr_Trans, js, je )
end if
else if ( n <= 8 ) then
! H2O band & CO2 band
if ( flag_dry_atmosphere ) then
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
else
call RadiationRoeweLiouCalcBandTrans( n, xyz_H2ODelScaledAbsAmt, xyrr_Trans, js, je )
end if
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = xyrr_Trans(:,j,k1,k2) * xyrr_TransCO2(:,j,k1,k2)
end do
end do
end do
else if ( n == 9 ) then
! H2O band
if ( flag_dry_atmosphere ) then
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
else
call RadiationRoeweLiouCalcBandTrans( n, xyz_H2ODelScaledAbsAmt, xyrr_Trans, js, je )
end if
else if ( n == 10 ) then
! H2O band & continuum
if ( flag_dry_atmosphere ) then
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
else
call RadiationRoeweLiouCalcBandTrans( n, xyz_H2ODelScaledAbsAmt, xyrr_Trans, js, je )
call RadiationRLCalcH2OContTrans( n, xyz_Temp, xyz_QVap, xyz_Press, xyz_H2ODelAbsAmt, xyrr_Trans )
end if
else if ( n == 11 ) then
! H2O continuum
if ( flag_dry_atmosphere ) then
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
else
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
call RadiationRLCalcH2OContTrans( n, xyz_Temp, xyz_QVap, xyz_Press, xyz_H2ODelAbsAmt, xyrr_Trans )
end if
else if ( n <= 21 ) then
! O3 band & H2O continuum
call RadiationRoeweLiouCalcBandTrans( n, xyz_O3DelScaledAbsAmt, xyrr_Trans, js, je )
if ( flag_dry_atmosphere ) then
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = xyrr_Trans(:,j,k1,k2)
end do
end do
end do
else
call RadiationRLCalcH2OContTrans( n, xyz_Temp, xyz_QVap, xyz_Press, xyz_H2ODelAbsAmt, xyrr_Trans )
end if
else if ( n == 22 ) then
! H2O continuum
if ( flag_dry_atmosphere ) then
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
else
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
call RadiationRLCalcH2OContTrans( n, xyz_Temp, xyz_QVap, xyz_Press, xyz_H2ODelAbsAmt, xyrr_Trans )
end if
else if ( n <= 31 ) then
! H2O band
if ( flag_dry_atmosphere ) then
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
else
call RadiationRoeweLiouCalcBandTrans( n, xyz_H2ODelScaledAbsAmt, xyrr_Trans, js, je )
end if
else if ( n == 32 ) then
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end do
else
write( 6, * ) 'Unexpected number of band, ', n, '.'
stop
end if
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = xyrr_Trans(:,j,k1,k2) * xyrr_TransCloud(:,j,k1,k2)
xyrra_TransSave(:,j,k1,k2,n) = xyrr_Trans(:,j,k1,k2)
end do
end do
end do
end do
end subroutine RadiationRL78CalcTotTrans
| Subroutine : | |
| a_TransFlag(1:nbmax) : | logical , intent(in ) |
| xyz_Temp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xy_SurfTemp(0:imax-1, 1:jmax) : | real(DP), intent(in ) |
| xyr_RadLFlux(0:imax-1, 1:jmax, 0:kmax) : | real(DP), intent(out) |
| xyra_DelRadLFlux(0:imax-1, 1:jmax, 0:kmax, 0:1) : | real(DP), intent(out) |
| js : | integer , intent(in ) |
| je : | integer , intent(in ) |
subroutine RadiationRL78IntegRTE( a_TransFlag, xyz_Temp, xy_SurfTemp, xyr_RadLFlux, xyra_DelRadLFlux, js, je )
! USE statements
!
!
! Grid points settings
!
use gridset, only: imax, jmax, kmax !
! Number of vertical level
!
! Physical constants settings
!
use constants, only: PI ! $ \pi $ .
! Circular constant
logical , intent(in ):: a_TransFlag (1:nbmax)
real(DP), intent(in ):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xy_SurfTemp (0:imax-1, 1:jmax)
real(DP), intent(out):: xyr_RadLFlux (0:imax-1, 1:jmax, 0:kmax)
real(DP), intent(out):: xyra_DelRadLFlux(0:imax-1, 1:jmax, 0:kmax, 0:1)
integer , intent(in ):: js
integer , intent(in ):: je
!
! Work variables
!
real(DP):: xyrr_Trans (0:imax-1, 1:jmax, 0:kmax, 0:kmax)
real(DP):: xyz_PlankFunc (0:imax-1, 1:jmax, 1:kmax)
real(DP):: xy_SurfPlankFunc (0:imax-1, 1:jmax)
real(DP):: xy_DPFDT0 (0:imax-1, 1:jmax)
real(DP):: xy_DPFDT1 (0:imax-1, 1:jmax)
integer :: j
integer :: k, kk, k1, k2
integer :: l
integer :: n
do k = 0, kmax
do j = js, je
xyr_RadLFlux(:,j,k) = 0.0d0
end do
end do
do l = 0, 1
do k = 0, kmax
do j = js, je
xyra_DelRadLFlux(:,j,k,l) = 0.0d0
end do
end do
end do
LOOP_band: do n = 1, nbmax
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_Trans(:,j,k1,k2) = xyrra_TransSave(:,j,k1,k2,n)
end do
end do
end do
if ( a_TransFlag(n) ) then
call CalcIntegratedPFWithTable2D( n, xy_SurfTemp, xy_SurfPlankFunc, js, je )
do k = 0, kmax
do j = js, je
xyr_RadLFlux(:,j,k) = xyr_RadLFlux(:,j,k) + PI * xy_SurfPlankFunc(:,j) ! * xyrr_Trans(:,:,0,k)
end do
end do
call CalcIntegratedPFWithTable2D( n, xy_SurfTemp, xy_DPFDT0, js, je, .true. )
do k = 0, kmax
do j = js, je
xyra_DelRadLFlux(:,j,k,0) = xyra_DelRadLFlux(:,j,k,0) + PI * xy_DPFDT0(:,j) ! * xyrr_Trans(:,:,0,k)
end do
end do
else
call CalcIntegratedPFWithTable2D( n, xy_SurfTemp, xy_SurfPlankFunc, js, je )
call CalcIntegratedPFWithTable3D( n, kmax, xyz_Temp, xyz_PlankFunc, js, je )
do k = 0, kmax
do j = js, je
xyr_RadLFlux(:,j,k) = xyr_RadLFlux(:,j,k) + PI * xy_SurfPlankFunc(:,j) * xyrr_Trans(:,j,0,k)
end do
do kk = 1, kmax
do j = js, je
xyr_RadLFlux(:,j,k) = xyr_RadLFlux(:,j,k) - PI * xyz_PlankFunc(:,j,kk) * ( xyrr_Trans(:,j,k,kk-1) - xyrr_Trans(:,j,k,kk) )
end do
end do
end do
call CalcIntegratedPFWithTable2D( n, xy_SurfTemp, xy_DPFDT0, js, je, .true. )
call CalcIntegratedPFWithTable2D( n, xyz_Temp(:,:,1), xy_DPFDT1, js, je, .true. )
do k = 0, kmax
do j = js, je
xyra_DelRadLFlux(:,j,k,0) = xyra_DelRadLFlux(:,j,k,0) + PI * xy_DPFDT0(:,j) * xyrr_Trans(:,j,0,k)
xyra_DelRadLFlux(:,j,k,1) = xyra_DelRadLFlux(:,j,k,1) - PI * xy_DPFDT1(:,j) * ( xyrr_Trans(:,j,k,0) - xyrr_Trans(:,j,k,1) )
end do
end do
end if
end do LOOP_band
end subroutine RadiationRL78IntegRTE
| Subroutine : | |
| iband : | integer , intent(in ) |
| xyz_Temp(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyz_QVap(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyz_Press(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyz_H2ODelAbsAmt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyrr_Trans(0:imax-1, 1:jmax, 0:kmax, 0:kmax) : | real(DP), intent(inout) |
subroutine RadiationRLCalcH2OContTrans( iband, xyz_Temp, xyz_QVap, xyz_Press, xyz_H2ODelAbsAmt, xyrr_Trans )
! USE statements
!
!
! Grid points settings
!
use gridset, only: imax, jmax, kmax !
! Number of vertical level
integer , intent(in ):: iband
real(DP), intent(in ):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyz_QVap (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyz_Press (0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(in ):: xyz_H2ODelAbsAmt(0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(inout):: xyrr_Trans (0:imax-1, 1:jmax, 0:kmax, 0:kmax)
!
! Work variables
!
real(DP):: H2OContConstant
real(DP):: a_H2OContParam(3)
real(DP):: RefTemp
real(DP):: gamma
real(DP):: xyz_PressH2O (0:imax-1, 1:jmax, 1:kmax)
real(DP):: xyz_DelOptDep (0:imax-1, 1:jmax, 1:kmax)
real(DP):: xyrr_H2OContOptDep(0:imax-1, 1:jmax, 0:kmax, 0:kmax)
integer :: k1
integer :: k2
integer :: k3
integer :: n
if ( ( iband < 9 ) .and. ( iband > 11 ) ) then
write( 6, * ) 'Unexpected number of band in RadiationRLCalcH2OContTrans.'
stop
end if
! These constants are obtained from Roberts et al. (1976) [Applied Optics]
a_H2OContParam(1) = 1.25d-22 ! mol-1 cm2 atm-1
a_H2OContParam(2) = 1.67d-19 ! mol-1 cm2 atm-1
a_H2OContParam(3) = 7.87d-3 ! (cm)
! unit conversion
a_H2OContParam(1) = a_H2OContParam(1) / ( H2OMolWeight / AvogNum ) * 1.0d-4 / 101325.0d0 ! (kg-1 m2 Pa-1)
a_H2OContParam(2) = a_H2OContParam(2) / ( H2OMolWeight / AvogNum ) * 1.0d-4 / 101325.0d0 ! (kg-1 m2 Pa-1)
a_H2OContParam(3) = a_H2OContParam(3) * 1.0d-2 ! (m)
n = iband
! This constant is deribed from Roberts et al. (1976) [Applied Optics]
!!$ gamma = 0.005d0
gamma = 0.0d0
xyz_PressH2O = xyz_Press * xyz_QVap * MeanMolWeight / H2OMolWeight
RefTemp = 1800.0d0
H2OContConstant = a_H2OContParam(1) + a_H2OContParam(2) * exp( - a_H2OContParam(3) * ( a_BandParam(1,n) + a_BandParam(2,n) ) * 0.5d0 )
xyz_DelOptDep = H2OContConstant * exp( RefTemp * ( 1.0d0 / xyz_Temp - 1.0d0 / 296.0d0 ) ) * ( xyz_PressH2O + gamma * ( xyz_Press - xyz_PressH2O ) ) * xyz_H2ODelAbsAmt
xyrr_H2OContOptDep(:,:,:,:) = 0.0d0
do k1 = 0, kmax
do k2 = k1, kmax
do k3 = k1+1, k2
xyrr_H2OContOptDep(:,:,k1,k2) = xyrr_H2OContOptDep(:,:,k1,k2) + xyz_DelOptDep(:,:,k3)
end do
xyrr_H2OContOptDep(:,:,k1,k2) = xyrr_H2OContOptDep(:,:,k1,k2) * DiffFactor
xyrr_Trans(:,:,k1,k2) = xyrr_Trans(:,:,k1,k2) * exp( - xyrr_H2OContOptDep(:,:,k1,k2) )
end do
end do
do k1 = 0, kmax
do k2 = 0, k1-1
xyrr_Trans(:,:,k1,k2) = xyrr_Trans(:,:,k2,k1)
end do
end do
do k1 = 0, kmax
k2 = k1
xyrr_Trans(:,:,k1,k2) = 1.0d0
end do
end subroutine RadiationRLCalcH2OContTrans
| Subroutine : | |
| iband : | integer , intent(in ) |
| xyz_DelScaledAbsAmt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyrr_Trans(0:imax-1, 1:jmax, 0:kmax, 0:kmax) : | real(DP), intent(out) |
| js : | integer , intent(in ) |
| je : | integer , intent(in ) |
subroutine RadiationRoeweLiouCalcBandTrans( iband, xyz_DelScaledAbsAmt, xyrr_Trans, js, je )
! USE statements
!
!
! Grid points settings
!
use gridset, only: imax, jmax, kmax !
! Number of vertical level
integer , intent(in ):: iband
real(DP), intent(in ):: xyz_DelScaledAbsAmt(0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(out):: xyrr_Trans (0:imax-1, 1:jmax, 0:kmax, 0:kmax)
integer , intent(in ):: js
integer , intent(in ):: je
!
! Work variables
!
real(DP):: xyrr_AbsAmt(0:imax-1, 1:jmax, 0:kmax, 0:kmax)
integer :: j
integer :: k1
integer :: k2
integer :: k3
integer :: n
n = iband
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_AbsAmt(:,j,k1,k2) = 0.0d0
end do
end do
end do
do k1 = 0, kmax
do k2 = k1, kmax
do k3 = k1+1, k2
do j = js, je
xyrr_AbsAmt(:,j,k1,k2) = xyrr_AbsAmt(:,j,k1,k2) + xyz_DelScaledAbsAmt(:,j,k3)
end do
end do
do j = js, je
xyrr_AbsAmt(:,j,k1,k2) = xyrr_AbsAmt(:,j,k1,k2) * DiffFactor
end do
do j = js, je
xyrr_Trans(:,j,k1,k2) = - a_BandParam(3,n) * xyrr_AbsAmt(:,j,k1,k2) / sqrt( 1.0d0 + a_BandParam(3,n) / a_BandParam(4,n) * xyrr_AbsAmt(:,j,k1,k2) )
xyrr_Trans(:,j,k1,k2) = exp( xyrr_Trans(:,j,k1,k2) )
end do
end do
end do
do k1 = 0, kmax
do k2 = 0, k1-1
do j = js, je
xyrr_Trans(:,j,k1,k2) = xyrr_Trans(:,j,k2,k1)
end do
end do
end do
do k1 = 0, kmax
k2 = k1
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end subroutine RadiationRoeweLiouCalcBandTrans
| Subroutine : | |
| xyz_CO2DelScaledAbsAmt(0:imax-1, 1:jmax, 1:kmax) : | real(DP), intent(in ) |
| xyrr_Trans(0:imax-1, 1:jmax, 0:kmax, 0:kmax) : | real(DP), intent(out) |
| js : | integer , intent(in ) |
| je : | integer , intent(in ) |
subroutine RadiationRoeweLiouCalcCO2Trans( xyz_CO2DelScaledAbsAmt, xyrr_Trans, js, je )
! USE statements
!
!
! Grid points settings
!
use gridset, only: imax, jmax, kmax !
! Number of vertical level
!!$ integer , intent(in ):: iband
real(DP), intent(in ):: xyz_CO2DelScaledAbsAmt(0:imax-1, 1:jmax, 1:kmax)
real(DP), intent(out):: xyrr_Trans (0:imax-1, 1:jmax, 0:kmax, 0:kmax)
integer , intent(in ):: js
integer , intent(in ):: je
!
! Work variables
!
real(DP):: xyrr_AbsAmt (0:imax-1, 1:jmax, 0:kmax, 0:kmax)
integer :: j
integer :: k1
integer :: k2
integer :: k3
!!$ integer :: n
!!$ n = iband
!!$ n = 2
do k2 = 0, kmax
do k1 = 0, kmax
do j = js, je
xyrr_AbsAmt(:,j,k1,k2) = 0.0d0
end do
end do
end do
do k1 = 0, kmax
do k2 = k1, kmax
do k3 = k1+1, k2
do j = js, je
xyrr_AbsAmt(:,j,k1,k2) = xyrr_AbsAmt(:,j,k1,k2) + xyz_CO2DelScaledAbsAmt(:,j,k3)
end do
end do
do j = js, je
xyrr_AbsAmt(:,j,k1,k2) = xyrr_AbsAmt(:,j,k1,k2) * DiffFactor
end do
do j = js, je
xyrr_Trans(:,j,k1,k2) = - a_CO2BandParam(3) * xyrr_AbsAmt(:,j,k1,k2) / sqrt( 1.0d0 + a_CO2BandParam(3) / a_CO2BandParam(4) * xyrr_AbsAmt(:,j,k1,k2) )
xyrr_Trans(:,j,k1,k2) = exp( xyrr_Trans(:,j,k1,k2) )
end do
end do
end do
do k1 = 0, kmax
do k2 = 0, k1-1
do j = js, je
xyrr_Trans(:,j,k1,k2) = xyrr_Trans(:,j,k2,k1)
end do
end do
end do
do k1 = 0, kmax
k2 = k1
do j = js, je
xyrr_Trans(:,j,k1,k2) = 1.0d0
end do
end do
end subroutine RadiationRoeweLiouCalcCO2Trans
| Subroutine : |
This procedure input/output NAMELIST#radiation_RL78_nml .
subroutine RadiationRoeweLiouInit
!
! Grid points settings
!
use gridset, only: imax, jmax, kmax !
! Number of vertical level
! メッセージ出力
! Message output
!
use dc_message, only: MessageNotify
! ファイル入出力補助
! File I/O support
!
use dc_iounit, only: FileOpen
! NAMELIST ファイル入力に関するユーティリティ
! Utilities for NAMELIST file input
!
use namelist_util, only: namelist_filename, NmlutilMsg, NmlutilAryValid
! 暦と日時の取り扱い
! Calendar and Date handler
!
use dc_calendar, only: DCCalConvertByUnit
! ガウス重み, 分点の計算
! Calculate Gauss node and Gaussian weight
!
use gauss_quad, only : GauLeg
! プランク関数の計算
! Calculate Planck function
!
use planck_func, only : PF, DPFDT, Integ_PF_GQ_Array2D, Integ_DPFDT_GQ_Array2D
real(DP) :: DelTimeCalcTransValue
character(STRING) :: DelTimeCalcTransUnit
integer:: unit_nml ! NAMELIST ファイルオープン用装置番号.
! Unit number for NAMELIST file open
integer:: iostat_nml ! NAMELIST 読み込み時の IOSTAT.
! IOSTAT of NAMELIST read
logical :: FlagCheckLoopExit
real(DP) :: xy_TempTMP (0:imax-1, 1:jmax)
real(DP) :: xy_PF (0:imax-1, 1:jmax)
real(DP) :: xy_DPFDT (0:imax-1, 1:jmax)
real(DP) :: xy_PFTable (0:imax-1, 1:jmax)
real(DP) :: xy_DPFDTTable(0:imax-1, 1:jmax)
real(DP) :: ErrorPFInteg
real(DP), parameter:: ThresholdErrorPFInteg = 1.0d-3
! Threshold for checking accuracy of calculation of
! integrated Planc function by using a pre-calculated
! table.
! Variables for preparation for calculation of Plank function
!
real(DP) , allocatable :: GQP(:)
real(DP) , allocatable :: GQW(:)
integer:: i
integer:: j
integer:: l
integer:: m
integer:: n
namelist /radiation_RL78_nml/ VMRCO2, DelTimeCalcTransValue, DelTimeCalcTransUnit, flag_save_time
VMRCO2 = 382.0d-6
DelTimeCalcTransValue = 3.0
DelTimeCalcTransUnit = 'hrs'
flag_save_time = .false.
! NAMELIST is input
!
if ( trim(namelist_filename) /= '' ) then
call FileOpen( unit_nml, namelist_filename, mode = 'r' ) ! (in)
rewind( unit_nml )
read( unit_nml, nml = radiation_RL78_nml, iostat = iostat_nml ) ! (out)
close( unit_nml )
call NmlutilMsg( iostat_nml, module_name ) ! (in)
end if
! Handle interval time
!
IntTimeSave = DCCalConvertByUnit( DelTimeCalcTransValue, DelTimeCalcTransUnit, 'sec' ) ! (in)
!!$ do n = 1, nbmax
!!$ ! unit conversion from (cm-1) to (m-1)
!!$ a_BandParam(1,n) = a_BandParam(1,n) * 1.0d2
!!$ a_BandParam(2,n) = a_BandParam(2,n) * 1.0d2
!!$ ! unit conversion from (g-1 cm2) to (kg-1 m2)
!!$ a_BandParam(3,n) = a_BandParam(3,n) * 1.0d-4 * 1.0d3
!!$ end do
do n = 1, 12-1
! unit conversion from (cm-1) to (m-1)
a_BandParam(1,n) = a_BandParam(1,n) * 1.0d2
a_BandParam(2,n) = a_BandParam(2,n) * 1.0d2
! unit conversion from (g-1 cm2) to (kg-1 m2)
a_BandParam(3,n) = a_BandParam(3,n) * 1.0d-4 * 1.0d3
end do
! O3 unit conversion
do n = 12, 21
! unit conversion from (cm-1) to (m-1)
a_BandParam(1,n) = a_BandParam(1,n) * 1.0d2
a_BandParam(2,n) = a_BandParam(2,n) * 1.0d2
! unit conversion from "wrong (g-1 cm2)" to (kg-1 m2)
! The values written by Roewe and Liou (1978) seems to be wrong.
! In order to convert cm-1 atm-1 to g-1 cm2, the value has to be MULTIPLIED
! by ~400.
! The factor ~400 is
! 1.0d2 / 101325.0d0 * 8.31432d0 / ( 48.0d-3 ) * 233.0d0 * 1.0d4 * 1.0d-3.
! However, it seems that the value was DIVIDED by ~400 to convert the value
! in cm-1 atm-1 to g-1 cm2 by Roewe and Liou (1978).
! So, first, the value written in Roewe and Liou (1978) is multiplied by ~400
! to obtain the correct value in cm-1 atm-1.
! Then the value is multiplied by ~40 to convert unit from cm-1 atm-1 to m2 kg-1.
! The factor ~40 is
! 1.0d2 / 101325.0d0 * 8.31432d0 / ( 48.0d-3 ) * 233.0d0.
a_BandParam(3,n) = a_BandParam(3,n) * 1.0d2 / 101325.0d0 * 8.31432d0 / ( 48.0d-3 ) * 233.0d0 * 1.0d4 * 1.0d-3 * 1.0d2 / 101325.0d0 * 8.31432d0 / ( 48.0d-3 ) * 233.0d0
end do
do n = 21+1, nbmax
! unit conversion from (cm-1) to (m-1)
a_BandParam(1,n) = a_BandParam(1,n) * 1.0d2
a_BandParam(2,n) = a_BandParam(2,n) * 1.0d2
! unit conversion from (g-1 cm2) to (kg-1 m2)
a_BandParam(3,n) = a_BandParam(3,n) * 1.0d-4 * 1.0d3
end do
!!$ do n = 1, nbH2Omax
!!$ ! unit conversion from (cm-1) to (m-1)
!!$ a_H2OBandParam(1,n) = a_H2OBandParam(1,n) * 1.0d2
!!$ a_H2OBandParam(2,n) = a_H2OBandParam(2,n) * 1.0d2
!!$ ! unit conversion from (g-1 cm2) to (kg-1 m2)
!!$ a_H2OBandParam(3,n) = a_H2OBandParam(3,n) * 1.0d-4 * 1.0d3
!!$
!!$ ! unit conversion from (cm-1) to (m-1)
!!$ a_H2OContParam(1,n) = a_H2OContParam(1,n) * 1.0d2
!!$ a_H2OContParam(2,n) = a_H2OContParam(2,n) * 1.0d2
!!$ ! unit conversion from (g-1 cm2 atm-1) to (kg-1 m2 Pa-1)
!!$ a_H2OContParam(3,n) = a_H2OContParam(3,n) * 1.0d-4 * 1.0d3 * 1.0d-5
!!$ end do
! unit conversion from (cm-1) to (m-1)
a_CO2BandParam(1) = a_CO2BandParam(1) * 1.0d2
a_CO2BandParam(2) = a_CO2BandParam(2) * 1.0d2
! unit conversion from (g-1 cm2) to (kg-1 m2)
a_CO2BandParam(3) = a_CO2BandParam(3) * 1.0d-4 * 1.0d3
!!$ do n = 1, nbO3max
!!$ ! unit conversion from (cm-1) to (m-1)
!!$ a_O3BandParam(1,n) = a_O3BandParam(1,n) * 1.0d2
!!$ a_O3BandParam(2,n) = a_O3BandParam(2,n) * 1.0d2
!!$ ! unit conversion from (g-1 cm2) to (kg-1 m2)
!!$ a_O3BandParam(3,n) = a_O3BandParam(3,n) * 1.0d-4 * 1.0d3
!!$ end do
!!$ do n = 1, 3
!!$ ! unit conversion from (cm-1) to (m-1)
!!$ a_TMPFORO3BandParam(1,n) = a_TMPFORO3BandParam(1,n) * 1.0d2
!!$ a_TMPFORO3BandParam(2,n) = a_TMPFORO3BandParam(2,n) * 1.0d2
!!$ ! unit conversion from (g-1 cm2) to (kg-1 m2)
!!$ a_TMPFORO3BandParam(3,n) = a_TMPFORO3BandParam(3,n) * 1.0d-4 * 1.0d3
!!$ end do
! Values by Miyoshi and Morita (19??)
!
H2OScaleIndex = 1.0d0
CO2ScaleIndex = 0.9d0
O3ScaleIndex = 0.4d0
NGaussQuad = 5
MeanMolWeight = 28.0d-3
H2OMolWeight = 18.0d-3
CO2MolWeight = 44.0d-3
allocate( xyrra_TransSave (0:imax-1, 1:jmax, 0:kmax, 0:kmax, 1:nbmax) )
! Preparation of tables for calculation of Plank function
!
TableTempMin = 50.0d0
TableTempMax = 600.0d0
TableTempIncrement = 0.1d0
ntmax = ( TableTempMax - TableTempMin ) / TableTempIncrement + 1
allocate( a_TableTemp (1:ntmax) )
allocate( aa_TableIPF (1:ntmax, 1:nbmax) )
allocate( aa_TableIDPFDT(1:ntmax, 1:nbmax) )
do m = 1, ntmax
a_TableTemp(m) = TableTempMin + TableTempIncrement * ( m - 1 )
end do
aa_TableIPF (:,:) = 0.0d0
aa_TableIDPFDT(:,:) = 0.0d0
allocate( GQP(1:NGaussQuad) )
allocate( GQW(1:NGaussQuad) )
do n = 1, nbmax
call GauLeg( a_BandParam(1,n), a_BandParam(2,n), NGaussQuad, GQP, GQW )
do m = 1, ntmax
do l = 1, NGaussQuad
aa_TableIPF (m,n) = aa_TableIPF (m,n) + PF ( GQP(l), a_TableTemp(m) ) * GQW(l)
aa_TableIDPFDT(m,n) = aa_TableIDPFDT(m,n) + DPFDT( GQP(l), a_TableTemp(m) ) * GQW(l)
end do
end do
end do
deallocate( GQP )
deallocate( GQW )
!----------------------------------------------------
! Check accuracy of integration of Planc function by using a pre-calculated table.
!
! This routine is called once here, to initialize a pre-calculated table.
n = 1
xy_TempTMP = 300.0d0
call CalcIntegratedPFWithTable2D( n, xy_TempTMP, xy_PFTable, 1, jmax, .false. )
do n = 1, nbmax
FlagCheckLoopExit = .false.
l = 1
do
do j = 1, jmax
do i = 0, imax-1
xy_TempTMP(i,j) = a_TableTemp(1) + ( a_TableTemp(2) - a_TableTemp(1) ) * 0.5d0 + ( a_TableTemp(2) - a_TableTemp(1) ) * ( imax * jmax * ( l - 1 ) + imax * ( j - 1 ) + i )
end do
end do
do j = 1, jmax
do i = 0, imax-1
if ( xy_TempTMP(i,j) > a_TableTemp(ntmax) ) then
xy_TempTMP(i,j) = a_TableTemp(ntmax)
FlagCheckLoopExit = .true.
end if
end do
end do
call Integ_PF_GQ_Array2D( a_BandParam(1,n), a_BandParam(2,n), NGaussQuad, 0, imax-1, 1, jmax, xy_TempTMP, xy_PF )
call Integ_DPFDT_GQ_Array2D( 0, imax-1, 1, jmax, a_BandParam(1,n), a_BandParam(2,n), NGaussQuad, xy_TempTMP, xy_DPFDT )
call CalcIntegratedPFWithTable2D( n, xy_TempTMP, xy_PFTable, 1, jmax, .false. )
call CalcIntegratedPFWithTable2D( n, xy_TempTMP, xy_DPFDTTable, 1, jmax, .true. )
do j = 1, jmax
do i = 0, imax-1
ErrorPFInteg = abs( xy_PF (i,j) - xy_PFTable (i,j) ) / xy_PF (i,j)
if ( ErrorPFInteg > ThresholdErrorPFInteg ) then
call MessageNotify( 'E', module_name, 'Error of integrated PF, %f, is greater than threshold, %f, in band %d.', d = (/ ErrorPFInteg, ThresholdErrorPFInteg /), i = (/n/) )
end if
ErrorPFInteg = abs( xy_DPFDT(i,j) - xy_DPFDTTable(i,j) ) / xy_DPFDT(i,j)
if ( ErrorPFInteg > ThresholdErrorPFInteg ) then
call MessageNotify( 'E', module_name, 'Error of integrated DPFDT, %f, is greater than threshold, %f, in band %d', d = (/ ErrorPFInteg, ThresholdErrorPFInteg /), i = (/n/) )
end if
end do
end do
if ( FlagCheckLoopExit ) exit
l = l + 1
end do
end do
!----------------------------------------------------
do n = 1, nRefAtm
RefAtmPro(2,n) = RefAtmPro(2,n) * 1.0d2
!!$ RefAtmPro(5,n) = RefAtmPro(5,n) * 1.0d-3 / ( 48.0d0 * 1.66d-27 ) &
!!$ & / ( RefAtmPro(2,n) / ( 1.38d-23 * RefAtmPro(3,n) ) )
RefAtmPro(5,n) = RefAtmPro(5,n) * 1.0d-3 / ( RefAtmPro(2,n) / ( 8.314d0 / 48.0d-3 * RefAtmPro(3,n) ) )
end do
sw_fs = .false.
! 印字 ; Print
!
call MessageNotify( 'M', module_name, '----- Initialization Messages -----' )
call MessageNotify( 'M', module_name, ' DelTimeCalcTrans = %f [%c]', d = (/ DelTimeCalcTransValue /), c1 = trim( DelTimeCalcTransUnit ) )
call MessageNotify( 'M', module_name, '-- version = %c', c1 = trim(version) )
end subroutine RadiationRoeweLiouInit
| Subroutine : | |
| index : | integer , intent(in ) |
| sw_log : | logical , intent(in ) |
| xyz_Press(0:imax-1,1:jmax,1:kmax) : | real(DP), intent(in ) |
| xyz_Array(0:imax-1,1:jmax,1:kmax) : | real(DP), intent(out) |
subroutine SetRefAtmPro( index, sw_log, xyz_Press, xyz_Array )
use dc_types
use gridset, only: imax, jmax, kmax
integer , intent(in ) :: index
logical , intent(in ) :: sw_log
real(DP), intent(in ) :: xyz_Press(0:imax-1,1:jmax,1:kmax)
real(DP), intent(out) :: xyz_Array(0:imax-1,1:jmax,1:kmax)
!
! local variables
!
real(DP):: z_RefAtmProArray(1:nRefAtm)
integer :: k, kk
if ( sw_log ) then
do k = 1, nRefAtm
z_RefAtmProArray(k) = log( RefAtmPro(index,k) + 1.0d-100 )
end do
else
do k = 1, nRefAtm
z_RefAtmProArray(k) = RefAtmPro(index,k)
end do
end if
do k = 1, kmax
if( xyz_Press(0,1,k) <= RefAtmPro(2,nRefAtm) ) then
xyz_Array(0,1,k) = z_RefAtmProArray(k)
else
search_loop : do kk = 2, nRefAtm
if( RefAtmPro(2,kk) < xyz_Press(0,1,k) ) exit search_loop
end do search_loop
if( kk > nRefAtm ) stop 'Unexpected error in setting temperature profile'
xyz_Array(0,1,k) = ( z_RefAtmProArray( kk ) - z_RefAtmProArray( kk-1 ) ) / ( log( RefAtmPro(2,kk) / RefAtmPro(2,kk-1) ) ) * ( log( xyz_Press(0,1,k) / RefAtmPro(2,kk-1) ) ) + z_RefAtmProArray( kk-1 )
end if
end do
if ( sw_log ) then
do k = 1, kmax
xyz_Array(0,1,k) = exp( xyz_Array(0,1,k) )
end do
else
do k = 1, kmax
xyz_Array(0,1,k) = xyz_Array(0,1,k)
end do
end if
do k = 1, kmax
xyz_Array(:,:,k) = xyz_Array(0,1,k)
end do
end subroutine SetRefAtmPro
| Constant : | |||
| module_name = ‘radiation_RL78‘ : | character(*), parameter
|
| Constant : | |||
| version = ’$Name: dcpam5-20110221-2 $’ // ’$Id: radiation_RL78.f90,v 1.9 2010-11-14 12:23:59 yot Exp $’ : | character(*), parameter
|