← Back to Documentation Home
CCPP SciDoc v8.0.0  v8.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
rrtmgp_lw_main.F90
1
3
6 use mpi_f08
7 use machine, only: kind_phys, kind_dbl_prec
8 use mo_optical_props, only: ty_optical_props_1scl, ty_optical_props_2str
9 use mo_rte_lw, only: rte_lw
10 use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp
11 use mo_gas_concentrations, only: ty_gas_concs
12 use mo_fluxes_byband, only: ty_fluxes_byband
13 use mo_source_functions, only: ty_source_func_lw
14 use radiation_tools, only: check_error_msg
15 use rrtmgp_lw_gas_optics, only: lw_gas_props,rrtmgp_lw_gas_optics_init
16 use rrtmgp_lw_cloud_optics, only: lw_cloud_props, rrtmgp_lw_cloud_optics_init, abssnow0, &
17 abssnow1, absrain
18 use gfs_rrtmgp_pre, only: istr_h2o, istr_co2, istr_o3, istr_n2o, istr_ch4, &
19 istr_o2, istr_ccl4, istr_cfc11, istr_cfc12, istr_cfc22, &
20 eps, oneminus, ftiny
22 use rrtmgp_sampling, only: sampled_mask, draw_samples
23 use mo_rte_kind, only: rte_wp => wp
24 implicit none
25
26 public rrtmgp_lw_main_init, rrtmgp_lw_main_run
27contains
28
32 subroutine rrtmgp_lw_main_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, rrtmgp_lw_file_clouds,&
33 active_gases_array, nrghice, mpicomm, mpirank, mpiroot, nLay, rrtmgp_phys_blksz, &
34 is_init_gas_optics, is_init_cloud_optics, errmsg, errflg)
35
36 ! Inputs
37 character(len=128),intent(in) :: &
38 rrtmgp_root_dir, & !< RTE-RRTMGP root directory
39 rrtmgp_lw_file_clouds, & !< RRTMGP file containing coefficients used to compute
40
41 rrtmgp_lw_file_gas
43 character(len=*), dimension(:), intent(in), optional :: &
44 active_gases_array
45 integer, intent(inout) :: &
46 nrghice
47 type(mpi_comm),intent(in) :: &
48 mpicomm
49 integer,intent(in) :: &
50 mpirank, & !< Current MPI rank
51 mpiroot, & !< Master MPI rank
52 rrtmgp_phys_blksz, & !< Number of horizontal points to process at once.
53 nlay
54
55 ! Outputs
56 logical, intent(inout) :: &
57 is_init_gas_optics, & !< Initialization flag
58 is_init_cloud_optics
59 character(len=*), intent( out) :: &
60 errmsg
61 integer, intent( out) :: &
62 errflg
63
64 ! Initialize CCPP error handling variables
65 errmsg = ''
66 errflg = 0
67
68 ! RRTMGP longwave gas-optics (k-distribution) initialization
69 call rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, &
70 active_gases_array, mpicomm, mpirank, mpiroot, is_init_gas_optics, errmsg, errflg)
71
72 ! RRTMGP longwave cloud-optics initialization
73 call rrtmgp_lw_cloud_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_clouds, &
74 nrghice, mpicomm, mpirank, mpiroot, is_init_cloud_optics, errmsg, errflg)
75
76 end subroutine rrtmgp_lw_main_init
77
81 subroutine rrtmgp_lw_main_run(doLWrad, doLWclrsky, top_at_1, doGP_lwscat, &
82 nCol, nLay, nGases,rrtmgp_phys_blksz, &
83 nGauss_angles, icseed_lw, iovr, iovr_convcld, iovr_max, iovr_maxrand, iovr_rand, &
84 iovr_dcorr, iovr_exp, iovr_exprand, isubc_lw, semis, tsfg, p_lay, p_lev, t_lay, &
85 t_lev, vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, vmr_n2o, vmr_co2, &
86 cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, &
87 cld_rwp, cld_rerain, precip_frac, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, &
88 cld_cnv_reice, cld_pbl_lwp, cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, &
89 cloud_overlap_param, active_gases_array, aerlw_tau, aerlw_ssa, aerlw_g, &
90 fluxlwUP_allsky, fluxlwDOWN_allsky, fluxlwUP_clrsky, fluxlwDOWN_clrsky, &
91 fluxlwUP_radtime, fluxlwDOWN_radtime, fluxlwUP_jac, errmsg, errflg)
92
93 ! Inputs
94 logical, intent(in) :: &
95 dolwrad, & ! Flag to perform longwave calculation
96 dolwclrsky, & ! Flag to compute clear-sky fluxes
97 top_at_1, & ! Flag for vertical ordering convention
98 dogp_lwscat ! Flag to include scattering in clouds
99 integer,intent(in) :: &
100 ncol, & ! Number of horizontal points
101 nlay, & ! Number of vertical grid points.
102 ngases, & ! Number of active gases
103 rrtmgp_phys_blksz, & ! Number of horizontal points to process at once.
104 ngauss_angles, & ! Number of gaussian quadrature angles used
105 iovr, & ! Choice of cloud-overlap method
106 iovr_convcld, & ! Choice of convective cloud-overlap
107 iovr_max, & ! Flag for maximum cloud overlap method
108 iovr_maxrand, & ! Flag for maximum-random cloud overlap method
109 iovr_rand, & ! Flag for random cloud overlap method
110 iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method
111 iovr_exp, & ! Flag for exponential cloud overlap method
112 iovr_exprand, & ! Flag for exponential-random cloud overlap method
113 isubc_lw ! Flag for cloud-seeding (rng) for cloud-sampling
114 integer,intent(in),dimension(:) :: &
115 icseed_lw ! Seed for random number generation for longwave radiation
116 real(kind_phys), dimension(:), intent(in) :: &
117 semis, & ! Surface-emissivity (1)
118 tsfg ! Skin temperature (K)
119 real(kind_phys), dimension(:,:), intent(in) :: &
120 p_lay, & ! Pressure @ model layer-centers (Pa)
121 t_lay, & ! Temperature (K)
122 p_lev, & ! Pressure @ model layer-interfaces (Pa)
123 t_lev, & ! Temperature @ model levels (K)
124 vmr_o2, & ! Molar-mixing ratio oxygen
125 vmr_h2o, & ! Molar-mixing ratio water vapor
126 vmr_o3, & ! Molar-mixing ratio ozone
127 vmr_ch4, & ! Molar-mixing ratio methane
128 vmr_n2o, & ! Molar-mixing ratio nitrous oxide
129 vmr_co2 ! Molar-mixing ratio carbon dioxide
130 real(kind_phys), dimension(:,:), intent(in) :: &
131 cld_frac, & ! Cloud-fraction for stratiform clouds
132 cld_lwp, & ! Water path for stratiform liquid cloud-particles
133 cld_reliq, & ! Effective radius for stratiform liquid cloud-particles
134 cld_iwp, & ! Water path for stratiform ice cloud-particles
135 cld_reice, & ! Effective radius for stratiform ice cloud-particles
136 cld_swp, & ! Water path for snow hydrometeors
137 cld_resnow, & ! Effective radius for snow hydrometeors
138 cld_rwp, & ! Water path for rain hydrometeors
139 cld_rerain, & ! Effective radius for rain hydrometeors
140 precip_frac, & ! Precipitation fraction (not active, currently precipitation optics uses cloud-fraction)
141 cloud_overlap_param ! Cloud overlap parameter
142 real(kind_phys), dimension(:,:), intent(in), optional :: &
143 cld_cnv_lwp, & ! Water path for convective liquid cloud-particles
144 cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles
145 cld_cnv_iwp, & ! Water path for convective ice cloud-particles
146 cld_cnv_reice, & ! Effective radius for convective ice cloud-particles
147 cld_pbl_lwp, & ! Water path for PBL liquid cloud-particles
148 cld_pbl_reliq, & ! Effective radius for PBL liquid cloud-particles
149 cld_pbl_iwp, & ! Water path for PBL ice cloud-particles
150 cld_pbl_reice ! Effective radius for PBL ice cloud-particles
151 real(kind_phys), dimension(:,:,:), intent(in) :: &
152 aerlw_tau, & ! Aerosol optical depth
153 aerlw_ssa, & ! Aerosol single scattering albedo
154 aerlw_g ! Aerosol asymmetry paramter
155 character(len=*), dimension(:), intent(in) :: &
156 active_gases_array ! List of active gases from namelist as array
157
158 ! Outputs
159 real(kind_phys), dimension(:,:), intent(inout), optional :: &
160 fluxlwup_jac ! Jacobian of upwelling LW surface radiation (W/m2/K)
161 real(kind_phys), dimension(:,:), intent(inout) :: &
162 fluxlwup_allsky, & ! All-sky flux (W/m2)
163 fluxlwdown_allsky, & ! All-sky flux (W/m2)
164 fluxlwup_clrsky, & ! Clear-sky flux (W/m2)
165 fluxlwdown_clrsky, & ! All-sky flux (W/m2)
166 fluxlwup_radtime, & ! Copy of fluxes (Used for coupling)
167 fluxlwdown_radtime !
168 character(len=*), intent(out) :: &
169 errmsg ! CCPP error message
170 integer, intent(out) :: &
171 errflg ! CCPP error flag
172
173 ! Local variables
174 type(ty_fluxes_byband) :: flux_allsky, flux_clrsky
175 integer :: icol, ilay, igas, iband, icol2, ix, iblck
176 integer, dimension(rrtmgp_phys_blksz) :: ipseed_lw
177 type(random_stat) :: rng_stat
178 real(kind_phys), dimension(rrtmgp_phys_blksz) :: zcf0, zcf1
179 logical, dimension(rrtmgp_phys_blksz,nLay,lw_gas_props%get_ngpt()) :: maskmcica
180 real(kind_phys), dimension(rrtmgp_phys_blksz) :: tau_rain, tau_snow
181 real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()) :: rng1d
182 real(rte_wp), dimension(lw_gas_props%get_ngpt(),nLay,rrtmgp_phys_blksz) :: rng3d,rng3d2
183 real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()*nLay) :: rng2d
184 real(rte_wp), dimension(rrtmgp_phys_blksz,nLay+1,lw_gas_props%get_nband()),target :: &
185 fluxlw_up_allsky, fluxlw_up_clrsky, fluxlw_dn_allsky, fluxlw_dn_clrsky
186 real(rte_wp), dimension(rrtmgp_phys_blksz,lw_gas_props%get_ngpt()) :: lw_ds
187 real(rte_wp), dimension(lw_gas_props%get_nband(),rrtmgp_phys_blksz) :: sfc_emiss_byband
188 real(rte_wp), dimension(rrtmgp_phys_blksz,nLay+1) :: fluxlw_up_jac
189 logical :: dogp_sgs_cnv, dogp_sgs_pbl
190 ! Local RRTMGP DDTs.
191 type(ty_gas_concs) :: gas_concs
192 type(ty_optical_props_1scl) :: lw_optical_props_clrsky, lw_optical_props_aerosol_local
193 type(ty_optical_props_2str) :: lw_optical_props_clouds, lw_optical_props_cloudsbyband, &
194 lw_optical_props_cnvcloudsbyband, lw_optical_props_pblcloudsbyband, &
195 lw_optical_props_precipbyband
196 type(ty_source_func_lw) :: sources
197
198 ! Initialize CCPP error handling variables
199 errmsg = ''
200 errflg = 0
201
202 if (.not. dolwrad) return
203
204 ! Do we have convective cloud properties?
205 dogp_sgs_cnv = .false.
206 if (present(cld_cnv_lwp) .and. present(cld_cnv_reliq) .and. &
207 present(cld_cnv_iwp) .and. present(cld_cnv_reice)) then
208 dogp_sgs_cnv = .true.
209 endif
210
211 ! Do we have pbl cloud prperties?
212 dogp_sgs_pbl = .false.
213 if (present(cld_pbl_lwp) .and. present(cld_pbl_reliq) .and. &
214 present(cld_pbl_iwp) .and. present(cld_pbl_reice)) then
215 dogp_sgs_pbl = .true.
216 endif
217
218 !
219 ! Initialize RRTMGP DDTs (local)
220 !
221
222 ! ty_gas_concs
223 call check_error_msg('rrtmgp_lw_main_gas_concs_run',gas_concs%init(active_gases_array))
224
225 ! ty_optical_props
226 call check_error_msg('rrtmgp_lw_main_gas_optics_run',&
227 lw_optical_props_clrsky%alloc_1scl(rrtmgp_phys_blksz, nlay, lw_gas_props))
228 call check_error_msg('rrtmgp_lw_main_sources_run',&
229 sources%alloc(rrtmgp_phys_blksz, nlay, lw_gas_props))
230 call check_error_msg('rrtmgp_lw_main_cloud_optics_run',&
231 lw_optical_props_cloudsbyband%alloc_2str(rrtmgp_phys_blksz, nlay, lw_gas_props%get_band_lims_wavenumber()))
232 call check_error_msg('rrtmgp_lw_main_precip_optics_run',&
233 lw_optical_props_precipbyband%alloc_2str(rrtmgp_phys_blksz, nlay, lw_gas_props%get_band_lims_wavenumber()))
234 call check_error_msg('rrtmgp_lw_mian_cloud_sampling_run', &
235 lw_optical_props_clouds%alloc_2str(rrtmgp_phys_blksz, nlay, lw_gas_props))
236 call check_error_msg('rrtmgp_lw_main_aerosol_optics_run',&
237 lw_optical_props_aerosol_local%alloc_1scl(rrtmgp_phys_blksz, nlay, lw_gas_props%get_band_lims_wavenumber()))
238 if (dogp_sgs_cnv) then
239 call check_error_msg('rrtmgp_lw_main_cnv_cloud_optics_run',&
240 lw_optical_props_cnvcloudsbyband%alloc_2str(rrtmgp_phys_blksz, nlay, lw_gas_props%get_band_lims_wavenumber()))
241 endif
242 if (dogp_sgs_pbl) then
243 call check_error_msg('rrtmgp_lw_main_pbl_cloud_optics_run',&
244 lw_optical_props_pblcloudsbyband%alloc_2str(rrtmgp_phys_blksz, nlay, lw_gas_props%get_band_lims_wavenumber()))
245 endif
246
247 ! ######################################################################################
248 !
249 ! Loop over all columns...
250 !
251 ! ######################################################################################
252 do icol=1,ncol,rrtmgp_phys_blksz
253 icol2 = icol + rrtmgp_phys_blksz - 1
254
255 ! Initialize/reset
256
257 ! ty_optical_props
258 lw_optical_props_clrsky%tau = 0._kind_phys
259 lw_optical_props_precipbyband%tau = 0._kind_phys
260 lw_optical_props_precipbyband%ssa = 0._kind_phys
261 lw_optical_props_precipbyband%g = 0._kind_phys
262 lw_optical_props_cloudsbyband%tau = 0._kind_phys
263 lw_optical_props_cloudsbyband%ssa = 0._kind_phys
264 lw_optical_props_cloudsbyband%g = 0._kind_phys
265 lw_optical_props_clouds%tau = 0._kind_phys
266 lw_optical_props_clouds%ssa = 0._kind_phys
267 lw_optical_props_clouds%g = 0._kind_phys
268 sources%sfc_source = 0._kind_phys
269 sources%lay_source = 0._kind_phys
270 sources%sfc_source_Jac = 0._kind_phys
271 fluxlw_up_allsky = 0._rte_wp
272 fluxlw_dn_allsky = 0._rte_wp
273 fluxlw_up_clrsky = 0._rte_wp
274 fluxlw_dn_clrsky = 0._rte_wp
275 if (dogp_sgs_cnv) lw_optical_props_cnvcloudsbyband%tau = 0._kind_phys
276 if (dogp_sgs_pbl) lw_optical_props_pblcloudsbyband%tau = 0._kind_phys
277
278 ! ty_fluxes_byband
279 fluxlw_up_allsky = 0._rte_wp
280 fluxlw_dn_allsky = 0._rte_wp
281 fluxlw_up_clrsky = 0._rte_wp
282 fluxlw_dn_clrsky = 0._rte_wp
283 flux_allsky%bnd_flux_up => fluxlw_up_allsky
284 flux_allsky%bnd_flux_dn => fluxlw_dn_allsky
285 flux_clrsky%bnd_flux_up => fluxlw_up_clrsky
286 flux_clrsky%bnd_flux_dn => fluxlw_dn_clrsky
287
288 ! ###################################################################################
289 !
290 ! Set gas-concentrations
291 !
292 ! ###################################################################################
293 call check_error_msg('rrtmgp_lw_main_set_vmr_o2', &
294 gas_concs%set_vmr(trim(active_gases_array(istr_o2)), real(vmr_o2(icol:icol2,:),kind=rte_wp)))
295 call check_error_msg('rrtmgp_lw_main_set_vmr_co2', &
296 gas_concs%set_vmr(trim(active_gases_array(istr_co2)),real(vmr_co2(icol:icol2,:),kind=rte_wp)))
297 call check_error_msg('rrtmgp_lw_main_set_vmr_ch4', &
298 gas_concs%set_vmr(trim(active_gases_array(istr_ch4)),real(vmr_ch4(icol:icol2,:),kind=rte_wp)))
299 call check_error_msg('rrtmgp_lw_main_set_vmr_n2o', &
300 gas_concs%set_vmr(trim(active_gases_array(istr_n2o)),real(vmr_n2o(icol:icol2,:),kind=rte_wp)))
301 call check_error_msg('rrtmgp_lw_main_set_vmr_h2o', &
302 gas_concs%set_vmr(trim(active_gases_array(istr_h2o)),real(vmr_h2o(icol:icol2,:),kind=rte_wp)))
303 call check_error_msg('rrtmgp_lw_main_set_vmr_o3', &
304 gas_concs%set_vmr(trim(active_gases_array(istr_o3)), real(vmr_o3(icol:icol2,:),kind=rte_wp)))
305
306 ! ###################################################################################
307 !
308 ! Surface emissity in each band
309 !
310 ! ###################################################################################
311 ! Assign same emissivity to all band
312 do iblck=1,rrtmgp_phys_blksz
313 if (semis(icol+iblck-1) > eps .and. semis(icol+iblck-1) <= 1._kind_phys) then
314 do iband=1,lw_gas_props%get_nband()
315 sfc_emiss_byband(iband,iblck) = semis(icol+iblck-1)
316 enddo
317 else
318 sfc_emiss_byband(1:lw_gas_props%get_nband(),iblck) = 1.0
319 endif
320 enddo
321
322 ! ###################################################################################
323 !
324 ! Compute gas-optics...
325 !
326 ! ###################################################################################
327 call check_error_msg('rrtmgp_lw_main_gas_optics',lw_gas_props%gas_optics(&
328 real(p_lay(icol:icol2,:),kind=rte_wp), & ! IN - Pressure @ layer-centers (Pa)
329 real(p_lev(icol:icol2,:),kind=rte_wp), & ! IN - Pressure @ layer-interfaces (Pa)
330 real(t_lay(icol:icol2,:),kind=rte_wp), & ! IN - Temperature @ layer-centers (K)
331 real(tsfg(icol:icol2),kind=rte_wp), & ! IN - Skin-temperature (K)
332 gas_concs, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios
333 lw_optical_props_clrsky, & ! OUT - RRTMGP DDT: longwave optical properties
334 sources, & ! OUT - RRTMGP DDT: source functions
335 tlev=real(t_lev(icol:icol2,:),kind=rte_wp))) ! IN - Temperature @ layer-interfaces (K) (optional)
336
337 ! ###################################################################################
338 !
339 ! Compute cloud-optics...
340 !
341 ! ###################################################################################
342 ! Create clear/cloudy indicator
343 zcf0(:) = 1._kind_phys
344 zcf1(:) = 1._kind_phys
345 do iblck = 1, rrtmgp_phys_blksz
346 do ilay=1,nlay
347 zcf0(iblck) = min(zcf0(iblck), 1._kind_phys - cld_frac(icol+iblck-1,ilay))
348 enddo
349 if (zcf0(iblck) <= ftiny) zcf0(iblck) = 0._kind_phys
350 if (zcf0(iblck) > oneminus) zcf0(iblck) = 1._kind_phys
351 zcf1(iblck) = 1._kind_phys - zcf0(iblck)
352 enddo
353
354 if (any(zcf1 .gt. eps)) then
355 ! Microphysical (gridmean) cloud optics
356 call check_error_msg('rrtmgp_lw_main_cloud_optics',lw_cloud_props%cloud_optics(&
357 real(cld_lwp(icol:icol2,:),kind=rte_wp), & ! IN - Cloud liquid water path (g/m2)
358 real(cld_iwp(icol:icol2,:),kind=rte_wp), & ! IN - Cloud ice water path (g/m2)
359 real(cld_reliq(icol:icol2,:),kind=rte_wp), & ! IN - Cloud liquid effective radius (microns)
360 real(cld_reice(icol:icol2,:),kind=rte_wp), & ! IN - Cloud ice effective radius (microns)
361 lw_optical_props_cloudsbyband)) ! OUT - RRTMGP DDT containing cloud radiative properties
362 ! in each band
363 ! Include convective (subgrid scale) clouds?
364 if (dogp_sgs_cnv) then
365 ! Compute
366 call check_error_msg('rrtmgp_lw_main_cnv_cloud_optics',lw_cloud_props%cloud_optics(&
367 real(cld_cnv_lwp(icol:icol2,:),kind=rte_wp), & ! IN - Convective cloud liquid water path (g/m2)
368 real(cld_cnv_iwp(icol:icol2,:),kind=rte_wp), & ! IN - Convective cloud ice water path (g/m2)
369 real(cld_cnv_reliq(icol:icol2,:),kind=rte_wp), & ! IN - Convective cloud liquid effective radius (microns)
370 real(cld_cnv_reice(icol:icol2,:),kind=rte_wp), & ! IN - Convective cloud ice effective radius (microns)
371 lw_optical_props_cnvcloudsbyband)) ! OUT - RRTMGP DDT containing convective cloud radiative properties
372 ! in each band
373 ! Increment
374 call check_error_msg('rrtmgp_lw_main_increment_cnvclouds_to_clouds',&
375 lw_optical_props_cnvcloudsbyband%increment(lw_optical_props_cloudsbyband))
376 endif
377
378 ! Include PBL (subgrid scale) clouds?
379 if (dogp_sgs_pbl) then
380 ! Compute
381 call check_error_msg('rrtmgp_lw_main_pbl_cloud_optics',lw_cloud_props%cloud_optics(&
382 real(cld_pbl_lwp(icol:icol2,:),kind=rte_wp), & ! IN - PBL cloud liquid water path (g/m2)
383 real(cld_pbl_iwp(icol:icol2,:),kind=rte_wp), & ! IN - PBL cloud ice water path (g/m2)
384 real(cld_pbl_reliq(icol:icol2,:),kind=rte_wp), & ! IN - PBL cloud liquid effective radius (microns)
385 real(cld_pbl_reice(icol:icol2,:),kind=rte_wp), & ! IN - PBL cloud ice effective radius (microns)
386 lw_optical_props_pblcloudsbyband)) ! OUT - RRTMGP DDT containing PBL cloud radiative properties
387 ! in each band
388 ! Increment
389 call check_error_msg('rrtmgp_lw_main_increment_pblclouds_to_clouds',&
390 lw_optical_props_pblcloudsbyband%increment(lw_optical_props_cloudsbyband))
391 endif
392 endif
393
394 ! ###################################################################################
395 !
396 ! Cloud precipitation optics: rain and snow(+groupel)
397 !
398 ! ###################################################################################
399 tau_rain(:) = 0._kind_phys
400 tau_snow(:) = 0._kind_phys
401 do ix=1,rrtmgp_phys_blksz
402 do ilay=1,nlay
403 if (cld_frac(icol+ix-1,ilay) .gt. eps) then
404 ! Rain optical-depth (No band dependence)
405 tau_rain(ix) = absrain*cld_rwp(icol+ix-1,ilay)
406
407 ! Snow (+groupel) optical-depth (No band dependence)
408 if (cld_swp(icol+ix-1,ilay) .gt. 0. .and. cld_resnow(icol+ix-1,ilay) .gt. 10._kind_phys) then
409 tau_snow(ix) = abssnow0*1.05756*cld_swp(icol+ix-1,ilay)/cld_resnow(icol+ix-1,ilay)
410 else
411 tau_snow(ix) = 0.0
412 endif
413 do iband=1,lw_gas_props%get_nband()
414 lw_optical_props_precipbyband%tau(ix,ilay,iband) = tau_rain(ix) + tau_snow(ix)
415 enddo
416 endif
417 enddo
418 enddo
419 ! Increment
420 call check_error_msg('rrtmgp_lw_main_increment_precip_to_clouds',&
421 lw_optical_props_precipbyband%increment(lw_optical_props_cloudsbyband))
422
423 ! ###################################################################################
424 !
425 ! Cloud-sampling
426 ! *Note* All of the included cloud-types are sampled together, not independently.
427 !
428 ! ###################################################################################
429 if (any(zcf1 .gt. eps)) then
430 ! Change random number seed value for each radiation invocation (isubc_lw =1 or 2).
431 if(isubc_lw == 1) then ! advance prescribed permutation seed
432 do ix=1,rrtmgp_phys_blksz
433 ipseed_lw(ix) = lw_gas_props%get_ngpt() + icol + ix - 1
434 enddo
435 elseif (isubc_lw == 2) then ! use input array of permutation seeds
436 do ix=1,rrtmgp_phys_blksz
437 ipseed_lw(ix) = icseed_lw(icol+ix-1)
438 enddo
439 endif
440
441 ! Call RNG
442 do ix=1,rrtmgp_phys_blksz
443 call random_setseed(ipseed_lw(ix),rng_stat)
444 ! Use same rng for each layer
445 if (iovr == iovr_max) then
446 call random_number(rng1d,rng_stat)
447 do ilay=1,nlay
448 rng3d(:,ilay,ix) = rng1d
449 enddo
450 else
451 do ilay=1,nlay
452 call random_number(rng1d,rng_stat)
453 rng3d(:,ilay,ix) = rng1d
454 enddo
455 endif
456 enddo
457
458 ! Cloud-overlap.
459 ! Maximum-random, random or maximum.
460 if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then
461 call sampled_mask(rng3d, real(cld_frac(icol:icol2,:),kind=rte_wp), maskmcica)
462 endif
463 ! Exponential decorrelation length overlap
464 if (iovr == iovr_dcorr) then
465 do ix=1,rrtmgp_phys_blksz
466 ! Generate second RNG
467 call random_setseed(ipseed_lw(ix),rng_stat)
468 call random_number(rng2d,rng_stat)
469 rng3d2(:,:,ix) = reshape(source = rng2d,shape=[lw_gas_props%get_ngpt(),nlay])
470 enddo
471 !
472 call sampled_mask(rng3d, real(cld_frac(icol:icol2,:),kind=rte_wp), &
473 maskmcica, overlap_param = real(cloud_overlap_param(icol:icol2,1:nlay-1),kind=rte_wp), &
474 randoms2 = rng3d2)
475 endif
476 ! Exponential or Exponential-random
477 if (iovr == iovr_exp .or. iovr == iovr_exprand) then
478 call sampled_mask(rng3d, real(cld_frac(icol:icol2,:),kind=rte_wp), &
479 maskmcica, overlap_param = real(cloud_overlap_param(icol:icol2,1:nlay-1),kind=rte_wp))
480 endif
481 ! Sampling. Map band optical depth to each g-point using McICA
482 call check_error_msg('rrtmgp_lw_main_cloud_sampling',&
483 draw_samples(maskmcica, .true., &
484 lw_optical_props_cloudsbyband, lw_optical_props_clouds))
485 endif
486
487 ! ###################################################################################
488 !
489 ! Compute clear-sky fluxes (gaseous+aerosol) (optional)
490 !
491 ! ###################################################################################
492 ! Increment
493 lw_optical_props_aerosol_local%tau = aerlw_tau(icol:icol2,:,:)
494 call check_error_msg('rrtmgp_lw_main_increment_aerosol_to_clrsky',&
495 lw_optical_props_aerosol_local%increment(lw_optical_props_clrsky))
496
497 ! Call RTE solver
498 if (dolwclrsky) then
499 call check_error_msg('rrtmgp_lw_main_opt_angle',&
500 lw_gas_props%compute_optimal_angles(lw_optical_props_clrsky,lw_ds))
501 if (ngauss_angles .gt. 1) then
502 call check_error_msg('rrtmgp_lw_main_lw_rte_clrsky',rte_lw( &
503 lw_optical_props_clrsky, & ! IN - optical-properties
504 top_at_1, & ! IN - veritcal ordering flag
505 sources, & ! IN - source function
506 sfc_emiss_byband, & ! IN - surface emissivity in each LW band
507 flux_clrsky, & ! OUT - Fluxes
508 n_gauss_angles = ngauss_angles)) ! IN - Number of angles in Gaussian quadrature
509 else
510 call check_error_msg('rrtmgp_lw_main_lw_rte_clrsky',rte_lw( &
511 lw_optical_props_clrsky, & ! IN - optical-properties
512 top_at_1, & ! IN - veritcal ordering flag
513 sources, & ! IN - source function
514 sfc_emiss_byband, & ! IN - surface emissivity in each LW band
515 flux_clrsky, & ! OUT - Fluxes
516 lw_ds = lw_ds))
517 endif
518
519 ! Store fluxes
520 fluxlwup_clrsky(icol:icol2,:) = sum(flux_clrsky%bnd_flux_up, dim=3)
521 fluxlwdown_clrsky(icol:icol2,:) = sum(flux_clrsky%bnd_flux_dn, dim=3)
522 else
523 fluxlwup_clrsky(icol:icol2,:) = 0.0
524 fluxlwdown_clrsky(icol:icol2,:) = 0.0
525 endif
526
527 ! ###################################################################################
528 !
529 ! All-sky fluxes (clear-sky + clouds + precipitation)
530 ! *Note* CCPP does not allow for polymorphic types, they are ambiguous to the CCPP
531 ! framework. rte-rrtmgp uses polymorphic types extensively, for example, querying the
532 ! type to determine physics configuration/pathway/etc...
533 !
534 ! The logic in the code below is to satisfy the polymorphishm in the rte-rrtmgp code.
535 ! The rte-rrtmgp "increment" procedures are utilized to provide the correct type to the
536 ! rte solver (rte_lw). Rte_lw quieries the type determine if scattering is to be
537 ! included in the calculation. The increment procedures are called so that the correct
538 ! optical properties are inherited. ugh...
539 !
540 ! ###################################################################################
541
542 ! Include LW cloud-scattering?
543 if (dogp_lwscat) then
544 ! Increment
545 call check_error_msg('rrtmgp_lw_main_increment_clrsky_to_clouds',&
546 lw_optical_props_clrsky%increment(lw_optical_props_clouds))
547
548 if (present(fluxlwup_jac)) then
549 ! Compute LW Jacobians
550 call check_error_msg('rrtmgp_lw_main_lw_rte_allsky',rte_lw( &
551 lw_optical_props_clouds, & ! IN - optical-properties
552 top_at_1, & ! IN - veritcal ordering flag
553 sources, & ! IN - source function
554 sfc_emiss_byband, & ! IN - surface emissivity in each LW band
555 flux_allsky, & ! OUT - Flxues
556 n_gauss_angles = ngauss_angles, & ! IN - Number of angles in Gaussian quadrature
557 flux_up_jac = fluxlw_up_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K)
558 else
559 call check_error_msg('rrtmgp_lw_main_lw_rte_allsky',rte_lw( &
560 lw_optical_props_clouds, & ! IN - optical-properties
561 top_at_1, & ! IN - veritcal ordering flag
562 sources, & ! IN - source function
563 sfc_emiss_byband, & ! IN - surface emissivity in each LW band
564 flux_allsky, & ! OUT - Flxues
565 n_gauss_angles = ngauss_angles)) ! IN - Number of angles in Gaussian quadrature
566 end if
567 ! No scattering in LW clouds.
568 else
569 ! Increment
570 call check_error_msg('rrtmgp_lw_main_increment_clouds_to_clrsky', &
571 lw_optical_props_clouds%increment(lw_optical_props_clrsky))
572
573 if (present(fluxlwup_jac)) then
574 ! Compute LW Jacobians
575 call check_error_msg('rrtmgp_lw_rte_run',rte_lw( &
576 lw_optical_props_clrsky, & ! IN - optical-properties
577 top_at_1, & ! IN - veritcal ordering flag
578 sources, & ! IN - source function
579 sfc_emiss_byband, & ! IN - surface emissivity in each LW band
580 flux_allsky, & ! OUT - Flxues
581 n_gauss_angles = ngauss_angles, & ! IN - Number of angles in Gaussian quadrature
582 flux_up_jac = fluxlw_up_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K)
583 else
584 call check_error_msg('rrtmgp_lw_rte_run',rte_lw( &
585 lw_optical_props_clrsky, & ! IN - optical-properties
586 top_at_1, & ! IN - veritcal ordering flag
587 sources, & ! IN - source function
588 sfc_emiss_byband, & ! IN - surface emissivity in each LW band
589 flux_allsky, & ! OUT - Flxues
590 n_gauss_angles = ngauss_angles)) ! IN - Number of angles in Gaussian quadrature
591 end if
592 endif
593
594 ! Store fluxes
595 fluxlwup_allsky(icol:icol2,:) = sum(flux_allsky%bnd_flux_up, dim=3)
596 fluxlwdown_allsky(icol:icol2,:) = sum(flux_allsky%bnd_flux_dn, dim=3)
597
598 ! Save fluxes for coupling
599 if (present(fluxlwup_jac)) then
600 fluxlwup_jac(icol:icol2,:) = fluxlw_up_jac
601 endif
602 fluxlwup_radtime(icol:icol2,:) = fluxlwup_allsky(icol:icol2,:)
603 fluxlwdown_radtime(icol:icol2,:) = fluxlwdown_allsky(icol:icol2,:)
604
605 enddo
606
607 end subroutine rrtmgp_lw_main_run
608end module rrtmgp_lw_main
This module calculates random numbers using the Mersenne twister.
This module contains tools for radiation.
This module contains two routines: The first initializes data and functions needed to compute the lon...
This module contains two routines: One to initialize the k-distribution data and functions needed to ...
This module contains the RRTMGP-LW radiation scheme.
This module provides a simple implementation of sampling for the Monte Carlo Independent Pixel Approx...