@@ -115,150 +115,6 @@ NVTX.@annotate function set_prognostic_edmf_precomputed_quantities_draft!(
115115 return nothing
116116end
117117
118- """
119- set_prognostic_edmf_precomputed_quantities_bottom_bc!(Y, p, ᶠuₕ³, t)
120-
121- Updates velocity and thermodynamics quantities at the surface in each SGS draft.
122- """
123- NVTX. @annotate function set_prognostic_edmf_precomputed_quantities_bottom_bc! (
124- Y,
125- p,
126- t,
127- )
128- (; moisture_model, turbconv_model, microphysics_model) = p. atmos
129-
130- FT = Spaces. undertype (axes (Y. c))
131- n = n_mass_flux_subdomains (turbconv_model)
132- thermo_params = CAP. thermodynamics_params (p. params)
133- turbconv_params = CAP. turbconv_params (p. params)
134-
135- (; ᶜΦ,) = p. core
136- (; ᶜp, ᶜK, ᶜtsʲs, ᶜρʲs, ᶜts) = p. precomputed
137- (; ustar, obukhov_length, buoyancy_flux) = p. precomputed. sfc_conditions
138-
139- for j in 1 : n
140- ᶜtsʲ = ᶜtsʲs.:($ j)
141- ᶜmseʲ = Y. c. sgsʲs.:($ j). mse
142- ᶜq_totʲ = Y. c. sgsʲs.:($ j). q_tot
143- if moisture_model isa NonEquilMoistModel && (
144- microphysics_model isa Microphysics1Moment ||
145- microphysics_model isa Microphysics2Moment
146- )
147- ᶜq_liqʲ = Y. c. sgsʲs.:($ j). q_liq
148- ᶜq_iceʲ = Y. c. sgsʲs.:($ j). q_ice
149- ᶜq_raiʲ = Y. c. sgsʲs.:($ j). q_rai
150- ᶜq_snoʲ = Y. c. sgsʲs.:($ j). q_sno
151- end
152-
153- # We need field_values everywhere because we are mixing
154- # information from surface and first interior inside the
155- # sgs_scalar_first_interior_bc call.
156- ᶜz_int_val =
157- Fields. field_values (Fields. level (Fields. coordinate_field (Y. c). z, 1 ))
158- z_sfc_val = Fields. field_values (
159- Fields. level (Fields. coordinate_field (Y. f). z, Fields. half),
160- )
161- ᶜρ_int_val = Fields. field_values (Fields. level (Y. c. ρ, 1 ))
162- ᶜp_int_val = Fields. field_values (Fields. level (ᶜp, 1 ))
163- (; ρ_flux_h_tot, ρ_flux_q_tot, ustar, obukhov_length) =
164- p. precomputed. sfc_conditions
165-
166- buoyancy_flux_val = Fields. field_values (buoyancy_flux)
167- ρ_flux_h_tot_val = Fields. field_values (ρ_flux_h_tot)
168- ρ_flux_q_tot_val = Fields. field_values (ρ_flux_q_tot)
169-
170- ustar_val = Fields. field_values (ustar)
171- obukhov_length_val = Fields. field_values (obukhov_length)
172- sfc_local_geometry_val = Fields. field_values (
173- Fields. local_geometry_field (Fields. level (Y. f, Fields. half)),
174- )
175-
176- # Based on boundary conditions for updrafts we overwrite
177- # the first interior point for EDMFX ᶜmseʲ...
178- ᶜaʲ_int_val = p. scratch. temp_data_level
179- # TODO : replace this with the actual surface area fraction when
180- # using prognostic surface area
181- @. ᶜaʲ_int_val = FT (turbconv_params. surface_area)
182- ᶜh_tot = @. lazy (
183- TD. total_specific_enthalpy (
184- thermo_params,
185- ᶜts,
186- specific (Y. c. ρe_tot, Y. c. ρ),
187- ),
188- )
189- ᶜh_tot_int_val = Fields. field_values (Fields. level (ᶜh_tot, 1 ))
190- ᶜK_int_val = Fields. field_values (Fields. level (ᶜK, 1 ))
191- ᶜmseʲ_int_val = Fields. field_values (Fields. level (ᶜmseʲ, 1 ))
192- @. ᶜmseʲ_int_val = sgs_scalar_first_interior_bc (
193- ᶜz_int_val - z_sfc_val,
194- ᶜρ_int_val,
195- ᶜaʲ_int_val,
196- ᶜh_tot_int_val - ᶜK_int_val,
197- buoyancy_flux_val,
198- ρ_flux_h_tot_val,
199- ustar_val,
200- obukhov_length_val,
201- sfc_local_geometry_val,
202- )
203-
204- # ... and the first interior point for EDMFX ᶜq_totʲ.
205-
206- ᶜq_tot = @. lazy (specific (Y. c. ρq_tot, Y. c. ρ))
207- ᶜq_tot_int_val = Fields. field_values (Fields. level (ᶜq_tot, 1 ))
208- ᶜq_totʲ_int_val = Fields. field_values (Fields. level (ᶜq_totʲ, 1 ))
209- @. ᶜq_totʲ_int_val = sgs_scalar_first_interior_bc (
210- ᶜz_int_val - z_sfc_val,
211- ᶜρ_int_val,
212- ᶜaʲ_int_val,
213- ᶜq_tot_int_val,
214- buoyancy_flux_val,
215- ρ_flux_q_tot_val,
216- ustar_val,
217- obukhov_length_val,
218- sfc_local_geometry_val,
219- )
220-
221- # Then overwrite the prognostic variables at first inetrior point.
222- ᶜΦ_int_val = Fields. field_values (Fields. level (ᶜΦ, 1 ))
223- ᶜtsʲ_int_val = Fields. field_values (Fields. level (ᶜtsʲ, 1 ))
224- if moisture_model isa NonEquilMoistModel && (
225- microphysics_model isa Microphysics1Moment ||
226- microphysics_model isa Microphysics2Moment
227- )
228- ᶜq_liqʲ_int_val = Fields. field_values (Fields. level (ᶜq_liqʲ, 1 ))
229- ᶜq_iceʲ_int_val = Fields. field_values (Fields. level (ᶜq_iceʲ, 1 ))
230- ᶜq_raiʲ_int_val = Fields. field_values (Fields. level (ᶜq_raiʲ, 1 ))
231- ᶜq_snoʲ_int_val = Fields. field_values (Fields. level (ᶜq_snoʲ, 1 ))
232- @. ᶜtsʲ_int_val = TD. PhaseNonEquil_phq (
233- thermo_params,
234- ᶜp_int_val,
235- ᶜmseʲ_int_val - ᶜΦ_int_val,
236- TD. PhasePartition (
237- ᶜq_totʲ_int_val,
238- ᶜq_liqʲ_int_val + ᶜq_raiʲ_int_val,
239- ᶜq_iceʲ_int_val + ᶜq_snoʲ_int_val,
240- ),
241- )
242- else
243- @. ᶜtsʲ_int_val = TD. PhaseEquil_phq (
244- thermo_params,
245- ᶜp_int_val,
246- ᶜmseʲ_int_val - ᶜΦ_int_val,
247- ᶜq_totʲ_int_val,
248- )
249- end
250- sgsʲs_ρ_int_val = Fields. field_values (Fields. level (ᶜρʲs.:($ j), 1 ))
251- sgsʲs_ρa_int_val =
252- Fields. field_values (Fields. level (Y. c. sgsʲs.:($ j). ρa, 1 ))
253-
254- @. sgsʲs_ρ_int_val = TD. air_density (thermo_params, ᶜtsʲ_int_val)
255- @. sgsʲs_ρa_int_val =
256- $ (FT (turbconv_params. surface_area)) *
257- TD. air_density (thermo_params, ᶜtsʲ_int_val)
258- end
259- return nothing
260- end
261-
262118"""
263119 set_prognostic_edmf_precomputed_quantities_implicit_closures!(Y, p, t)
264120
@@ -332,6 +188,7 @@ NVTX.@annotate function set_prognostic_edmf_precomputed_quantities_explicit_clos
332188 ᶠnh_pressure₃_buoyʲs,
333189 ) = p. precomputed
334190 (; ustar, obukhov_length) = p. precomputed. sfc_conditions
191+ ᶜaʲ_int_val = p. scratch. temp_data_level
335192
336193 ᶜz = Fields. coordinate_field (Y. c). z
337194 z_sfc = Fields. level (Fields. coordinate_field (Y. f). z, Fields. half)
@@ -411,6 +268,27 @@ NVTX.@annotate function set_prognostic_edmf_precomputed_quantities_explicit_clos
411268 dt,
412269 )
413270
271+ # If the surface buoyancy flux is positive, increase entrainment in the first cell
272+ # so that the updraft area grows to at least `surface_area` within one timestep.
273+ # Otherwise (stable surface), leave entrainment unchanged.
274+ buoyancy_flux_val = Fields. field_values (p. precomputed. sfc_conditions. buoyancy_flux)
275+ sgsʲs_ρ_int_val = Fields. field_values (Fields. level (ᶜρʲs.:($ j), 1 ))
276+ sgsʲs_ρa_int_val =
277+ Fields. field_values (Fields. level (Y. c. sgsʲs.:($ j). ρa, 1 ))
278+ @. ᶜaʲ_int_val = draft_area (sgsʲs_ρa_int_val, sgsʲs_ρ_int_val)
279+ entr_int_val = Fields. field_values (Fields. level (ᶜentrʲs.:($ j), 1 ))
280+ detr_int_val = Fields. field_values (Fields. level (ᶜdetrʲs.:($ j), 1 ))
281+ @. entr_int_val = limit_entrainment (
282+ ifelse (
283+ buoyancy_flux_val < 0 || ᶜaʲ_int_val >= $ (FT (turbconv_params. surface_area)),
284+ entr_int_val,
285+ detr_int_val +
286+ ($ (FT (turbconv_params. surface_area)) / ᶜaʲ_int_val - 1 ) / FT (dt),
287+ ),
288+ ᶜaʲ_int_val,
289+ dt,
290+ )
291+
414292 # The buoyancy term in the nonhydrostatic pressure closure is always applied
415293 # for prognostic edmf. The tendency is combined with the buoyancy term in the
416294 # updraft momentum equation in `edmfx_sgs_vertical_advection_tendency!`. This
0 commit comments