← 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_cloud_optics.F90
1
3
6 use mo_rte_kind, only: wl, wp
7 use mo_cloud_optics_rrtmgp, only: ty_cloud_optics => ty_cloud_optics_rrtmgp
8 use rrtmgp_sw_gas_optics, only: sw_gas_props
9 use radiation_tools, only: check_error_msg
10 use netcdf
11 use mpi_f08
12
13 implicit none
14
15 type(ty_cloud_optics) :: sw_cloud_props
16 integer :: &
17 nrghice_fromfileSW, nBandSW, nSize_liqSW, nSize_iceSW, nSizeregSW, &
18 nCoeff_extSW, nCoeff_ssa_gSW, nBoundSW, nPairsSW
19 real(wp), dimension(:,:), allocatable :: &
20 lut_extliqsw, & !< LUT shortwave liquid extinction coefficient
21 lut_ssaliqsw, & !< LUT shortwave liquid single scattering albedo
22 lut_asyliqsw, & !< LUT shortwave liquid asymmetry parameter
23 band_limscldsw
24 real(wp), dimension(:,:,:), allocatable :: &
25 lut_exticesw, & !< LUT shortwave ice extinction coefficient
26 lut_ssaicesw, & !< LUT shortwave ice single scattering albedo
27 lut_asyicesw
28 real(wp) :: &
29 radliq_lwrsw, & !< Liquid particle size lower bound for LUT interpolation
30 radliq_uprsw, & !< Liquid particle size upper bound for LUT interpolation
31 radice_lwrsw, & !< Ice particle size upper bound for LUT interpolation
32 radice_uprsw
33
34 ! Parameters used for rain and snow(+groupel) RRTMGP cloud-optics. *NOTE* Same as in RRTMG
35 ! Need to document these magic numbers below.
36 real(wp),parameter :: &
37 a0r = 3.07e-3, & !
38 a0s = 0.0, & !
39 a1s = 1.5 !
40 real(wp),dimension(:),allocatable :: b0r,b0s,b1s,c0r,c0s
41
42contains
43 ! ######################################################################################
44 ! SUBROUTINE sw_cloud_optics_init
45 ! ######################################################################################
47 subroutine rrtmgp_sw_cloud_optics_init( rrtmgp_root_dir, rrtmgp_sw_file_clouds, &
48 nrghice, mpicomm, mpirank, mpiroot, is_initialized, errmsg, errflg)
49
50 ! Inputs
51 character(len=128),intent(in) :: &
52 rrtmgp_root_dir, & !< RTE-RRTMGP root directory
53 rrtmgp_sw_file_clouds
54 integer, intent(inout) :: &
55 nrghice
56 type(mpi_comm), intent(in) :: &
57 mpicomm
58 integer, intent(in) :: &
59 mpirank, & !< Current MPI rank
60 mpiroot
61
62 ! Outputs
63 logical, intent(inout) :: &
64 is_initialized
65 character(len=*), intent( out) :: &
66 errmsg
67 integer, intent( out) :: &
68 errflg
69
70 ! Local variables
71 integer :: status,ncid,dimid,varID,mpierr
72 character(len=264) :: sw_cloud_props_file
73
74 ! Initialize
75 errmsg = ''
76 errflg = 0
77
78 if (is_initialized) return
79
80 ! Filenames are set in the physics_nml
81 sw_cloud_props_file = trim(rrtmgp_root_dir)//trim(rrtmgp_sw_file_clouds)
82
83 ! #######################################################################################
84 !
85 ! Read dimensions for shortwave cloud-optics fields...
86 ! (ONLY master processor(0), if MPI enabled)
87 !
88 ! #######################################################################################
89 if (mpirank .eq. mpiroot) then
90 write (*,*) 'Reading RRTMGP shortwave cloud-optics metadata ... '
91
92 ! Open file
93 status = nf90_open(trim(sw_cloud_props_file), nf90_nowrite, ncid)
94
95 ! Read dimensions
96 status = nf90_inq_dimid(ncid, 'nband', dimid)
97 status = nf90_inquire_dimension(ncid, dimid, len=nbandsw)
98 status = nf90_inq_dimid(ncid, 'nrghice', dimid)
99 status = nf90_inquire_dimension(ncid, dimid, len=nrghice_fromfilesw)
100 status = nf90_inq_dimid(ncid, 'nsize_liq', dimid)
101 status = nf90_inquire_dimension(ncid, dimid, len=nsize_liqsw)
102 status = nf90_inq_dimid(ncid, 'nsize_ice', dimid)
103 status = nf90_inquire_dimension(ncid, dimid, len=nsize_icesw)
104 status = nf90_inq_dimid(ncid, 'nsizereg', dimid)
105 status = nf90_inquire_dimension(ncid, dimid, len=nsizeregsw)
106 status = nf90_inq_dimid(ncid, 'ncoeff_ext', dimid)
107 status = nf90_inquire_dimension(ncid, dimid, len=ncoeff_extsw)
108 status = nf90_inq_dimid(ncid, 'ncoeff_ssa_g', dimid)
109 status = nf90_inquire_dimension(ncid, dimid, len=ncoeff_ssa_gsw)
110 status = nf90_inq_dimid(ncid, 'nbound', dimid)
111 status = nf90_inquire_dimension(ncid, dimid, len=nboundsw)
112 status = nf90_inq_dimid(ncid, 'pair', dimid)
113 status = nf90_inquire_dimension(ncid, dimid, len=npairssw)
114 endif ! On master processor
115
116 ! Other processors waiting...
117 call mpi_barrier(mpicomm, mpierr)
118
119 ! #######################################################################################
120 !
121 ! Broadcast dimensions...
122 ! (ALL processors)
123 !
124 ! #######################################################################################
125 call mpi_bcast(nbandsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
126 call mpi_bcast(nsize_liqsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
127 call mpi_bcast(nsize_icesw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
128 call mpi_bcast(nsizeregsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
129 call mpi_bcast(ncoeff_extsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
130 call mpi_bcast(ncoeff_ssa_gsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
131 call mpi_bcast(nboundsw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
132 call mpi_bcast(npairssw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
133
134 ! Has the number of ice-roughnes categories been provided from the namelist?
135 ! If so, override nrghice from cloud-optics file
136 if (nrghice .ne. 0) nrghice_fromfilesw = nrghice
137 call mpi_bcast(nrghice_fromfilesw, 1, mpi_integer, mpiroot, mpicomm, mpierr)
138
139 ! #######################################################################################
140 !
141 ! Allocate space for arrays...
142 ! (ALL processors)
143 !
144 ! #######################################################################################
145 allocate(lut_extliqsw(nsize_liqsw, nbandsw))
146 allocate(lut_ssaliqsw(nsize_liqsw, nbandsw))
147 allocate(lut_asyliqsw(nsize_liqsw, nbandsw))
148 allocate(lut_exticesw(nsize_icesw, nbandsw, nrghice_fromfilesw))
149 allocate(lut_ssaicesw(nsize_icesw, nbandsw, nrghice_fromfilesw))
150 allocate(lut_asyicesw(nsize_icesw, nbandsw, nrghice_fromfilesw))
151 allocate(band_limscldsw(2,nbandsw))
152
153 ! #######################################################################################
154 !
155 ! Read in data ...
156 ! (ONLY master processor(0), if MPI enabled)
157 !
158 ! #######################################################################################
159 if (mpirank .eq. mpiroot) then
160 write (*,*) 'Reading RRTMGP shortwave cloud data (LUT) ... '
161 status = nf90_inq_varid(ncid,'radliq_lwr',varid)
162 status = nf90_get_var(ncid,varid,radliq_lwrsw)
163 status = nf90_inq_varid(ncid,'radliq_upr',varid)
164 status = nf90_get_var(ncid,varid,radliq_uprsw)
165 status = nf90_inq_varid(ncid,'radice_lwr',varid)
166 status = nf90_get_var(ncid,varid,radice_lwrsw)
167 status = nf90_inq_varid(ncid,'radice_upr',varid)
168 status = nf90_get_var(ncid,varid,radice_uprsw)
169 status = nf90_inq_varid(ncid,'lut_extliq',varid)
170 status = nf90_get_var(ncid,varid,lut_extliqsw)
171 status = nf90_inq_varid(ncid,'lut_ssaliq',varid)
172 status = nf90_get_var(ncid,varid,lut_ssaliqsw)
173 status = nf90_inq_varid(ncid,'lut_asyliq',varid)
174 status = nf90_get_var(ncid,varid,lut_asyliqsw)
175 status = nf90_inq_varid(ncid,'lut_extice',varid)
176 status = nf90_get_var(ncid,varid,lut_exticesw)
177 status = nf90_inq_varid(ncid,'lut_ssaice',varid)
178 status = nf90_get_var(ncid,varid,lut_ssaicesw)
179 status = nf90_inq_varid(ncid,'lut_asyice',varid)
180 status = nf90_get_var(ncid,varid,lut_asyicesw)
181 status = nf90_inq_varid(ncid,'bnd_limits_wavenumber',varid)
182 status = nf90_get_var(ncid,varid,band_limscldsw)
183
184 ! Close file
185 status = nf90_close(ncid)
186
187 endif ! Master process
188
189 ! Other processors waiting...
190 call mpi_barrier(mpicomm, mpierr)
191
192 ! #######################################################################################
193 !
194 ! Broadcast data...
195 ! (ALL processors)
196 !
197 ! #######################################################################################
198
199 ! Real scalars
200#ifdef RTE_USE_SP
201 call mpi_bcast(radliq_lwrsw, 1, mpi_real, mpiroot, mpicomm, mpierr)
202 call mpi_bcast(radliq_uprsw, 1, mpi_real, mpiroot, mpicomm, mpierr)
203 call mpi_bcast(radice_lwrsw, 1, mpi_real, mpiroot, mpicomm, mpierr)
204 call mpi_bcast(radice_uprsw, 1, mpi_real, mpiroot, mpicomm, mpierr)
205#else
206 call mpi_bcast(radliq_lwrsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
207 call mpi_bcast(radliq_uprsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
208 call mpi_bcast(radice_lwrsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
209 call mpi_bcast(radice_uprsw, 1, mpi_double_precision, mpiroot, mpicomm, mpierr)
210#endif
211
212 ! Real arrays
213#ifdef RTE_USE_SP
214 call mpi_bcast(band_limscldsw, size(band_limscldsw), mpi_real, mpiroot, mpicomm, mpierr)
215 call mpi_bcast(lut_extliqsw, size(lut_extliqsw), mpi_real, mpiroot, mpicomm, mpierr)
216 call mpi_bcast(lut_ssaliqsw, size(lut_ssaliqsw), mpi_real, mpiroot, mpicomm, mpierr)
217 call mpi_bcast(lut_asyliqsw, size(lut_asyliqsw), mpi_real, mpiroot, mpicomm, mpierr)
218 call mpi_bcast(lut_exticesw, size(lut_exticesw), mpi_real, mpiroot, mpicomm, mpierr)
219 call mpi_bcast(lut_ssaicesw, size(lut_ssaicesw), mpi_real, mpiroot, mpicomm, mpierr)
220 call mpi_bcast(lut_asyicesw, size(lut_asyicesw), mpi_real, mpiroot, mpicomm, mpierr)
221#else
222 call mpi_bcast(band_limscldsw, size(band_limscldsw), mpi_double_precision, mpiroot, mpicomm, mpierr)
223 call mpi_bcast(lut_extliqsw, size(lut_extliqsw), mpi_double_precision, mpiroot, mpicomm, mpierr)
224 call mpi_bcast(lut_ssaliqsw, size(lut_ssaliqsw), mpi_double_precision, mpiroot, mpicomm, mpierr)
225 call mpi_bcast(lut_asyliqsw, size(lut_asyliqsw), mpi_double_precision, mpiroot, mpicomm, mpierr)
226 call mpi_bcast(lut_exticesw, size(lut_exticesw), mpi_double_precision, mpiroot, mpicomm, mpierr)
227 call mpi_bcast(lut_ssaicesw, size(lut_ssaicesw), mpi_double_precision, mpiroot, mpicomm, mpierr)
228 call mpi_bcast(lut_asyicesw, size(lut_asyicesw), mpi_double_precision, mpiroot, mpicomm, mpierr)
229#endif
230
231 ! #######################################################################################
232 !
233 ! Initialize RRTMGP DDT's...
234 !
235 ! #######################################################################################
236 call check_error_msg('sw_cloud_optics_init',sw_cloud_props%load(band_limscldsw, &
237 radliq_lwrsw, radliq_uprsw, radice_lwrsw, radice_uprsw, &
238 lut_extliqsw, lut_ssaliqsw, lut_asyliqsw, &
239 lut_exticesw, lut_ssaicesw, lut_asyicesw))
240
241 call check_error_msg('sw_cloud_optics_init',sw_cloud_props%set_ice_roughness(nrghice_fromfilesw))
242
243 ! Initialize coefficients for rain and snow(+groupel) cloud optics
244 allocate(b0r(sw_cloud_props%get_nband()),b0s(sw_cloud_props%get_nband()), &
245 b1s(sw_cloud_props%get_nband()),c0r(sw_cloud_props%get_nband()), &
246 c0s(sw_cloud_props%get_nband()))
247 b0r = (/0.496, 0.466, 0.437, 0.416, 0.391, 0.374, 0.352, &
248 0.183, 0.048, 0.012, 0.000, 0.000, 0.000, 0.000/)
249 b0s = (/0.460, 0.460, 0.460, 0.460, 0.460, 0.460, 0.460, &
250 0.460, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000/)
251 b1s = (/0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, &
252 0.000, 1.62e-5, 1.62e-5, 0.000, 0.000, 0.000, 0.000/)
253 c0r = (/0.980, 0.975, 0.965, 0.960, 0.955, 0.952, 0.950, &
254 0.944, 0.894, 0.884, 0.883, 0.883, 0.883, 0.883/)
255 c0s = (/0.970, 0.970, 0.970, 0.970, 0.970, 0.970, 0.970, &
256 0.970, 0.970, 0.970, 0.700, 0.700, 0.700, 0.700/)
257
258 is_initialized = .true.
259
260 end subroutine rrtmgp_sw_cloud_optics_init
261end 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...