@@ -124,278 +124,18 @@ NVTX.@annotate function cloud_fraction_model_callback!(integrator)
124124 set_cloud_fraction! (Y, p, p. atmos. moisture_model, p. atmos. cloud_model)
125125end
126126
127- # TODO : Move this somewhere else
128- update_o3! (_, _, _) = nothing
129- function update_o3! (p, t, :: PrescribedOzone )
130- evaluate! (p. tracers. o3, p. tracers. prescribed_o3_timevaryinginput, t)
131- return nothing
132- end
133-
134- update_co2! (_, _, _) = nothing
135- function update_co2! (p, t, :: MaunaLoaCO2 )
136- evaluate! (p. tracers. co2, p. tracers. prescribed_co2_timevaryinginput, t)
137- return nothing
138- end
139-
140-
141127NVTX. @annotate function rrtmgp_model_callback! (integrator)
142128 Y = integrator. u
143129 p = integrator. p
144130 t = integrator. t
145131
146- (; ᶜts, ᶜp, cloud_diagnostics_tuple, sfc_conditions) = p. precomputed
147132 (; params) = p
148133 (; ᶠradiation_flux, rrtmgp_model) = p. radiation
149134 (; radiation_mode) = p. atmos
150135
151- # If we have prescribed ozone or aerosols, we need to update them
152- update_o3! (p, t, p. atmos. ozone)
153- update_co2! (p, t, p. atmos. co2)
154- if :prescribed_aerosols_field in propertynames (p. tracers)
155- for (key, tv) in pairs (p. tracers. prescribed_aerosol_timevaryinginputs)
156- field = getproperty (p. tracers. prescribed_aerosols_field, key)
157- evaluate! (field, tv, t)
158- end
159- end
160- if :prescribed_clouds_field in propertynames (p. radiation)
161- for (key, tv) in pairs (p. radiation. prescribed_cloud_timevaryinginputs)
162- field = getproperty (p. radiation. prescribed_clouds_field, key)
163- evaluate! (field, tv, t)
164- end
165- end
166-
167- FT = Spaces. undertype (axes (Y. c))
168- thermo_params = CAP. thermodynamics_params (params)
169- cmc = CAP. microphysics_cloud_params (params)
170- T_min = CAP. optics_lookup_temperature_min (params)
171- T_max = CAP. optics_lookup_temperature_max (params)
172-
173- sfc_ts = sfc_conditions. ts
174- sfc_T = Fields. array2field (rrtmgp_model. surface_temperature, axes (sfc_ts))
175- @. sfc_T = TD. air_temperature (thermo_params, sfc_ts)
176-
177- rrtmgp_model. center_pressure .= Fields. field2array (ᶜp)
178- ᶜT = Fields. array2field (rrtmgp_model. center_temperature, axes (Y. c))
179- # TODO : move this to RRTMGP
180- @. ᶜT =
181- min (max (TD. air_temperature (thermo_params, ᶜts), FT (T_min)), FT (T_max))
182-
183- if ! (radiation_mode isa RRTMGPI. GrayRadiation)
184- ᶜrh =
185- Fields. array2field (rrtmgp_model. center_relative_humidity, axes (Y. c))
186- ᶜvmr_h2o = Fields. array2field (
187- rrtmgp_model. center_volume_mixing_ratio_h2o,
188- axes (Y. c),
189- )
190- if radiation_mode. idealized_h2o
191- # slowly increase the relative humidity from 0 to 0.6 to account for
192- # the fact that we have a very unrealistic initial condition
193- max_relative_humidity = FT (0.6 )
194- t_increasing_humidity = FT (60 * 60 * 24 * 30 )
195- if float (t) < t_increasing_humidity
196- max_relative_humidity *= float (t) / t_increasing_humidity
197- end
198- @. ᶜrh = max_relative_humidity
199-
200- # temporarily store ᶜq_tot in ᶜvmr_h2o
201- ᶜq_tot = ᶜvmr_h2o
202- @. ᶜq_tot =
203- max_relative_humidity * TD. q_vap_saturation (thermo_params, ᶜts)
204-
205- # filter ᶜq_tot so that it is monotonically decreasing with z
206- for i in 2 : Spaces. nlevels (axes (ᶜq_tot))
207- level = Fields. field_values (Spaces. level (ᶜq_tot, i))
208- prev_level = Fields. field_values (Spaces. level (ᶜq_tot, i - 1 ))
209- @. level = min (level, prev_level)
210- end
211-
212- # assume that ᶜq_vap = ᶜq_tot when computing ᶜvmr_h2o
213- @. ᶜvmr_h2o = TD. vol_vapor_mixing_ratio (
214- thermo_params,
215- TD. PhasePartition (ᶜq_tot),
216- )
217- else
218- @. ᶜvmr_h2o = TD. vol_vapor_mixing_ratio (
219- thermo_params,
220- TD. PhasePartition (thermo_params, ᶜts),
221- )
222- @. ᶜrh = min (max (TD. relative_humidity (thermo_params, ᶜts), 0 ), 1 )
223- end
224- end
136+ RRTMGPI. update_atmospheric_state! (integrator)
225137
226138 set_insolation_variables! (Y, p, t, p. atmos. insolation)
227-
228- if radiation_mode isa RRTMGPI. AllSkyRadiation ||
229- radiation_mode isa RRTMGPI. AllSkyRadiationWithClearSkyDiagnostics
230- if ! radiation_mode. idealized_clouds
231- ᶜΔz = Fields. Δz_field (Y. c)
232- ᶜlwp = Fields. array2field (
233- rrtmgp_model. center_cloud_liquid_water_path,
234- axes (Y. c),
235- )
236- ᶜiwp = Fields. array2field (
237- rrtmgp_model. center_cloud_ice_water_path,
238- axes (Y. c),
239- )
240- ᶜfrac = Fields. array2field (
241- rrtmgp_model. center_cloud_fraction,
242- axes (Y. c),
243- )
244- ᶜreliq = Fields. array2field (
245- rrtmgp_model. center_cloud_liquid_effective_radius,
246- axes (Y. c),
247- )
248- ᶜreice = Fields. array2field (
249- rrtmgp_model. center_cloud_ice_effective_radius,
250- axes (Y. c),
251- )
252- # RRTMGP needs lwp and iwp in g/m^2
253- kg_to_g_factor = 1000
254- m_to_um_factor = FT (1e6 )
255- cloud_liquid_water_content =
256- radiation_mode. cloud isa PrescribedCloudInRadiation ?
257- p. radiation. prescribed_clouds_field. clwc :
258- cloud_diagnostics_tuple. q_liq
259- cloud_ice_water_content =
260- radiation_mode. cloud isa PrescribedCloudInRadiation ?
261- p. radiation. prescribed_clouds_field. ciwc :
262- cloud_diagnostics_tuple. q_ice
263- cloud_fraction =
264- radiation_mode. cloud isa PrescribedCloudInRadiation ?
265- p. radiation. prescribed_clouds_field. cc :
266- cloud_diagnostics_tuple. cf
267- @. ᶜlwp =
268- kg_to_g_factor * Y. c. ρ * cloud_liquid_water_content * ᶜΔz /
269- max (cloud_fraction, eps (FT))
270- @. ᶜiwp =
271- kg_to_g_factor * Y. c. ρ * cloud_ice_water_content * ᶜΔz /
272- max (cloud_fraction, eps (FT))
273- @. ᶜfrac = cloud_fraction
274- # RRTMGP needs effective radius in microns
275-
276- seasalt_aero_conc = p. scratch. ᶜtemp_scalar
277- dust_aero_conc = p. scratch. ᶜtemp_scalar_2
278- SO4_aero_conc = p. scratch. ᶜtemp_scalar_3
279- @. seasalt_aero_conc = 0
280- @. dust_aero_conc = 0
281- @. SO4_aero_conc = 0
282- # Get aerosol mass concentrations if available
283- seasalt_names = [:SSLT01 , :SSLT02 , :SSLT03 , :SSLT04 , :SSLT05 ]
284- dust_names = [:DST01 , :DST02 , :DST03 , :DST04 , :DST05 ]
285- SO4_names = [:SO4 ]
286- if :prescribed_aerosols_field in propertynames (p. tracers)
287- aerosol_field = p. tracers. prescribed_aerosols_field
288- for aerosol_name in propertynames (aerosol_field)
289- if aerosol_name in seasalt_names
290- data = getproperty (aerosol_field, aerosol_name)
291- @. seasalt_aero_conc += data
292- elseif aerosol_name in dust_names
293- data = getproperty (aerosol_field, aerosol_name)
294- @. dust_aero_conc += data
295- elseif aerosol_name in SO4_names
296- data = getproperty (aerosol_field, aerosol_name)
297- @. SO4_aero_conc += data
298- end
299- end
300- end
301-
302- lwp_col = p. scratch. temp_field_level
303- ᶜliquid_water_mass_concentration =
304- @. lazy (cloud_liquid_water_content * Y. c. ρ)
305- Operators. column_integral_definite! (
306- lwp_col,
307- ᶜliquid_water_mass_concentration,
308- )
309-
310- @. ᶜreliq = ifelse (
311- cloud_liquid_water_content > FT (0 ),
312- CM. CloudDiagnostics. effective_radius_Liu_Hallet_97 (
313- cmc. liquid,
314- Y. c. ρ,
315- cloud_liquid_water_content / max (eps (FT), cloud_fraction),
316- ml_N_cloud_liquid_droplets (
317- (cmc,),
318- dust_aero_conc,
319- seasalt_aero_conc,
320- SO4_aero_conc,
321- lwp_col,
322- ),
323- FT (0 ),
324- FT (0 ),
325- ) * m_to_um_factor,
326- FT (0 ),
327- )
328-
329- @. ᶜreice = ifelse (
330- cloud_ice_water_content > FT (0 ),
331- CM. CloudDiagnostics. effective_radius_const (cmc. ice) *
332- m_to_um_factor,
333- FT (0 ),
334- )
335- end
336- end
337-
338- if ! (radiation_mode isa RRTMGPI. GrayRadiation)
339- if radiation_mode. aerosol_radiation
340- ᶜΔz = Fields. Δz_field (Y. c)
341-
342- more_aerosols = (
343- (:center_dust1_column_mass_density , :DST01 ),
344- (:center_dust2_column_mass_density , :DST02 ),
345- (:center_dust3_column_mass_density , :DST03 ),
346- (:center_dust4_column_mass_density , :DST04 ),
347- (:center_dust5_column_mass_density , :DST05 ),
348- (:center_ss1_column_mass_density , :SSLT01 ),
349- (:center_ss2_column_mass_density , :SSLT02 ),
350- (:center_ss3_column_mass_density , :SSLT03 ),
351- (:center_ss4_column_mass_density , :SSLT04 ),
352- (:center_ss5_column_mass_density , :SSLT05 ),
353- )
354-
355- aerosol_names_pair = [
356- more_aerosols... ,
357- (:center_so4_column_mass_density , :SO4 ),
358- (:center_bcpi_column_mass_density , :CB2 ),
359- (:center_bcpo_column_mass_density , :CB1 ),
360- (:center_ocpi_column_mass_density , :OC2 ),
361- (:center_ocpo_column_mass_density , :OC1 ),
362- ]
363-
364- for (rrtmgp_aerosol_name, prescribed_aerosol_name) in
365- aerosol_names_pair
366- ᶜaero_conc = Fields. array2field (
367- getproperty (rrtmgp_model, rrtmgp_aerosol_name),
368- axes (Y. c),
369- )
370- if prescribed_aerosol_name in
371- propertynames (p. tracers. prescribed_aerosols_field)
372- aerosol_field = getproperty (
373- p. tracers. prescribed_aerosols_field,
374- prescribed_aerosol_name,
375- )
376- @. ᶜaero_conc = aerosol_field * Y. c. ρ * ᶜΔz
377- else
378- @. ᶜaero_conc = 0
379- end
380- end
381-
382- end
383- if :o3 in propertynames (p. tracers)
384- ᶜvmr_o3 = Fields. array2field (
385- rrtmgp_model. center_volume_mixing_ratio_o3,
386- axes (Y. c),
387- )
388- @. ᶜvmr_o3 = p. tracers. o3
389- end
390- if :co2 in propertynames (p. tracers)
391- if pkgversion (ClimaUtilities) < v " 0.1.21"
392- rrtmgp_model. volume_mixing_ratio_co2 .= p. tracers. co2
393- else
394- rrtmgp_model. volume_mixing_ratio_co2 .= p. tracers. co2[]
395- end
396- end
397- end
398-
399139 set_surface_albedo! (Y, p, t, p. atmos. surface_albedo)
400140
401141 RRTMGPI. update_fluxes! (rrtmgp_model, UInt32 (floor (t / integrator. p. dt)))
@@ -483,7 +223,7 @@ function set_insolation_variables!(Y, p, t, tvi::TimeVaryingInsolation)
483223 current_datetime,
484224 date0,
485225 insolation_params,
486- )
226+ ),
487227 )
488228 bottom_coords = Fields. coordinate_field (Spaces. level (Y. c, 1 ))
489229 cos_zenith =
0 commit comments