← Back to Documentation Home
CCPP SciDoc v8.0.0  v8.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
rrtmgp_sw_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_2str
10 use mo_rte_sw, only: rte_sw
11 use mo_gas_concentrations, only: ty_gas_concs
12 use mo_fluxes_byband, only: ty_fluxes_byband
13 use radiation_tools, only: check_error_msg
14 use rrtmgp_sw_gas_optics, only: sw_gas_props,rrtmgp_sw_gas_optics_init
15 use rrtmgp_sw_cloud_optics, only: sw_cloud_props, rrtmgp_sw_cloud_optics_init, a0r, a0s, &
16 a1s, b0r, b0s, b1s, c0r, c0s
17 use gfs_rrtmgp_pre, only: istr_h2o, istr_co2, istr_o3, istr_n2o, istr_ch4, &
18 istr_o2, istr_ccl4, istr_cfc11, istr_cfc12, istr_cfc22, &
19 eps, oneminus, ftiny
21 use rrtmgp_sampling, only: sampled_mask, draw_samples
22 use mo_rte_kind, only: rte_wp => wp
23 implicit none
24
25 public rrtmgp_sw_main_init, rrtmgp_sw_main_run
26
27contains
28
32 subroutine rrtmgp_sw_main_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, rrtmgp_sw_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_sw_file_clouds, & !< RRTMGP file containing K-distribution data
40 rrtmgp_sw_file_gas
41 character(len=*), dimension(:), intent(in), optional :: &
42 active_gases_array
43 integer, intent(inout) :: &
44 nrghice
45 type(mpi_comm),intent(in) :: &
46 mpicomm
47 integer,intent(in) :: &
48 mpirank, & !< Current MPI rank
49 mpiroot, & !< Master MPI rank
50 rrtmgp_phys_blksz, & !< Number of horizontal points to process at once.
51 nlay
52 ! Outputs
53 logical, intent(inout) :: &
54 is_init_gas_optics, & !< Initialization flag
55 is_init_cloud_optics
56 character(len=*), intent( out) :: &
57 errmsg
58 integer, intent( out) :: &
59 errflg
60
61 ! Initialize CCPP error handling variables
62 errmsg = ''
63 errflg = 0
64
65 ! RRTMGP shortwave gas-optics (k-distribution) initialization
66 call rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, active_gases_array,&
67 mpicomm, mpirank, mpiroot, is_init_gas_optics, errmsg, errflg)
68
69 ! RRTMGP shortwave cloud-optics initialization
70 call rrtmgp_sw_cloud_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_clouds, &
71 nrghice, mpicomm, mpirank, mpiroot, is_init_cloud_optics, errmsg, errflg)
72
73 end subroutine rrtmgp_sw_main_init
74
78 subroutine rrtmgp_sw_main_run(doSWrad, doSWclrsky, top_at_1, &
79 nCol, nDay, nLay, nGases, rrtmgp_phys_blksz, idx, icseed_sw, iovr, iovr_convcld, &
80 iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, isubc_sw, &
81 iSFC, sfc_alb_nir_dir, sfc_alb_nir_dif, sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, coszen,&
82 p_lay, p_lev, t_lay, t_lev, vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, vmr_n2o, vmr_co2, &
83 cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, &
84 cld_rerain, precip_frac, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, &
85 cld_pbl_lwp, cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, cloud_overlap_param, &
86 active_gases_array, aersw_tau, aersw_ssa, aersw_g, solcon, scmpsw, &
87 fluxswUP_allsky, fluxswDOWN_allsky, fluxswUP_clrsky, fluxswDOWN_clrsky, cldtausw, &
88 errmsg, errflg)
89
90 ! Inputs
91 logical, intent(in) :: &
92 doswrad, & ! Flag to perform shortwave calculation
93 doswclrsky, & ! Flag to compute clear-sky fluxes
94 top_at_1 ! Flag for vertical ordering convention
95 integer,intent(in) :: &
96 ncol, & ! Number of horizontal points
97 nday, & ! Number of daytime points
98 nlay, & ! Number of vertical grid points.
99 ngases, & ! Number of active gases
100 rrtmgp_phys_blksz, & ! Number of horizontal points to process at once.
101 iovr, & ! Choice of cloud-overlap method
102 iovr_convcld, & ! Choice of convective cloud-overlap
103 iovr_max, & ! Flag for maximum cloud overlap method
104 iovr_maxrand, & ! Flag for maximum-random cloud overlap method
105 iovr_rand, & ! Flag for random cloud overlap method
106 iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method
107 iovr_exp, & ! Flag for exponential cloud overlap method
108 iovr_exprand, & ! Flag for exponential-random cloud overlap method
109 isubc_sw, & !
110 isfc
111 integer,intent(in),dimension(:) :: &
112 idx ! Index array for daytime points
113 integer,intent(in),dimension(:) :: &
114 icseed_sw ! Seed for random number generation for shortwave radiation
115 real(kind_phys), dimension(:), intent(in) :: &
116 sfc_alb_nir_dir, & ! Surface albedo (direct)
117 sfc_alb_nir_dif, & ! Surface albedo (diffuse)
118 sfc_alb_uvvis_dir, & ! Surface albedo (direct)
119 sfc_alb_uvvis_dif, & ! Surface albedo (diffuse)
120 coszen ! Cosize of SZA
121 real(kind_phys), dimension(:,:), intent(in) :: &
122 p_lay, & ! Pressure @ model layer-centers (Pa)
123 t_lay, & ! Temperature (K)
124 p_lev, & ! Pressure @ model layer-interfaces (Pa)
125 t_lev, & ! Temperature @ model levels (K)
126 vmr_o2, & ! Molar-mixing ratio oxygen
127 vmr_h2o, & ! Molar-mixing ratio water vapor
128 vmr_o3, & ! Molar-mixing ratio ozone
129 vmr_ch4, & ! Molar-mixing ratio methane
130 vmr_n2o, & ! Molar-mixing ratio nitrous oxide
131 vmr_co2 ! Molar-mixing ratio carbon dioxide
132 real(kind_phys), dimension(:,:), intent(in) :: &
133 cld_frac, & ! Cloud-fraction for stratiform clouds
134 cld_lwp, & ! Water path for stratiform liquid cloud-particles
135 cld_reliq, & ! Effective radius for stratiform liquid cloud-particles
136 cld_iwp, & ! Water path for stratiform ice cloud-particles
137 cld_reice, & ! Effective radius for stratiform ice cloud-particles
138 cld_swp, & ! Water path for snow hydrometeors
139 cld_resnow, & ! Effective radius for snow hydrometeors
140 cld_rwp, & ! Water path for rain hydrometeors
141 cld_rerain, & ! Effective radius for rain hydrometeors
142 precip_frac, & ! Precipitation fraction
143 cloud_overlap_param !
144 real(kind_phys), dimension(:,:), intent(in), optional :: &
145 cld_cnv_lwp, & ! Water path for convective liquid cloud-particles
146 cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles
147 cld_cnv_iwp, & ! Water path for convective ice cloud-particles
148 cld_cnv_reice, & ! Effective radius for convective ice cloud-particles
149 cld_pbl_lwp, & ! Water path for PBL liquid cloud-particles
150 cld_pbl_reliq, & ! Effective radius for PBL liquid cloud-particles
151 cld_pbl_iwp, & ! Water path for PBL ice cloud-particles
152 cld_pbl_reice ! Effective radius for PBL ice cloud-particles
153 real(kind_phys), dimension(:,:,:), intent(in) :: &
154 aersw_tau, & ! Aerosol optical depth
155 aersw_ssa, & ! Aerosol single scattering albedo
156 aersw_g ! Aerosol asymmetry paramter
157 character(len=*), dimension(:), intent(in) :: &
158 active_gases_array ! List of active gases from namelist as array
159 real(kind_phys), intent(in) :: &
160 solcon ! Solar constant
161
162 ! Outputs
163 character(len=*), intent(out) :: &
164 errmsg ! CCPP error message
165 integer, intent(out) :: &
166 errflg ! CCPP error flag
167 real(kind_phys), dimension(:,:), intent(inout) :: &
168 cldtausw ! Approx 10.mu band layer cloud optical depth
169 real(kind_phys), dimension(:,:), intent(inout) :: &
170 fluxswup_allsky, & ! RRTMGP upward all-sky flux profiles (W/m2)
171 fluxswdown_allsky, & ! RRTMGP downward all-sky flux profiles (W/m2)
172 fluxswup_clrsky, & ! RRTMGP upward clear-sky flux profiles (W/m2)
173 fluxswdown_clrsky ! RRTMGP downward clear-sky flux profiles (W/m2)
174 type(cmpfsw_type), dimension(:), intent(inout) :: &
175 scmpsw ! 2D surface fluxes, components:
176 ! uvbfc - total sky downward uv-b flux (W/m2)
177 ! uvbf0 - clear sky downward uv-b flux (W/m2)
178 ! nirbm - downward nir direct beam flux (W/m2)
179 ! nirdf - downward nir diffused flux (W/m2)
180 ! visbm - downward uv+vis direct beam flux (W/m2)
181 ! visdf - downward uv+vis diffused flux (W/m2)
182
183 ! Local variables
184 type(cmpfsw_type), dimension(rrtmgp_phys_blksz) :: scmpsw_clrsky, scmpsw_allsky
185 type(ty_fluxes_byband) :: flux_allsky, flux_clrsky
186 real(kind_phys) :: tau_rain, tau_snow, ssa_rain, ssa_snow, asy_rain, asy_snow, &
187 tau_prec, asy_prec, ssa_prec, asyw, ssaw, za1, za2, flux_dir, flux_dif
188 real(kind_phys), dimension(rrtmgp_phys_blksz) :: zcf0, zcf1
189 real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()) :: rng1d
190 real(rte_wp), dimension(sw_gas_props%get_ngpt(),nLay,rrtmgp_phys_blksz) :: rng3d,rng3d2
191 real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()*nLay) :: rng2d
192 logical, dimension(rrtmgp_phys_blksz,nLay,sw_gas_props%get_ngpt()) :: maskmcica
193 logical :: cloudy_column, clear_column, dogp_sgs_pbl, dogp_sgs_cnv
194 real(rte_wp), dimension(sw_gas_props%get_nband(),rrtmgp_phys_blksz) :: &
195 sfc_alb_dir, sfc_alb_dif
196 real(rte_wp), dimension(rrtmgp_phys_blksz,nLay+1,sw_gas_props%get_nband()),target :: &
197 fluxsw_up_allsky, fluxsw_up_clrsky, fluxsw_dn_dir_clrsky, fluxsw_dn_allsky, &
198 fluxsw_dn_clrsky, fluxsw_dn_dir_allsky
199 integer :: iband, ibd, ibd_uv, icol, igas, ilay, ix, ix2, iblck
200 integer, dimension(rrtmgp_phys_blksz) :: ipseed_sw, icols
201 type(random_stat) :: rng_stat
202 real(kind_phys), dimension(2,sw_gas_props%get_nband()) :: bandlimits
203 real(kind_phys), dimension(2), parameter :: &
204 nir_uvvis_bnd = (/12850,16000/), &
205 uvb_bnd = (/29000,38000/)
206 real(rte_wp), dimension(rrtmgp_phys_blksz,sw_gas_props%get_ngpt()) :: toa_src_sw
207
208 type(ty_gas_concs) :: gas_concs
209 type(ty_optical_props_2str) :: sw_optical_props_accum, sw_optical_props_aerosol_local, &
210 sw_optical_props_cloudsbyband, sw_optical_props_cnvcloudsbyband, &
211 sw_optical_props_pblcloudsbyband, sw_optical_props_precipbyband, &
212 sw_optical_props_clouds
213
214 ! Initialize CCPP error handling variables
215 errmsg = ''
216 errflg = 0
217
218 if (.not. doswrad) return
219
220 ! Do we have convective cloud properties?
221 dogp_sgs_cnv = .false.
222 if (present(cld_cnv_lwp) .and. present(cld_cnv_reliq) .and. &
223 present(cld_cnv_iwp) .and. present(cld_cnv_reice)) then
224 dogp_sgs_cnv = .true.
225 endif
226 ! Do we have pbl cloud prperties?
227 dogp_sgs_pbl = .false.
228 if (present(cld_pbl_lwp) .and. present(cld_pbl_reliq) .and. &
229 present(cld_pbl_iwp) .and. present(cld_pbl_reice)) then
230 dogp_sgs_pbl = .true.
231 endif
232
233 ! ty_gas_concs
234 call check_error_msg('rrtmgp_sw_main_gas_concs_init',gas_concs%init(active_gases_array))
235
236 ! ty_optical_props
237 call check_error_msg('rrtmgp_sw_main_accumulated_optics_init',&
238 sw_optical_props_accum%alloc_2str(rrtmgp_phys_blksz, nlay, sw_gas_props))
239 call check_error_msg('rrtmgp_sw_main_cloud_optics_init',&
240 sw_optical_props_cloudsbyband%alloc_2str(rrtmgp_phys_blksz, nlay, sw_gas_props%get_band_lims_wavenumber()))
241 call check_error_msg('rrtmgp_sw_main_precip_optics_init',&
242 sw_optical_props_precipbyband%alloc_2str(rrtmgp_phys_blksz, nlay, sw_gas_props%get_band_lims_wavenumber()))
243 call check_error_msg('rrtmgp_sw_mian_cloud_sampling_init', &
244 sw_optical_props_clouds%alloc_2str(rrtmgp_phys_blksz, nlay, sw_gas_props))
245 call check_error_msg('rrtmgp_sw_main_aerosol_optics_init',&
246 sw_optical_props_aerosol_local%alloc_2str(rrtmgp_phys_blksz, nlay, sw_gas_props%get_band_lims_wavenumber()))
247 if (dogp_sgs_cnv) then
248 call check_error_msg('rrtmgp_sw_main_cnv_cloud_optics_init',&
249 sw_optical_props_cnvcloudsbyband%alloc_2str(rrtmgp_phys_blksz, nlay, sw_gas_props%get_band_lims_wavenumber()))
250 endif
251 if (dogp_sgs_pbl) then
252 call check_error_msg('rrtmgp_sw_main_pbl_cloud_optics_init',&
253 sw_optical_props_pblcloudsbyband%alloc_2str(rrtmgp_phys_blksz, nlay, sw_gas_props%get_band_lims_wavenumber()))
254 endif
255
256 if (nday .gt. 0) then
257
258 bandlimits = sw_gas_props%get_band_lims_wavenumber()
259 ! ######################################################################################
260 !
261 ! Loop over all (daylit) columns...
262 !
263 ! ######################################################################################
264 do icol=1,nday,rrtmgp_phys_blksz
265 !ix = idx(iCol)
266 !ix2 = idx(iCol + rrtmgp_phys_blksz - 1)
267 icols = idx(icol:icol + rrtmgp_phys_blksz - 1)
268
269 ! Create clear/cloudy indicator
270 zcf0(:) = 1._kind_phys
271 zcf1(:) = 1._kind_phys
272 do iblck = 1, rrtmgp_phys_blksz
273 do ilay=1,nlay
274 zcf0(iblck) = min(zcf0(iblck), 1._kind_phys - cld_frac(icols(iblck),ilay))
275 enddo
276 if (zcf0(iblck) <= ftiny) zcf0(iblck) = 0._kind_phys
277 if (zcf0(iblck) > oneminus) zcf0(iblck) = 1._kind_phys
278 zcf1(iblck) = 1._kind_phys - zcf0(iblck)
279 enddo
280 cloudy_column = any(zcf1 .gt. eps)
281 clear_column = .true.
282 if (cloudy_column) clear_column = .false.
283
284 ! ###################################################################################
285 !
286 ! Initialize/reset
287 !
288 ! ###################################################################################
289 sw_optical_props_clouds%tau = 0._kind_phys
290 sw_optical_props_clouds%ssa = 0._kind_phys
291 sw_optical_props_clouds%g = 0._kind_phys
292 sw_optical_props_accum%tau = 0._kind_phys
293 sw_optical_props_accum%ssa = 0._kind_phys
294 sw_optical_props_accum%g = 0._kind_phys
295 sw_optical_props_cloudsbyband%tau = 0._kind_phys
296 sw_optical_props_cloudsbyband%ssa = 0._kind_phys
297 sw_optical_props_cloudsbyband%g = 0._kind_phys
298 sw_optical_props_precipbyband%tau = 0._kind_phys
299 sw_optical_props_precipbyband%ssa = 0._kind_phys
300 sw_optical_props_precipbyband%g = 0._kind_phys
301 if (dogp_sgs_cnv) then
302 sw_optical_props_cnvcloudsbyband%tau = 0._kind_phys
303 sw_optical_props_cnvcloudsbyband%ssa = 0._kind_phys
304 sw_optical_props_cnvcloudsbyband%g = 0._kind_phys
305 endif
306 if (dogp_sgs_pbl) then
307 sw_optical_props_pblcloudsbyband%tau = 0._kind_phys
308 sw_optical_props_pblcloudsbyband%ssa = 0._kind_phys
309 sw_optical_props_pblcloudsbyband%g = 0._kind_phys
310 endif
311 scmpsw_clrsky= cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 )
312 scmpsw_allsky= cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 )
313 cldtausw = 0._kind_phys
314
315 ! ty_fluxes_byband
316 fluxsw_up_allsky = 0._rte_wp
317 fluxsw_dn_allsky = 0._rte_wp
318 fluxsw_dn_dir_allsky = 0._rte_wp
319 fluxsw_up_clrsky = 0._rte_wp
320 fluxsw_dn_clrsky = 0._rte_wp
321 flux_allsky%bnd_flux_up => fluxsw_up_allsky
322 flux_allsky%bnd_flux_dn => fluxsw_dn_allsky
323 flux_allsky%bnd_flux_dn_dir => fluxsw_dn_dir_allsky
324 flux_clrsky%bnd_flux_up => fluxsw_up_clrsky
325 flux_clrsky%bnd_flux_dn => fluxsw_dn_clrsky
326
327 ! ###################################################################################
328 !
329 ! Set gas-concentrations
330 !
331 ! ###################################################################################
332 call check_error_msg('rrtmgp_sw_main_set_vmr_o2', &
333 gas_concs%set_vmr(trim(active_gases_array(istr_o2)), real(vmr_o2(icols,:), kind=rte_wp)))
334 call check_error_msg('rrtmgp_sw_main_set_vmr_co2', &
335 gas_concs%set_vmr(trim(active_gases_array(istr_co2)),real(vmr_co2(icols,:), kind=rte_wp)))
336 call check_error_msg('rrtmgp_sw_main_set_vmr_ch4', &
337 gas_concs%set_vmr(trim(active_gases_array(istr_ch4)),real(vmr_ch4(icols,:), kind=rte_wp)))
338 call check_error_msg('rrtmgp_sw_main_set_vmr_n2o', &
339 gas_concs%set_vmr(trim(active_gases_array(istr_n2o)),real(vmr_n2o(icols,:), kind=rte_wp)))
340 call check_error_msg('rrtmgp_sw_main_set_vmr_h2o', &
341 gas_concs%set_vmr(trim(active_gases_array(istr_h2o)),real(vmr_h2o(icols,:), kind=rte_wp)))
342 call check_error_msg('rrtmgp_sw_main_set_vmr_o3', &
343 gas_concs%set_vmr(trim(active_gases_array(istr_o3)), real(vmr_o3(icols,:), kind=rte_wp)))
344
345 ! ###################################################################################
346 !
347 ! Compute gas-optics
348 !
349 ! ###################################################################################
350
351 call check_error_msg('rrtmgp_sw_main_gas_optics',sw_gas_props%gas_optics(&
352 real(p_lay(icols,:), kind=rte_wp), & ! IN - Pressure @ layer-centers (Pa)
353 real(p_lev(icols,:), kind=rte_wp), & ! IN - Pressure @ layer-interfaces (Pa)
354 real(t_lay(icols,:), kind=rte_wp), & ! IN - Temperature @ layer-centers (K)
355 gas_concs, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios
356 sw_optical_props_accum, & ! OUT - RRTMGP DDT: Shortwave optical properties, by
357 ! spectral point (tau,ssa,g)
358 toa_src_sw)) ! OUT - TOA incident shortwave radiation (spectral)
359 ! Scale incident flux
360 do iblck = 1, rrtmgp_phys_blksz
361 toa_src_sw(iblck,:) = toa_src_sw(iblck,:)*solcon / sum(toa_src_sw(iblck,:))
362 enddo
363
364 ! ###################################################################################
365 !
366 ! Set surface albedo
367 !
368 ! Use near-IR albedo for bands with wavenumbers extending to 12850cm-1
369 ! Use uv-vis albedo for bands with wavenumbers greater than 16000cm-1
370 ! For overlapping band, average near-IR and us-vis albedos.
371 !
372 ! ###################################################################################
373 do iblck = 1, rrtmgp_phys_blksz
374 do iband=1,sw_gas_props%get_nband()
375 if (bandlimits(1,iband) .lt. nir_uvvis_bnd(1)) then
376 sfc_alb_dir(iband,iblck) = sfc_alb_nir_dir(icols(iblck))
377 sfc_alb_dif(iband,iblck) = sfc_alb_nir_dif(icols(iblck))
378 endif
379 if (bandlimits(1,iband) .eq. nir_uvvis_bnd(1)) then
380 sfc_alb_dir(iband,iblck) = 0.5_kind_phys*(sfc_alb_nir_dir(icols(iblck)) + &
381 sfc_alb_uvvis_dir(icols(iblck)))
382 sfc_alb_dif(iband,iblck) = 0.5_kind_phys*(sfc_alb_nir_dif(icols(iblck)) + &
383 sfc_alb_uvvis_dif(icols(iblck)))
384 ibd = iband
385 endif
386 if (bandlimits(1,iband) .ge. nir_uvvis_bnd(2)) then
387 sfc_alb_dir(iband,iblck) = sfc_alb_uvvis_dir(icols(iblck))
388 sfc_alb_dif(iband,iblck) = sfc_alb_uvvis_dif(icols(iblck))
389 endif
390 if (bandlimits(1,iband) .eq. uvb_bnd(1)) ibd_uv = iband
391 enddo
392 enddo
393
394 ! ###################################################################################
395 !
396 ! Compute optics for cloud(s) and precipitation, sample clouds...
397 !
398 ! ###################################################################################
399 if (cloudy_column) then
400 ! Gridmean/mp-clouds
401 call check_error_msg('rrtmgp_sw_main_cloud_optics',sw_cloud_props%cloud_optics(&
402 real(cld_lwp(icols,:), kind=rte_wp), & ! IN - Cloud liquid water path
403 real(cld_iwp(icols,:), kind=rte_wp), & ! IN - Cloud ice water path
404 real(cld_reliq(icols,:),kind=rte_wp), & ! IN - Cloud liquid effective radius
405 real(cld_reice(icols,:),kind=rte_wp), & ! IN - Cloud ice effective radius
406 sw_optical_props_cloudsbyband)) ! OUT - RRTMGP DDT: Shortwave optical properties,
407 ! in each band (tau,ssa,g)
408 cldtausw(icols,:) = sw_optical_props_cloudsbyband%tau(:,:,11)
409
410 ! Include convective clouds?
411 if (dogp_sgs_cnv) then
412 ! Compute
413 call check_error_msg('rrtmgp_sw_main_cnv_cloud_optics',sw_cloud_props%cloud_optics(&
414 real(cld_cnv_lwp(icols,:), kind=rte_wp), & ! IN - Convective cloud liquid water path (g/m2)
415 real(cld_cnv_iwp(icols,:), kind=rte_wp), & ! IN - Convective cloud ice water path (g/m2)
416 real(cld_cnv_reliq(icols,:),kind=rte_wp), & ! IN - Convective cloud liquid effective radius (microns)
417 real(cld_cnv_reice(icols,:),kind=rte_wp), & ! IN - Convective cloud ice effective radius (microns)
418 sw_optical_props_cnvcloudsbyband)) ! OUT - RRTMGP DDT containing convective cloud radiative properties
419 ! in each band
420 ! Increment
421 call check_error_msg('rrtmgp_sw_main_increment_cnvclouds_to_clouds',&
422 sw_optical_props_cnvcloudsbyband%increment(sw_optical_props_cloudsbyband))
423 endif
424
425 ! Include PBL clouds?
426 if (dogp_sgs_pbl) then
427 ! Compute
428 call check_error_msg('rrtmgp_sw_main_pbl_cloud_optics',sw_cloud_props%cloud_optics(&
429 real(cld_pbl_lwp(icols,:), kind=rte_wp), & ! IN - PBL cloud liquid water path (g/m2)
430 real(cld_pbl_iwp(icols,:), kind=rte_wp), & ! IN - PBL cloud ice water path (g/m2)
431 real(cld_pbl_reliq(icols,:), kind=rte_wp), & ! IN - PBL cloud liquid effective radius (microns)
432 real(cld_pbl_reice(icols,:), kind=rte_wp), & ! IN - PBL cloud ice effective radius (microns)
433 sw_optical_props_pblcloudsbyband)) ! OUT - RRTMGP DDT containing PBL cloud radiative properties
434 ! in each band
435 ! Increment
436 call check_error_msg('rrtmgp_sw_main_increment_pblclouds_to_clouds',&
437 sw_optical_props_pblcloudsbyband%increment(sw_optical_props_cloudsbyband))
438 endif
439
440 ! Cloud precipitation optics: rain and snow(+groupel)
441 do iblck = 1, rrtmgp_phys_blksz
442 do ilay=1,nlay
443 if (cld_frac(icols(iblck),ilay) .gt. ftiny) then
444 ! Rain/Snow optical depth (No band dependence)
445 tau_rain = cld_rwp(icols(iblck),ilay)*a0r
446 if (cld_swp(icols(iblck),ilay) .gt. 0. .and. cld_resnow(icols(iblck),ilay) .gt. 10._kind_phys) then
447 tau_snow = cld_swp(icols(iblck),ilay)*1.09087*(a0s + a1s/(1.0315*cld_resnow(icols(iblck),ilay))) ! fu's formula
448 else
449 tau_snow = 0._kind_phys
450 endif
451
452 ! Rain/Snow single-scattering albedo and asymmetry (Band dependent)
453 do iband=1,sw_gas_props%get_nband()
454 ! By species
455 ssa_rain = tau_rain*(1.-b0r(iband))
456 asy_rain = ssa_rain*c0r(iband)
457 ssa_snow = tau_snow*(1.-(b0s(iband)+b1s(iband)*1.0315*cld_resnow(icols(iblck),ilay)))
458 asy_snow = ssa_snow*c0s(iband)
459 ! Combine
460 tau_prec = max(1.e-12_kind_phys, tau_rain + tau_snow)
461 ssa_prec = max(1.e-12_kind_phys, ssa_rain + ssa_snow)
462 asy_prec = max(1.e-12_kind_phys, asy_rain + asy_snow)
463 asyw = asy_prec/max(1.e-12_kind_phys, ssa_prec)
464 ssaw = min(1._kind_phys-0.000001, ssa_prec/tau_prec)
465 za1 = asyw * asyw
466 za2 = ssaw * za1
467 sw_optical_props_precipbyband%tau(iblck,ilay,iband) = (1._kind_phys - za2) * tau_prec
468 sw_optical_props_precipbyband%ssa(iblck,ilay,iband) = (ssaw - za2) / (1._kind_phys - za2)
469 sw_optical_props_precipbyband%g(iblck,ilay,iband) = asyw/(1+asyw)
470 enddo
471 endif
472 enddo
473 enddo
474 ! Increment
475 call check_error_msg('rrtmgp_sw_main_increment_precip_to_clouds',&
476 sw_optical_props_precipbyband%increment(sw_optical_props_cloudsbyband))
477
478 ! ###################################################################################
479 !
480 ! Cloud-sampling
481 !
482 ! ###################################################################################
483 ! Change random number seed value for each radiation invocation (isubc_sw =1 or 2).
484 if(isubc_sw == 1) then ! advance prescribed permutation seed
485 do iblck = 1, rrtmgp_phys_blksz
486 ipseed_sw(iblck) = sw_gas_props%get_ngpt() + icols(iblck)
487 enddo
488 elseif (isubc_sw == 2) then ! use input array of permutation seeds
489 do iblck = 1, rrtmgp_phys_blksz
490 ipseed_sw(iblck) = icseed_sw(icols(iblck))
491 enddo
492 endif
493
494 ! Call RNG
495 do iblck = 1, rrtmgp_phys_blksz
496 call random_setseed(ipseed_sw(iblck),rng_stat)
497 ! Use same rng for each layer
498 if (iovr == iovr_max) then
499 call random_number(rng1d,rng_stat)
500 do ilay=1,nlay
501 rng3d(:,ilay,iblck) = rng1d
502 enddo
503 else
504 do ilay=1,nlay
505 call random_number(rng1d,rng_stat)
506 rng3d(:,ilay,iblck) = rng1d
507 enddo
508 endif
509 enddo
510
511 ! Cloud-overlap.
512 ! Maximum-random, random or maximum.
513 if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then
514 call sampled_mask(rng3d, real(cld_frac(icols,:), kind=rte_wp), maskmcica)
515 endif
516 ! Exponential decorrelation length overlap
517 if (iovr == iovr_dcorr) then
518 do iblck = 1, rrtmgp_phys_blksz
519 ! Generate second RNG
520 call random_setseed(ipseed_sw(iblck),rng_stat)
521 call random_number(rng2d,rng_stat)
522 rng3d2(:,:,iblck) = reshape(source = rng2d,shape=[sw_gas_props%get_ngpt(),nlay])
523 enddo
524 !
525 call sampled_mask(rng3d, real(cld_frac(icols,:), kind=rte_wp), &
526 maskmcica, overlap_param = real(cloud_overlap_param(icols,1:nlay-1), kind=rte_wp),&
527 randoms2 = rng3d2)
528 endif
529 ! Exponential or Exponential-random
530 if (iovr == iovr_exp .or. iovr == iovr_exprand) then
531 call sampled_mask(rng3d, real(cld_frac(icols,:), kind=rte_wp), &
532 maskmcica, overlap_param = real(cloud_overlap_param(icols,1:nlay-1), kind=rte_wp))
533 endif
534 ! Sampling. Map band optical depth to each g-point using McICA
535 call check_error_msg('rrtmgp_sw_main_cloud_sampling',&
536 draw_samples(maskmcica, .true., &
537 sw_optical_props_cloudsbyband, sw_optical_props_clouds))
538 endif ! cloudy_column
539
540 ! ###################################################################################
541 !
542 ! Compute clear-sky fluxes (gaseous+aerosol)
543 !
544 ! ###################################################################################
545 ! Increment optics (always)
546 sw_optical_props_aerosol_local%tau = aersw_tau(icols,:,:)
547 sw_optical_props_aerosol_local%ssa = aersw_ssa(icols,:,:)
548 sw_optical_props_aerosol_local%g = aersw_g(icols,:,:)
549 call check_error_msg('rrtmgp_sw_main_increment_aerosol_to_clrsky', &
550 sw_optical_props_aerosol_local%increment(sw_optical_props_accum))
551
552 ! Compute clear-sky fluxes (Yes for no-clouds. Optional for cloudy scenes)
553 if (clear_column .or. doswclrsky) then
554 call check_error_msg('rrtmgp_sw_main_rte_sw_clrsky',rte_sw( &
555 sw_optical_props_accum, & ! IN - optical-properties
556 top_at_1, & ! IN - veritcal ordering flag
557 real(coszen(icols), kind=rte_wp), & ! IN - Cosine of solar zenith angle
558 toa_src_sw, & ! IN - incident solar flux at TOA
559 sfc_alb_dir, & ! IN - Shortwave surface albedo (direct)
560 sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse)
561 flux_clrsky)) ! OUT - Fluxes, clear-sky, 3D (1,nLay,nBand)
562
563 ! Store fluxes
564 fluxswup_clrsky(icols,:) = sum(flux_clrsky%bnd_flux_up, dim=3)
565 fluxswdown_clrsky(icols,:) = sum(flux_clrsky%bnd_flux_dn, dim=3)
566
567 ! Compute surface downward beam/diffused flux components
568 do iblck = 1, rrtmgp_phys_blksz
569 do iband=1,sw_gas_props%get_nband()
570 flux_dir = flux_clrsky%bnd_flux_dn(iblck,isfc,iband)
571 flux_dif = 0._kind_phys
572 ! Near-IR bands
573 if (iband < ibd) then
574 scmpsw_clrsky(iblck)%nirbm = scmpsw_clrsky(iblck)%nirbm + flux_dir
575 scmpsw_clrsky(iblck)%nirdf = scmpsw_clrsky(iblck)%nirdf + flux_dif
576 endif
577 ! Transition band
578 if (iband == ibd) then
579 scmpsw_clrsky(iblck)%nirbm = scmpsw_clrsky(iblck)%nirbm + flux_dir*0.5_kind_phys
580 scmpsw_clrsky(iblck)%nirdf = scmpsw_clrsky(iblck)%nirdf + flux_dif*0.5_kind_phys
581 scmpsw_clrsky(iblck)%visbm = scmpsw_clrsky(iblck)%visbm + flux_dir*0.5_kind_phys
582 scmpsw_clrsky(iblck)%visdf = scmpsw_clrsky(iblck)%visdf + flux_dif*0.5_kind_phys
583 endif
584 ! UV-VIS bands
585 if (iband > ibd) then
586 scmpsw_clrsky(iblck)%visbm = scmpsw_clrsky(iblck)%visbm + flux_dir
587 scmpsw_clrsky(iblck)%visdf = scmpsw_clrsky(iblck)%visdf + flux_dif
588 endif
589 ! uv-b surface downward flux
590 scmpsw_clrsky(iblck)%uvbfc = flux_clrsky%bnd_flux_dn(iblck,isfc,ibd_uv)
591 enddo
592 enddo
593 else
594 fluxswup_clrsky(icols,:) = 0._kind_phys
595 fluxswdown_clrsky(icols,:) = 0._kind_phys
596 scmpsw = cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 )
597 endif
598
599 ! ###################################################################################
600 !
601 ! All-sky fluxes (clear-sky + clouds + precipitation)
602 !
603 ! ###################################################################################
604 if (cloudy_column) then
605 ! Delta scale
606 !call check_error_msg('rrtmgp_sw_main_delta_scale',sw_optical_props_clouds%delta_scale())
607
608 ! Increment
609 call check_error_msg('rrtmgp_sw_main_increment_clouds_to_clrsky', &
610 sw_optical_props_clouds%increment(sw_optical_props_accum))
611
612 ! Compute fluxes
613 call check_error_msg('rrtmgp_sw_main_rte_sw_allsky',rte_sw( &
614 sw_optical_props_accum, & ! IN - optical-properties
615 top_at_1, & ! IN - veritcal ordering flag
616 real(coszen(icols), kind=rte_wp), & ! IN - Cosine of solar zenith angle
617 toa_src_sw, & ! IN - incident solar flux at TOA
618 sfc_alb_dir, & ! IN - Shortwave surface albedo (direct)
619 sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse)
620 flux_allsky)) ! OUT - Fluxes, clear-sky, 3D (1,nLay,nBand)
621
622 ! Store fluxes
623 fluxswup_allsky(icols,:) = sum(flux_allsky%bnd_flux_up, dim=3)
624 fluxswdown_allsky(icols,:) = sum(flux_allsky%bnd_flux_dn, dim=3)
625
626 ! Compute and store downward beam/diffused flux components
627 do iblck = 1, rrtmgp_phys_blksz
628 ! Loop over bands, sum fluxes...
629 do iband=1,sw_gas_props%get_nband()
630 flux_dir = flux_allsky%bnd_flux_dn_dir(iblck,isfc,iband)
631 flux_dif = flux_allsky%bnd_flux_dn(iblck,isfc,iband) - flux_allsky%bnd_flux_dn_dir(iblck,isfc,iband)
632 ! Near-IR bands
633 if (iband < ibd) then
634 scmpsw_allsky(iblck)%nirbm = scmpsw_allsky(iblck)%nirbm + flux_dir
635 scmpsw_allsky(iblck)%nirdf = scmpsw_allsky(iblck)%nirdf + flux_dif
636 endif
637 ! Transition band
638 if (iband == ibd) then
639 scmpsw_allsky(iblck)%nirbm = scmpsw_allsky(iblck)%nirbm + flux_dir*0.5_kind_phys
640 scmpsw_allsky(iblck)%nirdf = scmpsw_allsky(iblck)%nirdf + flux_dif*0.5_kind_phys
641 scmpsw_allsky(iblck)%visbm = scmpsw_allsky(iblck)%visbm + flux_dir*0.5_kind_phys
642 scmpsw_allsky(iblck)%visdf = scmpsw_allsky(iblck)%visdf + flux_dif*0.5_kind_phys
643 endif
644 ! UV-VIS bands
645 if (iband > ibd) then
646 scmpsw_allsky(iblck)%visbm = scmpsw_allsky(iblck)%visbm + flux_dir
647 scmpsw_allsky(iblck)%visdf = scmpsw_allsky(iblck)%visdf + flux_dif
648 endif
649 ! uv-b surface downward flux
650 scmpsw_allsky(iblck)%uvbfc = flux_allsky%bnd_flux_dn(iblck,isfc,ibd_uv)
651 enddo
652 ! Store surface downward beam/diffused flux components
653 if (zcf1(iblck) .gt. eps) then
654 scmpsw(icols(iblck))%nirbm = scmpsw_allsky(iblck)%nirbm
655 scmpsw(icols(iblck))%nirdf = scmpsw_allsky(iblck)%nirdf
656 scmpsw(icols(iblck))%visbm = scmpsw_allsky(iblck)%visbm
657 scmpsw(icols(iblck))%visdf = scmpsw_allsky(iblck)%visdf
658 scmpsw(icols(iblck))%uvbfc = flux_allsky%bnd_flux_dn(iblck,isfc,ibd_uv)
659 else
660 scmpsw(icols(iblck))%nirbm = scmpsw_clrsky(iblck)%nirbm
661 scmpsw(icols(iblck))%nirdf = scmpsw_clrsky(iblck)%nirdf
662 scmpsw(icols(iblck))%visbm = scmpsw_clrsky(iblck)%visbm
663 scmpsw(icols(iblck))%visdf = scmpsw_clrsky(iblck)%visdf
664 scmpsw(icols(iblck))%uvbfc = flux_clrsky%bnd_flux_dn(iblck,isfc,ibd_uv)
665 endif
666 scmpsw(icols(iblck))%uvbf0 = flux_clrsky%bnd_flux_dn(iblck,isfc,ibd_uv)
667 enddo
668 else ! No clouds
669 fluxswup_allsky(icols,:) = sum(flux_clrsky%bnd_flux_up, dim=3)
670 fluxswdown_allsky(icols,:) = sum(flux_clrsky%bnd_flux_dn, dim=3)
671 do iblck = 1, rrtmgp_phys_blksz
672 scmpsw(icols(iblck))%nirbm = scmpsw_clrsky(iblck)%nirbm
673 scmpsw(icols(iblck))%nirdf = scmpsw_clrsky(iblck)%nirdf
674 scmpsw(icols(iblck))%visbm = scmpsw_clrsky(iblck)%visbm
675 scmpsw(icols(iblck))%visdf = scmpsw_clrsky(iblck)%visdf
676 scmpsw(icols(iblck))%uvbfc = flux_clrsky%bnd_flux_dn(iblck,isfc,ibd_uv)
677 scmpsw(icols(iblck))%uvbf0 = flux_clrsky%bnd_flux_dn(iblck,isfc,ibd_uv)
678 enddo
679 endif
680 !
681 enddo ! nday
682 else
683 fluxswup_allsky(:,:) = 0._kind_phys
684 fluxswdown_allsky(:,:) = 0._kind_phys
685 fluxswup_clrsky(:,:) = 0._kind_phys
686 fluxswdown_clrsky(:,:) = 0._kind_phys
687 scmpsw = cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 )
688 endif
689 end subroutine rrtmgp_sw_main_run
690end module rrtmgp_sw_main
This module calculates random numbers using the Mersenne twister.
This module is for specifying the band structures and program parameters used by the RRTMG-SW scheme.
Definition radsw_param.f:62
This module contains tools for radiation.
This module provides a simple implementation of sampling for the Monte Carlo Independent Pixel Approx...
This module contains the cloud optics properties calculation for RRTMGP-SW.
This module contains a routine to initialize the k-distribution data used by the RRTMGP shortwave rad...
This module contain the RRTMGP-SW radiation scheme.
derived type for special components of surface SW fluxes