26#include "scaleFElib.h"
37 use scale_atmos_phy_rd_common,
only: &
38 i_up, i_dn, i_lw, i_sw
58 integer,
parameter :: N_LW_BND_MAX = 2
62 integer :: optdep_type
65 real(rp) :: optdep_vallis_eq5_params(4)
69 real(rp) :: optdep_vallis_eq6a_params(2)
71 real(rp) :: optdep_vallis_eq7a_params(4)
73 real(rp) :: optdep_vallis_eq7b_params(4)
75 integer :: optdep_vallis_eq6a_kadd
76 real(rp) :: optdep_vallis_eq6a_qv_above_mot
78 real(rp) :: difffactor
79 real(rp) :: frac_lw(n_lw_bnd_max)
83 procedure,
public :: init => atm_phy_rd_dgm_simple_init
84 procedure,
public :: final => atm_phy_rd_dgm_simple_final
85 procedure,
public :: calculate_rad_flux => atm_phy_rd_dgm_simple_flux
86 procedure,
private :: calc_optical_thick
104 integer,
parameter :: optdep_type_v2018_lwbnd2swbnd1 = 2
115 subroutine atm_phy_rd_dgm_simple_init( this )
119 character(len=H_MID) :: simple_rd_type =
'Gray'
120 character(len=H_MID) :: v2018_gray_optdepth_params_type =
'V2018'
121 real(rp) :: v2018_gray_optdepth_lw_params(4)
123 character(len=H_MID) :: v2018_lwbnd2swbnd1_optdepth_params_type =
'V2018'
124 real(rp) :: v2018_lwbnd2swbnd1_optdepth_sw_params(2)
125 real(rp) :: v2018_lwbnd2swbnd1_optdepth_lw_params(4)
126 real(rp) :: v2018_lwbnd2swbnd1_optdepth_lw_window_params(4)
127 real(rp) :: v2018_lwbnd2swbnd1_lw_window_frac
128 integer :: v2018_lwbnd2swbnd1_optdepth_sw_kadd = 4
129 real(rp) :: v2018_lwbnd2swbnd1_optdepth_sw_qv_above_mot = 1e-3_rp
131 real(rp) :: diffusivityfactor = 1.0_rp
134 real(rp) :: pco2 = 360.0_rp
136 namelist / param_atmos_phy_rd_dgm_simple / &
139 v2018_gray_optdepth_params_type, &
140 v2018_gray_optdepth_lw_params, &
142 v2018_lwbnd2swbnd1_optdepth_params_type, &
143 v2018_lwbnd2swbnd1_optdepth_sw_params, &
144 v2018_lwbnd2swbnd1_optdepth_lw_params, &
145 v2018_lwbnd2swbnd1_optdepth_lw_window_params, &
146 v2018_lwbnd2swbnd1_lw_window_frac, &
147 v2018_lwbnd2swbnd1_optdepth_sw_kadd, &
148 v2018_lwbnd2swbnd1_optdepth_sw_qv_above_mot, &
157 log_info(
"ATMOS_PHY_RD_dgm_simple_setup",*)
'Setup'
161 read(io_fid_conf,nml=param_atmos_phy_rd_dgm_simple,iostat=ierr)
163 log_info(
"ATMOS_PHY_RD_dgm_simple_setup",*)
'Not found namelist. Default used.'
164 elseif( ierr > 0 )
then
165 log_error(
"ATMOS_PHY_RD_dgm_simple_setup",*)
'Not appropriate names in namelist PARAM_ATMOS_PHY_RD_DGM_SIMPLE. Check!'
168 log_nml(param_atmos_phy_rd_dgm_simple)
170 select case(trim(simple_rd_type))
173 this%FRAC_LW = [ 1.0_rp, 0.0_rp ]
174 case(
'LWbnd2+SWbnd1')
175 this%optdep_type = optdep_type_v2018_lwbnd2swbnd1
177 log_error(
"ATMOS_PHY_RD_dgm_simple_setup",*)
'SIMPLE_RD_TYPE is invalid. Check!', trim(simple_rd_type)
182 this%diffFactor = diffusivityfactor
185 select case(trim(v2018_gray_optdepth_params_type))
187 this%OPTDEP_VALLIS_EQ5_PARAMS = [ 0.8678_rp, 1.0_rp, 1997.9_rp, 0.0_rp ]
189 this%OPTDEP_VALLIS_EQ5_PARAMS = [ 0.1627_rp, 1.0_rp, 1997.9_rp, 0.17_rp ]
191 this%OPTDEP_VALLIS_EQ5_PARAMS(:) = v2018_gray_optdepth_lw_params(:)
193 log_error(
"ATMOS_PHY_RD_dgm_simple_setup",*)
'V2018_GRAY_OPTDEPTH_PARAMS_TYPE is invalid. Check!', trim(v2018_gray_optdepth_params_type)
198 if ( this%optdep_type == optdep_type_v2018_lwbnd2swbnd1 )
then
199 select case(trim(v2018_lwbnd2swbnd1_optdepth_params_type))
202 this%OPTDEP_VALLIS_EQ6a_PARAMS = [ 5.96e-2_rp, 2.9e-3_rp ]
203 this%OPTDEP_VALLIS_EQ7a_PARAMS = [ 0.1_rp, 23.8_rp, 254.0_rp, 0.2023_rp ]
204 this%OPTDEP_VALLIS_EQ7b_PARAMS = [ 0.215_rp, 1.4711e2_rp, 1.0814e4_rp, 0.0954_rp ]
205 this%FRAC_LW = [ 0.6268_rp, 0.3732_rp ]
206 this%OPTDEP_VALLIS_EQ6a_kadd = v2018_lwbnd2swbnd1_optdepth_sw_kadd
207 this%OPTDEP_VALLIS_EQ6a_QV_above_MOT = v2018_lwbnd2swbnd1_optdepth_sw_qv_above_mot
209 this%OPTDEP_VALLIS_EQ6a_PARAMS(:) = v2018_lwbnd2swbnd1_optdepth_sw_params(:)
210 this%OPTDEP_VALLIS_EQ7a_PARAMS(:) = v2018_lwbnd2swbnd1_optdepth_lw_params(:)
211 this%OPTDEP_VALLIS_EQ7b_PARAMS(:) = v2018_lwbnd2swbnd1_optdepth_lw_window_params(:)
212 this%FRAC_LW = [ 1.0_rp - v2018_lwbnd2swbnd1_lw_window_frac, v2018_lwbnd2swbnd1_lw_window_frac ]
213 this%OPTDEP_VALLIS_EQ6a_kadd = v2018_lwbnd2swbnd1_optdepth_sw_kadd
214 this%OPTDEP_VALLIS_EQ6a_QV_above_MOT = v2018_lwbnd2swbnd1_optdepth_sw_qv_above_mot
216 log_error(
"ATMOS_PHY_RD_dgm_simple_setup",*)
'V2018_LWbnd2SWbnd1_OPTDEPTH_PARAMS_TYPE is invalid. Check!', trim(v2018_lwbnd2swbnd1_optdepth_params_type)
221 end subroutine atm_phy_rd_dgm_simple_init
225 subroutine atm_phy_rd_dgm_simple_final(this)
230 end subroutine atm_phy_rd_dgm_simple_final
235 subroutine atm_phy_rd_dgm_simple_flux( this, &
236 flux, flux_top, sflx_up, sflx_dn, & ! (out)
237 solins, pres, temp, dens, qv, sfc_temp, sfc_alb, &
238 lcmesh, elem3d, lcmesh2d, elem2d )
239 use scale_const,
only: &
248 real(rp),
intent(out) :: flux(elem3d%nnode_h1d**2,elem3d%nnode_v,lcmesh%ne2d,lcmesh%nez,2,2)
249 real(rp),
intent(out) :: flux_top(elem2d%np,lcmesh2d%ne,2,2)
250 real(rp),
intent(out) :: sflx_up(elem2d%np,lcmesh2d%ne,2)
251 real(rp),
intent(out) :: sflx_dn(elem2d%np,lcmesh2d%ne,2)
252 real(rp),
intent(in) :: pres(elem3d%nnode_v,lcmesh%nez,elem3d%nnode_h1d**2,lcmesh%ne2d)
253 real(rp),
intent(in) :: temp(elem3d%nnode_v,lcmesh%nez,elem3d%nnode_h1d**2,lcmesh%ne2d)
254 real(rp),
intent(in) :: dens(elem3d%nnode_v,lcmesh%nez,elem3d%nnode_h1d**2,lcmesh%ne2d)
255 real(rp),
intent(in) :: qv(elem3d%nnode_v,lcmesh%nez,elem3d%nnode_h1d**2,lcmesh%ne2d)
256 real(rp),
intent(in) :: solins(elem2d%np,lcmesh2d%nea)
257 real(rp),
intent(in) :: sfc_alb(elem2d%np,lcmesh2d%nea)
258 real(rp),
intent(in) :: sfc_temp(elem2d%np,lcmesh2d%nea)
260 integer :: ke, ke_z, ke_h
261 integer :: p, p_z, p_h
263 real(rp) :: dtau_lw(elem3d%nnode_v-1,lcmesh%nez,n_lw_bnd_max)
264 real(rp) :: dtau_sw(elem3d%nnode_v-1,lcmesh%nez)
265 real(rp) :: dtau_sw_kadd
268 real(rp) :: trans_lw(elem3d%nnode_v-1,lcmesh%nez,n_lw_bnd_max)
269 real(rp) :: trans_sw(elem3d%nnode_v-1,lcmesh%nez)
270 real(rp) :: co2(elem3d%nnode_v,lcmesh%nez)
271 real(rp) :: src(elem3d%nnode_v-1,lcmesh%nez)
275 real(rp) :: flux_up_lw(elem3d%nnode_v,lcmesh%nez,n_lw_bnd_max)
276 real(rp) :: flux_dn_lw(elem3d%nnode_v,lcmesh%nez,n_lw_bnd_max)
277 real(rp) :: flux_up_lw_tot(elem3d%nnode_v,lcmesh%nez)
278 real(rp) :: flux_dn_lw_tot(elem3d%nnode_v,lcmesh%nez)
279 real(rp) :: flux_up_sw(elem3d%nnode_v,lcmesh%nez)
280 real(rp) :: flux_dn_sw(elem3d%nnode_v,lcmesh%nez)
285 real(rp) :: r_lw(n_lw_bnd_max)
289 r_lw(:) = this%FRAC_LW(:)
291 select case( this%optdep_type )
294 case( optdep_type_v2018_lwbnd2swbnd1 )
301 do ke_h=1, lcmesh%Ne2D
302 do p_h=1, elem3d%Nnode_h1D**2
304 call this%calc_optical_thick( dtau_lw, dtau_sw, dtau_sw_kadd, &
305 pres(:,:,p_h,ke_h), qv(:,:,p_h,ke_h), co2(:,:), &
306 elem3d%Nnode_v, lcmesh%NeZ )
308 trans_lw(:,:,1:n_lw_bnd) = exp(- d * dtau_lw(:,:,1:n_lw_bnd))
309 trans_sw(:,:) = exp(- dtau_sw(:,:))
312 do ke_z=1, lcmesh%NeZ
313 do p_z=1, elem3d%Nnode_v-1
314 temp_ = 0.5_rp * ( temp(p_z,ke_z,p_h,ke_h) + temp(p_z+1,ke_z,p_h,ke_h) )
315 src(p_z,ke_z) = temp_**4 * stb
321 flux_dn_lw_tot(:,:) = 0.0_rp
322 do bnd_i =1, n_lw_bnd
323 flux_dn_lw(elem3d%Nnode_v,lcmesh%NeZ,bnd_i) = 0.0_rp
324 do ke_z=lcmesh%NeZ, 1, -1
325 do p_z=elem3d%Nnode_v-1, 1, -1
326 flux_dn_lw(p_z,ke_z,bnd_i) = flux_dn_lw(p_z+1,ke_z,bnd_i) * trans_lw(p_z,ke_z,bnd_i) &
327 + r_lw(bnd_i) * src(p_z,ke_z) * ( 1.0_rp - trans_lw(p_z,ke_z,bnd_i) )
330 flux_dn_lw(elem3d%Nnode_v,ke_z-1,bnd_i) = flux_dn_lw(1,ke_z,bnd_i)
334 flux_dn_lw_tot(:,:) = flux_dn_lw_tot(:,:) + flux_dn_lw(:,:,bnd_i)
337 flux_dn_sw(elem3d%Nnode_v,lcmesh%NeZ) = solins(p_h,ke_h) * exp(-dtau_sw_kadd)
338 do ke_z=lcmesh%NeZ, 1, -1
339 do p_z=elem3d%Nnode_v-1, 1, -1
340 flux_dn_sw(p_z,ke_z) = flux_dn_sw(p_z+1,ke_z) * trans_sw(p_z,ke_z)
343 flux_dn_sw(elem3d%Nnode_v,ke_z-1) = flux_dn_sw(1,ke_z)
349 flux_up_lw_tot(:,:) = 0.0_rp
350 do bnd_i =1, n_lw_bnd
351 flux_up_lw(1,1,bnd_i) = r_lw(bnd_i) * sfc_temp(p_h,ke_h)**4 * stb
352 do ke_z=1, lcmesh%NeZ
353 do p_z=1, elem3d%Nnode_v-1
354 flux_up_lw(p_z+1,ke_z,bnd_i) = flux_up_lw(p_z,ke_z,bnd_i) * trans_lw(p_z,ke_z,bnd_i) &
355 + r_lw(bnd_i) * src(p_z,ke_z) * ( 1.0_rp - trans_lw(p_z,ke_z,bnd_i) )
357 if ( ke_z < lcmesh%NeZ )
then
358 flux_up_lw(1,ke_z+1,bnd_i) = flux_up_lw(elem3d%Nnode_v,ke_z,bnd_i)
362 flux_up_lw_tot(:,:) = flux_up_lw_tot(:,:) + flux_up_lw(:,:,bnd_i)
367 flux_up_sw(1,1) = sfc_alb(p_h,ke_h) * flux_dn_sw(1,1)
368 do ke_z=1, lcmesh%NeZ
369 do p_z=1, elem3d%Nnode_v-1
370 flux_up_sw(p_z+1,ke_z) = flux_up_sw(p_z,ke_z)
372 if ( ke_z < lcmesh%NeZ )
then
373 flux_up_sw(1,ke_z+1) = flux_up_sw(elem3d%Nnode_v,ke_z)
379 do ke_z=1, lcmesh%NeZ
380 do p_z=1, elem3d%Nnode_v
381 flux(p_h,p_z,ke_h,ke_z,i_lw,i_up) = flux_up_lw_tot(p_z,ke_z)
382 flux(p_h,p_z,ke_h,ke_z,i_lw,i_dn) = flux_dn_lw_tot(p_z,ke_z)
384 flux(p_h,p_z,ke_h,ke_z,i_sw,i_up) = flux_up_sw(p_z,ke_z)
385 flux(p_h,p_z,ke_h,ke_z,i_sw,i_dn) = flux_dn_sw(p_z,ke_z)
389 flux_top(p_h,ke_h,i_lw,i_up) = flux_up_lw_tot(elem3d%Nnode_v,lcmesh%NeZ)
390 flux_top(p_h,ke_h,i_lw,i_dn) = flux_dn_lw_tot(elem3d%Nnode_v,lcmesh%NeZ)
391 flux_top(p_h,ke_h,i_sw,i_up) = flux_up_sw(elem3d%Nnode_v,lcmesh%NeZ)
392 flux_top(p_h,ke_h,i_sw,i_dn) = flux_dn_sw(elem3d%Nnode_v,lcmesh%NeZ)
393 sflx_dn(p_h,ke_h,i_lw) = flux_dn_lw_tot(1,1)
394 sflx_dn(p_h,ke_h,i_sw) = flux_dn_sw(1,1)
395 sflx_up(p_h,ke_h,i_lw) = flux_up_lw_tot(1,1)
396 sflx_up(p_h,ke_h,i_sw) = flux_up_sw(1,1)
401 end subroutine atm_phy_rd_dgm_simple_flux
406 subroutine calc_optical_thick( this, dtau_lw, dtau_sw, dtau_sw_kadd, &
407 pres, qv, CO2, Nnode_v, NeZ )
410 integer,
intent(in) :: nnode_v
411 integer,
intent(in) :: nez
412 real(rp),
intent(out) :: dtau_lw(nnode_v-1,nez,n_lw_bnd_max)
413 real(rp),
intent(out) :: dtau_sw(nnode_v-1,nez)
414 real(rp),
intent(out) :: dtau_sw_kadd
415 real(rp),
intent(in) :: pres(nnode_v,nez)
416 real(rp),
intent(in) :: qv(nnode_v,nez)
417 real(rp),
intent(in) :: co2(nnode_v,nez)
423 real(rp) :: a_sw, b_sw, c_sw
424 real(rp) :: a_lw, b_lw, c_lw, d_lw
425 real(rp) :: a_win, b_win, c_win, d_win
430 real(rp),
parameter :: p0 = 1.0e5_rp
432 real(rp) :: ln_co2ov360ppm
434 real(rp) :: dsig_above_mot
435 real(rp) :: dtau_sw_kadd_tmp
440 a = this%OPTDEP_VALLIS_EQ5_PARAMS(1) * this%OPTDEP_VALLIS_EQ5_PARAMS(2)
441 b = this%OPTDEP_VALLIS_EQ5_PARAMS(3)
442 c = this%OPTDEP_VALLIS_EQ5_PARAMS(4)
443 dtau_sw_kadd = 0.0_rp
447 qv_tmp = 0.5_rp * ( qv(p_z,ke_z) + qv(p_z+1,ke_z) )
448 dsig = max( pres(p_z,ke_z) - pres(p_z+1,ke_z), 0.0_rp ) / p0
449 dtau_lw(p_z,ke_z,1) = ( a + b * qv_tmp + c * log( co2(p_z,ke_z) / 360.0_rp ) ) * dsig
450 dtau_sw(p_z,ke_z) = 0.0_rp * dsig
454 else if ( this%optdep_type == optdep_type_v2018_lwbnd2swbnd1 )
then
455 a_sw = this%OPTDEP_VALLIS_EQ6a_PARAMS(1)
456 c_sw = this%OPTDEP_VALLIS_EQ6a_PARAMS(2)
458 a_lw = this%OPTDEP_VALLIS_EQ7a_PARAMS(1)
459 b_lw = this%OPTDEP_VALLIS_EQ7a_PARAMS(2)
460 c_lw = this%OPTDEP_VALLIS_EQ7a_PARAMS(3)
461 d_lw = this%OPTDEP_VALLIS_EQ7a_PARAMS(4)
463 a_win = this%OPTDEP_VALLIS_EQ7b_PARAMS(1)
464 b_win = this%OPTDEP_VALLIS_EQ7b_PARAMS(2)
465 c_win = this%OPTDEP_VALLIS_EQ7b_PARAMS(3)
466 d_win = this%OPTDEP_VALLIS_EQ7b_PARAMS(4)
470 dsig_above_mot = pres(nnode_v,nez) / p0
471 dsig = dsig_above_mot / real(this%OPTDEP_VALLIS_EQ6a_kadd, kind=rp)
472 qv_tmp = this%OPTDEP_VALLIS_EQ6a_QV_above_MOT
473 ln_co2ov360ppm = log( co2(nnode_v,nez) / 360.0_rp )
476 do k=1, this%OPTDEP_VALLIS_EQ6a_kadd
477 b_sw = exp( 1.887e-2_rp / ( tau_sw_ + 9.522e-3_rp ) + 1.603_rp / ( tau_sw_ + 5.194e-1_rp )**2 )
478 dtau_sw_kadd_tmp = ( a_sw + b_sw * qv_tmp + c_sw * ln_co2ov360ppm ) * dsig
479 tau_sw_ = tau_sw_ + dtau_sw_kadd_tmp
481 dtau_sw_kadd = tau_sw_
485 do p_z=nnode_v-1, 1, -1
486 qv_tmp = 0.5_rp * ( qv(p_z,ke_z) + qv(p_z+1,ke_z) )
487 dsig = max( pres(p_z,ke_z) - pres(p_z+1,ke_z), 0.0_rp ) / p0
488 ln_co2ov360ppm = log( co2(p_z,ke_z) / 360.0_rp )
490 b_sw = exp( 1.887e-2_rp / ( tau_sw_ + 9.522e-3_rp ) + 1.603_rp / ( tau_sw_ + 5.194e-1_rp )**2 )
491 dtau_sw(p_z,ke_z) = ( a_sw + b_sw * qv_tmp + c_sw * ln_co2ov360ppm ) * dsig
492 dtau_lw(p_z,ke_z,1) = ( a_lw + b_lw * log( c_lw * qv_tmp + 1.0_rp ) + d_lw * ln_co2ov360ppm ) * dsig
493 dtau_lw(p_z,ke_z,2) = ( a_win + qv_tmp * ( b_win + c_win * qv_tmp ) + d_win * ln_co2ov360ppm ) * dsig
495 tau_sw_ = tau_sw_ + dtau_sw(p_z,ke_z)
501 end subroutine calc_optical_thick
module FElib / Atmosphere / Physics radiation
integer, parameter optdep_type_v2018_gray
An idealized radiation scheme based on Eq.5. This is gray in infrared so that a single optical thickn...
module FElib / Element / Base
module FElib / Element / hexahedron
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Data / base
module FElib / Mesh / Base 3D
module FElib / Data / base
Derived type to represent a simplified radiation scheme based on Vallis et al. (2018)
Derived type representing a 1D reference element.
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type representing a hexahedral element.
Derived type representing a local mesh for 2D domain.
Derived type to manage a local 3D computational domain.
Derived type representing a field with 3D local mesh.
Derived type to manage a computational mesh (base type for 3D domain)
Derived type representing a field with 3D mesh.