@@ -5,33 +5,85 @@ import Thermodynamics as TD
5
5
import ClimaCore: Spaces, Fields
6
6
7
7
"""
8
- precomputed_quantities(Y, atmos)
8
+ implicit_precomputed_quantities(Y, atmos)
9
+
10
+ Allocates precomputed quantities that are treated implicitly (i.e., updated
11
+ on each iteration of the implicit solver). This includes all quantities related
12
+ to velocity and thermodynamics that are used in the implicit tendency.
9
13
10
- Allocates and returns the precomputed quantities :
11
- - `ᶜspecific`: the specific quantities on cell centers (for every prognostic
14
+ The following grid-scale quantities are treated implicitly :
15
+ - `ᶜspecific`: specific quantities on cell centers (for every prognostic
12
16
quantity `ρχ`, there is a corresponding specific quantity `χ`)
13
- - `ᶜu`: the covariant velocity on cell centers
14
- - `ᶠu³`: the third component of contravariant velocity on cell faces
15
- - `ᶜK`: the kinetic energy on cell centers
16
- - `ᶜts`: the thermodynamic state on cell centers
17
- - `ᶜp`: the air pressure on cell centers
18
- - `sfc_conditions`: the conditions at the surface (at the bottom cell faces)
19
- - `ᶜh_tot`: the total enthalpy on cell centers
20
-
21
- If the `turbconv_model` is EDMFX, there also two SGS versions of every quantity
22
- except for `ᶜp` (we assume that the pressure is the same across all subdomains):
23
- - `_⁰`: the value for the environment
24
- - `_ʲs`: a tuple of the values for the mass-flux subdomains
25
- In addition, there are several other SGS quantities for the EDMFX model:
26
- - `ᶜρa⁰`: the area-weighted air density of the environment on cell centers
27
- - `ᶠu₃⁰`: the vertical component of the covariant velocity of the environment
28
- on cell faces
29
- - `ᶜρ⁰`: the air density of the environment on cell centers
17
+ - `ᶜu`: covariant velocity on cell centers
18
+ - `ᶠu`: contravariant velocity on cell faces
19
+ - `ᶜK`: kinetic energy on cell centers
20
+ - `ᶜts`: thermodynamic state on cell centers
21
+ - `ᶜp`: air pressure on cell centers
22
+ - `ᶜh_tot`: total enthalpy on cell centers
23
+ If the `turbconv_model` is `PrognosticEDMFX`, there also two SGS versions of
24
+ every quantity except for `ᶜp` (which is shared across all subdomains):
25
+ - `_⁰`: value for the environment
26
+ - `_ʲs`: a tuple of values for the mass-flux subdomains
27
+ In addition, there are several other SGS quantities for `PrognosticEDMFX`:
28
+ - `ᶜtke⁰`: turbulent kinetic energy of the environment on cell centers
29
+ - `ᶜρa⁰`: area-weighted air density of the environment on cell centers
30
+ - `ᶜmse⁰`: moist static energy of the environment on cell centers
31
+ - `ᶜq_tot⁰`: total specific humidity of the environment on cell centers
32
+ - `ᶜρ⁰`: air density of the environment on cell centers
30
33
- `ᶜρʲs`: a tuple of the air densities of the mass-flux subdomains on cell
31
34
centers
35
+ For every other `AbstractEDMF`, only `ᶜtke⁰` is added as a precomputed quantity.
32
36
33
37
TODO: Rename `ᶜK` to `ᶜκ`.
34
38
"""
39
+ function implicit_precomputed_quantities (Y, atmos)
40
+ (; moisture_model, turbconv_model) = atmos
41
+ FT = eltype (Y)
42
+ TST = thermo_state_type (moisture_model, FT)
43
+ n = n_mass_flux_subdomains (turbconv_model)
44
+ gs_quantities = (;
45
+ ᶜspecific = specific_gs .(Y. c),
46
+ ᶜu = similar (Y. c, C123{FT}),
47
+ ᶠu³ = similar (Y. f, CT3{FT}),
48
+ ᶠu = similar (Y. f, CT123{FT}),
49
+ ᶜK = similar (Y. c, FT),
50
+ ᶜts = similar (Y. c, TST),
51
+ ᶜp = similar (Y. c, FT),
52
+ ᶜh_tot = similar (Y. c, FT),
53
+ )
54
+ sgs_quantities =
55
+ turbconv_model isa AbstractEDMF ? (; ᶜtke⁰ = similar (Y. c, FT)) : (;)
56
+ prognostic_sgs_quantities =
57
+ turbconv_model isa PrognosticEDMFX ?
58
+ (;
59
+ ᶜρa⁰ = similar (Y. c, FT),
60
+ ᶜmse⁰ = similar (Y. c, FT),
61
+ ᶜq_tot⁰ = similar (Y. c, FT),
62
+ ᶠu₃⁰ = similar (Y. f, C3{FT}),
63
+ ᶜu⁰ = similar (Y. c, C123{FT}),
64
+ ᶠu³⁰ = similar (Y. f, CT3{FT}),
65
+ ᶜK⁰ = similar (Y. c, FT),
66
+ ᶜts⁰ = similar (Y. c, TST),
67
+ ᶜρ⁰ = similar (Y. c, FT),
68
+ ᶜuʲs = similar (Y. c, NTuple{n, C123{FT}}),
69
+ ᶠu³ʲs = similar (Y. f, NTuple{n, CT3{FT}}),
70
+ ᶜKʲs = similar (Y. c, NTuple{n, FT}),
71
+ ᶠKᵥʲs = similar (Y. f, NTuple{n, FT}),
72
+ ᶜtsʲs = similar (Y. c, NTuple{n, TST}),
73
+ ᶜρʲs = similar (Y. c, NTuple{n, FT}),
74
+ ) : (;)
75
+ return (; gs_quantities... , sgs_quantities... , prognostic_sgs_quantities... )
76
+ end
77
+
78
+ """
79
+ precomputed_quantities(Y, atmos)
80
+
81
+ Allocates all precomputed quantities. This includes the quantities treated
82
+ implicitly (updated before each tendency evaluation), and also the quantities
83
+ treated explicitly (updated only before explicit tendency evaluations).
84
+
85
+ TODO: Reduce the number of cached values by computing them on the fly.
86
+ """
35
87
function precomputed_quantities (Y, atmos)
36
88
FT = eltype (Y)
37
89
@assert ! (atmos. moisture_model isa DryModel) ||
@@ -45,20 +97,12 @@ function precomputed_quantities(Y, atmos)
45
97
fspace = axes (Y. f)
46
98
n = n_mass_flux_subdomains (atmos. turbconv_model)
47
99
gs_quantities = (;
48
- ᶜspecific = specific_gs .(Y. c),
49
- ᶜu = similar (Y. c, C123{FT}),
50
- ᶠu³ = similar (Y. f, CT3{FT}),
51
- ᶠu = similar (Y. f, CT123{FT}),
52
100
ᶜwₜqₜ = similar (Y. c, Geometry. WVector{FT}),
53
101
ᶜwₕhₜ = similar (Y. c, Geometry. WVector{FT}),
54
- ᶜK = similar (Y. c, FT),
55
- ᶜts = similar (Y. c, TST),
56
- ᶜp = similar (Y. c, FT),
57
- ᶜh_tot = similar (Y. c, FT),
58
102
ᶜmixing_length = similar (Y. c, FT),
59
103
ᶜlinear_buoygrad = similar (Y. c, FT),
60
104
ᶜstrain_rate_norm = similar (Y. c, FT),
61
- sfc_conditions = Fields . Field (SCT, Spaces. level (axes ( Y. f) , half)),
105
+ sfc_conditions = similar ( Spaces. level (Y. f, half), SCT ),
62
106
)
63
107
cloud_diagnostics_tuple =
64
108
similar (Y. c, @NamedTuple {cf:: FT , q_liq:: FT , q_ice:: FT })
@@ -82,29 +126,13 @@ function precomputed_quantities(Y, atmos)
82
126
advective_sgs_quantities =
83
127
atmos. turbconv_model isa PrognosticEDMFX ?
84
128
(;
85
- ᶜtke⁰ = similar (Y. c, FT),
86
- ᶜρa⁰ = similar (Y. c, FT),
87
- ᶠu₃⁰ = similar (Y. f, C3{FT}),
88
- ᶜu⁰ = similar (Y. c, C123{FT}),
89
- ᶠu³⁰ = similar (Y. f, CT3{FT}),
90
- ᶜK⁰ = similar (Y. c, FT),
91
- ᶜmse⁰ = similar (Y. c, FT),
92
- ᶜq_tot⁰ = similar (Y. c, FT),
93
- ᶜts⁰ = similar (Y. c, TST),
94
- ᶜρ⁰ = similar (Y. c, FT),
95
129
ᶜmixing_length_tuple = similar (Y. c, MixingLength{FT}),
96
130
ᶜK_u = similar (Y. c, FT),
97
131
ᶜK_h = similar (Y. c, FT),
98
132
ρatke_flux = similar (Fields. level (Y. f, half), C3{FT}),
99
- ᶜuʲs = similar (Y. c, NTuple{n, C123{FT}}),
100
- ᶠu³ʲs = similar (Y. f, NTuple{n, CT3{FT}}),
101
- ᶜKʲs = similar (Y. c, NTuple{n, FT}),
102
- ᶠKᵥʲs = similar (Y. f, NTuple{n, FT}),
103
- ᶜtsʲs = similar (Y. c, NTuple{n, TST}),
104
133
bdmr_l = similar (Y. c, BidiagonalMatrixRow{FT}),
105
134
bdmr_r = similar (Y. c, BidiagonalMatrixRow{FT}),
106
135
bdmr = similar (Y. c, BidiagonalMatrixRow{FT}),
107
- ᶜρʲs = similar (Y. c, NTuple{n, FT}),
108
136
ᶜentrʲs = similar (Y. c, NTuple{n, FT}),
109
137
ᶜdetrʲs = similar (Y. c, NTuple{n, FT}),
110
138
ᶜturb_entrʲs = similar (Y. c, NTuple{n, FT}),
@@ -149,7 +177,6 @@ function precomputed_quantities(Y, atmos)
149
177
ᶠu³⁰ = similar (Y. f, CT3{FT}),
150
178
ᶜu⁰ = similar (Y. c, C123{FT}),
151
179
ᶜK⁰ = similar (Y. c, FT),
152
- ᶜtke⁰ = similar (Y. c, FT),
153
180
ᶜmixing_length_tuple = similar (Y. c, MixingLength{FT}),
154
181
ᶜK_u = similar (Y. c, FT),
155
182
ᶜK_h = similar (Y. c, FT),
@@ -181,6 +208,7 @@ function precomputed_quantities(Y, atmos)
181
208
end
182
209
183
210
return (;
211
+ implicit_precomputed_quantities (Y, atmos)... ,
184
212
gs_quantities... ,
185
213
sgs_quantities... ,
186
214
advective_sgs_quantities... ,
@@ -369,37 +397,31 @@ function eddy_diffusivity_coefficient(C_E, norm_v_a, z_a, p)
369
397
end
370
398
371
399
"""
372
- set_precomputed_quantities !(Y, p, t)
400
+ set_implicit_precomputed_quantities !(Y, p, t)
373
401
374
- Updates the precomputed quantities stored in `p` based on the current state `Y`.
402
+ Updates the precomputed quantities that are handled implicitly based on the
403
+ current state `Y`. This is called before each evaluation of either
404
+ `implicit_tendency!` or `remaining_tendency!`, and it includes quantities used
405
+ in both tedencies.
375
406
376
407
This function also applies a "filter" to `Y` in order to ensure that `ᶠu³` is 0
377
408
at the surface (i.e., to enforce the impenetrable boundary condition). If the
378
409
`turbconv_model` is EDMFX, the filter also ensures that `ᶠu³⁰` and `ᶠu³ʲs` are 0
379
410
at the surface. In the future, we will probably want to move this filtering
380
411
elsewhere, but doing it here ensures that it occurs whenever the precomputed
381
412
quantities are updated.
382
-
383
- Note: If you need to use any of the precomputed quantities, please call this
384
- function instead of recomputing the value yourself. Otherwise, it will be
385
- difficult to ensure that the duplicated computations are consistent.
386
413
"""
387
- NVTX. @annotate function set_precomputed_quantities! (Y, p, t)
388
- (; moisture_model, turbconv_model, vert_diff, precip_model, cloud_model) =
389
- p. atmos
390
- (; call_cloud_diagnostics_per_stage) = p. atmos
391
- thermo_params = CAP. thermodynamics_params (p. params)
392
- n = n_mass_flux_subdomains (turbconv_model)
393
- thermo_args = (thermo_params, moisture_model, precip_model)
414
+ NVTX. @annotate function set_implicit_precomputed_quantities! (Y, p, t)
415
+ (; turbconv_model, moisture_model, precip_model) = p. atmos
394
416
(; ᶜΦ) = p. core
395
- (; ᶜspecific, ᶜu, ᶠu³, ᶠu, ᶜK, ᶜts, ᶜp) = p. precomputed
417
+ (; ᶜspecific, ᶜu, ᶠu³, ᶠu, ᶜK, ᶜts, ᶜp, ᶜh_tot ) = p. precomputed
396
418
ᶠuₕ³ = p. scratch. ᶠtemp_CT3
419
+ n = n_mass_flux_subdomains (turbconv_model)
420
+ thermo_params = CAP. thermodynamics_params (p. params)
421
+ thermo_args = (thermo_params, moisture_model, precip_model)
397
422
398
423
@. ᶜspecific = specific_gs (Y. c)
399
- ᶜρ = Y. c. ρ
400
- ᶜuₕ = Y. c. uₕ
401
- bc_ᶠuₕ³ = compute_ᶠuₕ³ (ᶜuₕ, ᶜρ)
402
- @. ᶠuₕ³ = bc_ᶠuₕ³
424
+ @. ᶠuₕ³ = $ compute_ᶠuₕ³ (Y. c. uₕ, Y. c. ρ)
403
425
404
426
# TODO : We might want to move this to dss! (and rename dss! to something
405
427
# like enforce_constraints!).
@@ -426,6 +448,36 @@ NVTX.@annotate function set_precomputed_quantities!(Y, p, t)
426
448
end
427
449
@. ᶜts = ts_gs (thermo_args... , ᶜspecific, ᶜK, ᶜΦ, Y. c. ρ)
428
450
@. ᶜp = TD. air_pressure (thermo_params, ᶜts)
451
+ @. ᶜh_tot = TD. total_specific_enthalpy (thermo_params, ᶜts, ᶜspecific. e_tot)
452
+
453
+ if turbconv_model isa PrognosticEDMFX
454
+ set_prognostic_edmf_precomputed_quantities_draft! (Y, p, ᶠuₕ³, t)
455
+ set_prognostic_edmf_precomputed_quantities_environment! (Y, p, ᶠuₕ³, t)
456
+ elseif turbconv_model isa AbstractEDMF
457
+ (; ᶜtke⁰) = p. precomputed
458
+ @. ᶜtke⁰ = Y. c. sgs⁰. ρatke / Y. c. ρ
459
+ end
460
+ end
461
+
462
+ """
463
+ set_explicit_precomputed_quantities!(Y, p, t)
464
+
465
+ Updates the precomputed quantities that are handled explicitly based on the
466
+ current state `Y`. This is only called before each evaluation of
467
+ `remaining_tendency!`, though it includes quantities used in both
468
+ `implicit_tendency!` and `remaining_tendency!`.
469
+ """
470
+ NVTX. @annotate function set_explicit_precomputed_quantities! (Y, p, t)
471
+ (; turbconv_model, moisture_model, precip_model, cloud_model) = p. atmos
472
+ (; vert_diff, call_cloud_diagnostics_per_stage) = p. atmos
473
+ (; ᶜΦ) = p. core
474
+ (; ᶜu, ᶜts, ᶜp) = p. precomputed
475
+ ᶠuₕ³ = p. scratch. ᶠtemp_CT3 # updated in set_implicit_precomputed_quantities!
476
+ thermo_params = CAP. thermodynamics_params (p. params)
477
+
478
+ if ! isnothing (p. sfc_setup)
479
+ SurfaceConditions. update_surface_conditions! (Y, p, float (t))
480
+ end
429
481
430
482
if turbconv_model isa AbstractEDMF
431
483
@. p. precomputed. ᶜgradᵥ_θ_virt =
@@ -436,13 +488,6 @@ NVTX.@annotate function set_precomputed_quantities!(Y, p, t)
436
488
ᶜgradᵥ (ᶠinterp (TD. liquid_ice_pottemp (thermo_params, ᶜts)))
437
489
end
438
490
439
- (; ᶜh_tot) = p. precomputed
440
- @. ᶜh_tot = TD. total_specific_enthalpy (thermo_params, ᶜts, ᶜspecific. e_tot)
441
-
442
- if ! isnothing (p. sfc_setup)
443
- SurfaceConditions. update_surface_conditions! (Y, p, float (t))
444
- end
445
-
446
491
# TODO : It is too slow to calculate mixing length at every timestep
447
492
# if isnothing(turbconv_model)
448
493
# (; ᶜmixing_length) = p.precomputed
@@ -511,8 +556,7 @@ NVTX.@annotate function set_precomputed_quantities!(Y, p, t)
511
556
end
512
557
513
558
if turbconv_model isa PrognosticEDMFX
514
- set_prognostic_edmf_precomputed_quantities_draft_and_bc! (Y, p, ᶠuₕ³, t)
515
- set_prognostic_edmf_precomputed_quantities_environment! (Y, p, ᶠuₕ³, t)
559
+ set_prognostic_edmf_precomputed_quantities_bottom_bc! (Y, p, t)
516
560
set_prognostic_edmf_precomputed_quantities_closures! (Y, p, t)
517
561
set_prognostic_edmf_precomputed_quantities_precipitation! (
518
562
Y,
@@ -540,12 +584,10 @@ NVTX.@annotate function set_precomputed_quantities!(Y, p, t)
540
584
541
585
if vert_diff isa DecayWithHeightDiffusion
542
586
(; ᶜK_h) = p. precomputed
543
- bc_K_h = compute_eddy_diffusivity_coefficient (ᶜρ, vert_diff)
544
- @. ᶜK_h = bc_K_h
587
+ @. ᶜK_h = $ compute_eddy_diffusivity_coefficient (Y. c. ρ, vert_diff)
545
588
elseif vert_diff isa VerticalDiffusion
546
589
(; ᶜK_h) = p. precomputed
547
- bc_K_h = compute_eddy_diffusivity_coefficient (Y. c. uₕ, ᶜp, vert_diff)
548
- @. ᶜK_h = bc_K_h
590
+ @. ᶜK_h = $ compute_eddy_diffusivity_coefficient (Y. c. uₕ, ᶜp, vert_diff)
549
591
end
550
592
551
593
# TODO
@@ -559,3 +601,13 @@ NVTX.@annotate function set_precomputed_quantities!(Y, p, t)
559
601
560
602
return nothing
561
603
end
604
+
605
+ """
606
+ set_precomputed_quantities!(Y, p, t)
607
+
608
+ Updates all precomputed quantities based on the current state `Y`.
609
+ """
610
+ function set_precomputed_quantities! (Y, p, t)
611
+ set_implicit_precomputed_quantities! (Y, p, t)
612
+ set_explicit_precomputed_quantities! (Y, p, t)
613
+ end
0 commit comments