CCPP SciDoc v7.0.0  v7.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
rrtmgp_sw_cloud_optics.F90
1
3
6 use machine, only: kind_phys
7 use mo_rte_kind, only: wl
8 use mo_cloud_optics, only: ty_cloud_optics
9 use rrtmgp_sw_gas_optics, only: sw_gas_props
10 use radiation_tools, only: check_error_msg
11 use netcdf
12#ifdef MPI
13 use mpi_f08
14#endif
15
16 implicit none
17
18 type(ty_cloud_optics) :: sw_cloud_props
19 integer :: &
20 nrghice_fromfilesw, nbandsw, nsize_liqsw, nsize_icesw, nsizeregsw, &
21 ncoeff_extsw, ncoeff_ssa_gsw, nboundsw, npairssw
22 real(kind_phys) :: &
23 radliq_facsw, & !< Factor for calculating LUT interpolation indices for liquid
24 radice_facsw
25 real(kind_phys), dimension(:,:), allocatable :: &
26 lut_extliqsw, & !< LUT shortwave liquid extinction coefficient
27 lut_ssaliqsw, & !< LUT shortwave liquid single scattering albedo
28 lut_asyliqsw, & !< LUT shortwave liquid asymmetry parameter
29 band_limscldsw
30 real(kind_phys), dimension(:,:,:), allocatable :: &
31 lut_exticesw, & !< LUT shortwave ice extinction coefficient
32 lut_ssaicesw, & !< LUT shortwave ice single scattering albedo
33 lut_asyicesw
34 real(kind_phys), dimension(:), allocatable :: &
35 pade_sizereg_extliqsw, & !< Particle size regime boundaries for shortwave liquid extinction
36
37 pade_sizereg_ssaliqsw, &
39 pade_sizereg_asyliqsw, &
41 pade_sizereg_exticesw, &
43 pade_sizereg_ssaicesw, &
45 pade_sizereg_asyicesw
47 real(kind_phys), dimension(:,:,:), allocatable :: &
48 pade_extliqsw, & !< PADE coefficients for shortwave liquid extinction
49 pade_ssaliqsw, & !< PADE coefficients for shortwave liquid single scattering albedo
50 pade_asyliqsw
51 real(kind_phys), dimension(:,:,:,:), allocatable :: &
52 pade_exticesw, & !< PADE coefficients for shortwave ice extinction
53 pade_ssaicesw, & !< PADE coefficients for shortwave ice single scattering albedo
54 pade_asyicesw
55 real(kind_phys) :: &
56 radliq_lwrsw, & !< Liquid particle size lower bound for LUT interpolation
57 radliq_uprsw, & !< Liquid particle size upper bound for LUT interpolation
58 radice_lwrsw, & !< Ice particle size upper bound for LUT interpolation
59 radice_uprsw
60
61 ! Parameters used for rain and snow(+groupel) RRTMGP cloud-optics. *NOTE* Same as in RRTMG
62 ! Need to document these magic numbers below.
63 real(kind_phys),parameter :: &
64 a0r = 3.07e-3, & !
65 a0s = 0.0, & !
66 a1s = 1.5 !
67 real(kind_phys),dimension(:),allocatable :: b0r,b0s,b1s,c0r,c0s
68
69contains
70 ! ######################################################################################
71 ! SUBROUTINE sw_cloud_optics_init
72 ! ######################################################################################
74 subroutine rrtmgp_sw_cloud_optics_init( rrtmgp_root_dir, rrtmgp_sw_file_clouds, &
75 doGP_cldoptics_PADE, doGP_cldoptics_LUT, nrghice, mpicomm, mpirank, mpiroot, &
76 errmsg, errflg)
77
78 ! Inputs
79 character(len=128),intent(in) :: &
80 rrtmgp_root_dir, & !< RTE-RRTMGP root directory
81 rrtmgp_sw_file_clouds
82 logical, intent(in) :: &
83 doGP_cldoptics_PADE,& !< Use RRTMGP cloud-optics: PADE approximation?
84 doGP_cldoptics_LUT
85 integer, intent(inout) :: &
86 nrghice
87 type(mpi_comm), intent(in) :: &
88 mpicomm
89 integer, intent(in) :: &
90 mpirank, & !< Current MPI rank
91 mpiroot
92
93 ! Outputs
94 character(len=*), intent(out) :: &
95 errmsg
96 integer, intent(out) :: &
97 errflg
98
99 ! Local variables
100 integer :: status,ncid,dimid,varID,mpierr
101 character(len=264) :: sw_cloud_props_file
102
103 ! Initialize
104 errmsg = ''
105 errflg = 0
106
107 ! Filenames are set in the physics_nml
108 sw_cloud_props_file = trim(rrtmgp_root_dir)//trim(rrtmgp_sw_file_clouds)
109
110 ! #######################################################################################
111 !
112 ! Read dimensions for shortwave cloud-optics fields...
113 ! (ONLY master processor(0), if MPI enabled)
114 !
115 ! #######################################################################################
116#ifdef MPI
117 if (mpirank .eq. mpiroot) then
118#endif
119 write (*,*) 'Reading RRTMGP shortwave cloud-optics metadata ... '
120
121 ! Open file
122 status = nf90_open(trim(sw_cloud_props_file), nf90_nowrite, ncid)
123
124 ! Read dimensions
125 status = nf90_inq_dimid(ncid, 'nband', dimid)
126 status = nf90_inquire_dimension(ncid, dimid, len=nbandsw)
127 status = nf90_inq_dimid(ncid, 'nrghice', dimid)
128 status = nf90_inquire_dimension(ncid, dimid, len=nrghice_fromfilesw)
129 status = nf90_inq_dimid(ncid, 'nsize_liq', dimid)
130 status = nf90_inquire_dimension(ncid, dimid, len=nsize_liqsw)
131 status = nf90_inq_dimid(ncid, 'nsize_ice', dimid)
132 status = nf90_inquire_dimension(ncid, dimid, len=nsize_icesw)
133 status = nf90_inq_dimid(ncid, 'nsizereg', dimid)
134 status = nf90_inquire_dimension(ncid, dimid, len=nsizeregsw)
135 status = nf90_inq_dimid(ncid, 'ncoeff_ext', dimid)
136 status = nf90_inquire_dimension(ncid, dimid, len=ncoeff_extsw)
137 status = nf90_inq_dimid(ncid, 'ncoeff_ssa_g', dimid)
138 status = nf90_inquire_dimension(ncid, dimid, len=ncoeff_ssa_gsw)
139 status = nf90_inq_dimid(ncid, 'nbound', dimid)
140 status = nf90_inquire_dimension(ncid, dimid, len=nboundsw)
141 status = nf90_inq_dimid(ncid, 'pair', dimid)
142 status = nf90_inquire_dimension(ncid, dimid, len=npairssw)
143#ifdef MPI
144 endif ! On master processor
145
146 ! Other processors waiting...
147 call mpi_barrier(mpicomm, mpierr)
148
149 ! #######################################################################################
150 !
151 ! Broadcast dimensions...
152 ! (ALL processors)
153 !
154 ! #######################################################################################
155 call mpi_bcast(nbandsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
156 call mpi_bcast(nsize_liqsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
157 call mpi_bcast(nsize_icesw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
158 call mpi_bcast(nsizeregsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
159 call mpi_bcast(ncoeff_extsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
160 call mpi_bcast(ncoeff_ssa_gsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
161 call mpi_bcast(nboundsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
162 call mpi_bcast(npairssw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
163#endif
164
165 ! Has the number of ice-roughnes categories been provided from the namelist?
166 ! If so, override nrghice from cloud-optics file
167 if (nrghice .ne. 0) nrghice_fromfilesw = nrghice
168#ifdef MPI
169 call mpi_bcast(nrghice_fromfilesw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
170#endif
171
172 ! #######################################################################################
173 !
174 ! Allocate space for arrays...
175 ! (ALL processors)
176 !
177 ! #######################################################################################
178 if (dogp_cldoptics_lut) then
179 allocate(lut_extliqsw(nsize_liqsw, nbandsw))
180 allocate(lut_ssaliqsw(nsize_liqsw, nbandsw))
181 allocate(lut_asyliqsw(nsize_liqsw, nbandsw))
182 allocate(lut_exticesw(nsize_icesw, nbandsw, nrghice_fromfilesw))
183 allocate(lut_ssaicesw(nsize_icesw, nbandsw, nrghice_fromfilesw))
184 allocate(lut_asyicesw(nsize_icesw, nbandsw, nrghice_fromfilesw))
185 endif
186 if (dogp_cldoptics_pade) then
187 allocate(pade_extliqsw(nbandsw, nsizeregsw, ncoeff_extsw ))
188 allocate(pade_ssaliqsw(nbandsw, nsizeregsw, ncoeff_ssa_gsw))
189 allocate(pade_asyliqsw(nbandsw, nsizeregsw, ncoeff_ssa_gsw))
190 allocate(pade_exticesw(nbandsw, nsizeregsw, ncoeff_extsw, nrghice_fromfilesw))
191 allocate(pade_ssaicesw(nbandsw, nsizeregsw, ncoeff_ssa_gsw, nrghice_fromfilesw))
192 allocate(pade_asyicesw(nbandsw, nsizeregsw, ncoeff_ssa_gsw, nrghice_fromfilesw))
193 allocate(pade_sizereg_extliqsw(nboundsw))
194 allocate(pade_sizereg_ssaliqsw(nboundsw))
195 allocate(pade_sizereg_asyliqsw(nboundsw))
196 allocate(pade_sizereg_exticesw(nboundsw))
197 allocate(pade_sizereg_ssaicesw(nboundsw))
198 allocate(pade_sizereg_asyicesw(nboundsw))
199 endif
200 allocate(band_limscldsw(2,nbandsw))
201
202 ! #######################################################################################
203 !
204 ! Read in data ...
205 ! (ONLY master processor(0), if MPI enabled)
206 !
207 ! #######################################################################################
208#ifdef MPI
209 if (mpirank .eq. mpiroot) then
210#endif
211 if (dogp_cldoptics_lut) then
212 write (*,*) 'Reading RRTMGP shortwave cloud data (LUT) ... '
213 status = nf90_inq_varid(ncid,'radliq_lwr',varid)
214 status = nf90_get_var(ncid,varid,radliq_lwrsw)
215 status = nf90_inq_varid(ncid,'radliq_upr',varid)
216 status = nf90_get_var(ncid,varid,radliq_uprsw)
217 status = nf90_inq_varid(ncid,'radliq_fac',varid)
218 status = nf90_get_var(ncid,varid,radliq_facsw)
219 status = nf90_inq_varid(ncid,'radice_lwr',varid)
220 status = nf90_get_var(ncid,varid,radice_lwrsw)
221 status = nf90_inq_varid(ncid,'radice_upr',varid)
222 status = nf90_get_var(ncid,varid,radice_uprsw)
223 status = nf90_inq_varid(ncid,'radice_fac',varid)
224 status = nf90_get_var(ncid,varid,radice_facsw)
225 status = nf90_inq_varid(ncid,'lut_extliq',varid)
226 status = nf90_get_var(ncid,varid,lut_extliqsw)
227 status = nf90_inq_varid(ncid,'lut_ssaliq',varid)
228 status = nf90_get_var(ncid,varid,lut_ssaliqsw)
229 status = nf90_inq_varid(ncid,'lut_asyliq',varid)
230 status = nf90_get_var(ncid,varid,lut_asyliqsw)
231 status = nf90_inq_varid(ncid,'lut_extice',varid)
232 status = nf90_get_var(ncid,varid,lut_exticesw)
233 status = nf90_inq_varid(ncid,'lut_ssaice',varid)
234 status = nf90_get_var(ncid,varid,lut_ssaicesw)
235 status = nf90_inq_varid(ncid,'lut_asyice',varid)
236 status = nf90_get_var(ncid,varid,lut_asyicesw)
237 status = nf90_inq_varid(ncid,'bnd_limits_wavenumber',varid)
238 status = nf90_get_var(ncid,varid,band_limscldsw)
239 endif
240 if (dogp_cldoptics_pade) then
241 write (*,*) 'Reading RRTMGP shortwave cloud data (PADE) ... '
242 status = nf90_inq_varid(ncid,'radliq_lwr',varid)
243 status = nf90_get_var(ncid,varid,radliq_lwrsw)
244 status = nf90_inq_varid(ncid,'radliq_upr',varid)
245 status = nf90_get_var(ncid,varid,radliq_uprsw)
246 status = nf90_inq_varid(ncid,'radliq_fac',varid)
247 status = nf90_get_var(ncid,varid,radliq_facsw)
248 status = nf90_inq_varid(ncid,'radice_lwr',varid)
249 status = nf90_get_var(ncid,varid,radice_lwrsw)
250 status = nf90_inq_varid(ncid,'radice_upr',varid)
251 status = nf90_get_var(ncid,varid,radice_uprsw)
252 status = nf90_inq_varid(ncid,'radice_fac',varid)
253 status = nf90_get_var(ncid,varid,radice_facsw)
254 status = nf90_inq_varid(ncid,'pade_extliq',varid)
255 status = nf90_get_var(ncid,varid,pade_extliqsw)
256 status = nf90_inq_varid(ncid,'pade_ssaliq',varid)
257 status = nf90_get_var(ncid,varid,pade_ssaliqsw)
258 status = nf90_inq_varid(ncid,'pade_asyliq',varid)
259 status = nf90_get_var(ncid,varid,pade_asyliqsw)
260 status = nf90_inq_varid(ncid,'pade_extice',varid)
261 status = nf90_get_var(ncid,varid,pade_exticesw)
262 status = nf90_inq_varid(ncid,'pade_ssaice',varid)
263 status = nf90_get_var(ncid,varid,pade_ssaicesw)
264 status = nf90_inq_varid(ncid,'pade_asyice',varid)
265 status = nf90_get_var(ncid,varid,pade_asyicesw)
266 status = nf90_inq_varid(ncid,'pade_sizreg_extliq',varid)
267 status = nf90_get_var(ncid,varid,pade_sizereg_extliqsw)
268 status = nf90_inq_varid(ncid,'pade_sizreg_ssaliq',varid)
269 status = nf90_get_var(ncid,varid,pade_sizereg_ssaliqsw)
270 status = nf90_inq_varid(ncid,'pade_sizreg_asyliq',varid)
271 status = nf90_get_var(ncid,varid,pade_sizereg_asyliqsw)
272 status = nf90_inq_varid(ncid,'pade_sizreg_extice',varid)
273 status = nf90_get_var(ncid,varid,pade_sizereg_exticesw)
274 status = nf90_inq_varid(ncid,'pade_sizreg_ssaice',varid)
275 status = nf90_get_var(ncid,varid,pade_sizereg_ssaicesw)
276 status = nf90_inq_varid(ncid,'pade_sizreg_asyice',varid)
277 status = nf90_get_var(ncid,varid,pade_sizereg_asyicesw)
278 status = nf90_inq_varid(ncid,'bnd_limits_wavenumber',varid)
279 status = nf90_get_var(ncid,varid,band_limscldsw)
280 endif
281
282 ! Close file
283 status = nf90_close(ncid)
284
285#ifdef MPI
286 endif ! Master process
287
288 ! Other processors waiting...
289 call mpi_barrier(mpicomm, mpierr)
290
291 ! #######################################################################################
292 !
293 ! Broadcast data...
294 ! (ALL processors)
295 !
296 ! #######################################################################################
297
298 ! Real scalars
299 call mpi_bcast(radliq_facsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
300 call mpi_bcast(radice_facsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
301 call mpi_bcast(radliq_lwrsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
302 call mpi_bcast(radliq_uprsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
303 call mpi_bcast(radice_lwrsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
304 call mpi_bcast(radice_uprsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
305
306 ! Real arrays
307 call mpi_bcast(band_limscldsw, size(band_limscldsw), &
308 mpi_double_precision, mpiroot, mpicomm, mpierr)
309 if (dogp_cldoptics_lut) then
310 call mpi_bcast(lut_extliqsw, size(lut_extliqsw), &
311 mpi_double_precision, mpiroot, mpicomm, mpierr)
312 call mpi_bcast(lut_ssaliqsw, size(lut_ssaliqsw), &
313 mpi_double_precision, mpiroot, mpicomm, mpierr)
314 call mpi_bcast(lut_asyliqsw, size(lut_asyliqsw), &
315 mpi_double_precision, mpiroot, mpicomm, mpierr)
316 call mpi_bcast(lut_exticesw, size(lut_exticesw), &
317 mpi_double_precision, mpiroot, mpicomm, mpierr)
318 call mpi_bcast(lut_ssaicesw, size(lut_ssaicesw), &
319 mpi_double_precision, mpiroot, mpicomm, mpierr)
320 call mpi_bcast(lut_asyicesw, size(lut_asyicesw), &
321 mpi_double_precision, mpiroot, mpicomm, mpierr)
322 endif
323 if (dogp_cldoptics_pade) then
324 call mpi_bcast(pade_extliqsw, size(pade_extliqsw), &
325 mpi_double_precision, mpiroot, mpicomm, mpierr)
326 call mpi_bcast(pade_ssaliqsw, size(pade_ssaliqsw), &
327 mpi_double_precision, mpiroot, mpicomm, mpierr)
328 call mpi_bcast(pade_asyliqsw, size(pade_asyliqsw), &
329 mpi_double_precision, mpiroot, mpicomm, mpierr)
330 call mpi_bcast(pade_exticesw, size(pade_exticesw), &
331 mpi_double_precision, mpiroot, mpicomm, mpierr)
332 call mpi_bcast(pade_ssaicesw, size(pade_ssaicesw), &
333 mpi_double_precision, mpiroot, mpicomm, mpierr)
334 call mpi_bcast(pade_asyicesw, size(pade_asyicesw), &
335 mpi_double_precision, mpiroot, mpicomm, mpierr)
336 call mpi_bcast(pade_sizereg_extliqsw, size(pade_sizereg_extliqsw), &
337 mpi_double_precision, mpiroot, mpicomm, mpierr)
338 call mpi_bcast(pade_sizereg_ssaliqsw, size(pade_sizereg_ssaliqsw), &
339 mpi_double_precision, mpiroot, mpicomm, mpierr)
340 call mpi_bcast(pade_sizereg_asyliqsw, size(pade_sizereg_asyliqsw), &
341 mpi_double_precision, mpiroot, mpicomm, mpierr)
342 call mpi_bcast(pade_sizereg_exticesw, size(pade_sizereg_exticesw), &
343 mpi_double_precision, mpiroot, mpicomm, mpierr)
344 call mpi_bcast(pade_sizereg_ssaicesw, size(pade_sizereg_ssaicesw), &
345 mpi_double_precision, mpiroot, mpicomm, mpierr)
346 call mpi_bcast(pade_sizereg_asyicesw, size(pade_sizereg_asyicesw), &
347 mpi_double_precision, mpiroot, mpicomm, mpierr)
348 endif
349#endif
350
351 ! #######################################################################################
352 !
353 ! Initialize RRTMGP DDT's...
354 !
355 ! #######################################################################################
356 if (dogp_cldoptics_lut) then
357 call check_error_msg('sw_cloud_optics_init',sw_cloud_props%load(band_limscldsw, &
358 radliq_lwrsw, radliq_uprsw, radliq_facsw, radice_lwrsw, radice_uprsw, &
359 radice_facsw, lut_extliqsw, lut_ssaliqsw, lut_asyliqsw, lut_exticesw, &
360 lut_ssaicesw, lut_asyicesw))
361 endif
362
363 if (dogp_cldoptics_pade) then
364 call check_error_msg('sw_cloud_optics_init', sw_cloud_props%load(band_limscldsw, &
365 pade_extliqsw, pade_ssaliqsw, pade_asyliqsw, pade_exticesw, pade_ssaicesw, &
366 pade_asyicesw, pade_sizereg_extliqsw, pade_sizereg_ssaliqsw, &
367 pade_sizereg_asyliqsw, pade_sizereg_exticesw, pade_sizereg_ssaicesw, &
368 pade_sizereg_asyicesw))
369 endif
370
371 call check_error_msg('sw_cloud_optics_init',sw_cloud_props%set_ice_roughness(nrghice_fromfilesw))
372
373 ! Initialize coefficients for rain and snow(+groupel) cloud optics
374 allocate(b0r(sw_cloud_props%get_nband()),b0s(sw_cloud_props%get_nband()), &
375 b1s(sw_cloud_props%get_nband()),c0r(sw_cloud_props%get_nband()), &
376 c0s(sw_cloud_props%get_nband()))
377 b0r = (/0.496, 0.466, 0.437, 0.416, 0.391, 0.374, 0.352, &
378 0.183, 0.048, 0.012, 0.000, 0.000, 0.000, 0.000/)
379 b0s = (/0.460, 0.460, 0.460, 0.460, 0.460, 0.460, 0.460, &
380 0.460, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000/)
381 b1s = (/0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, &
382 0.000, 1.62e-5, 1.62e-5, 0.000, 0.000, 0.000, 0.000/)
383 c0r = (/0.980, 0.975, 0.965, 0.960, 0.955, 0.952, 0.950, &
384 0.944, 0.894, 0.884, 0.883, 0.883, 0.883, 0.883/)
385 c0s = (/0.970, 0.970, 0.970, 0.970, 0.970, 0.970, 0.970, &
386 0.970, 0.970, 0.970, 0.700, 0.700, 0.700, 0.700/)
387
388 end subroutine rrtmgp_sw_cloud_optics_init
389end module rrtmgp_sw_cloud_optics
This module contains tools for radiation.
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...