|
| 1 | +import ClimaCore.MatrixFields: @name |
| 2 | + |
1 | 3 | """
|
2 | 4 | specific(ρχ, ρ)
|
3 | 5 | specific(ρaχ, ρa, ρχ, ρ, turbconv_model)
|
@@ -51,6 +53,64 @@ Arguments:
|
51 | 53 | return ρa == 0 ? ρχ / ρ : weight * ρaχ / ρa + (1 - weight) * ρχ / ρ
|
52 | 54 | end
|
53 | 55 |
|
| 56 | +""" |
| 57 | + scalar_names(field) |
| 58 | +
|
| 59 | +Filters and returns the names of the variables from a given state |
| 60 | +vector component, excluding `ρ`, `ρe_tot`, and `uₕ` |
| 61 | +
|
| 62 | +Arguments: |
| 63 | +
|
| 64 | +- `field`: A component of the state vector `Y.c`. |
| 65 | +
|
| 66 | +Returns: |
| 67 | +
|
| 68 | +- A `Tuple` of `ClimaCore.MatrixFields.FieldName`s corresponding to the tracers. |
| 69 | +""" |
| 70 | +scalar_names(field) = |
| 71 | + unrolled_filter(MatrixFields.top_level_names(field)) do name |
| 72 | + !(name in (@name(ρ), @name(ρe_tot), @name(uₕ))) |
| 73 | + end |
| 74 | + |
| 75 | +""" |
| 76 | + foreach_scalar(f::F, Yₜ, Y) where {F} |
| 77 | +
|
| 78 | +Applies a given function `f` to each scalar variable (except `ρ` and `ρe_tot`) |
| 79 | +in the state `Y` and its corresponding tendency `Yₜ`. |
| 80 | +This utility abstracts the process of iterating over all scalars. It uses |
| 81 | +`scalar_names` to identify the relevant variables and `unrolled_foreach` to |
| 82 | +ensure a performant loop. For each tracer, it calls the provided function `f` |
| 83 | +with the tendency field, the state field, and a boolean flag indicating if |
| 84 | +the current tracer is `ρq_tot` (to allow for special handling). |
| 85 | +
|
| 86 | +Arguments: |
| 87 | +
|
| 88 | +- `f`: A function to apply to each scalar. It must have the signature |
| 89 | + `f(ᶜρχₜ, ᶜρχ, is_ρq_tot)`, where `ᶜρχₜ` is the tendency field, `ᶜρχ` is |
| 90 | + the state field, and `is_ρq_tot` is a `Bool`. |
| 91 | +- `Yₜ`: The tendency state vector. |
| 92 | +- `Y`: The current state vector. |
| 93 | +
|
| 94 | +# Example |
| 95 | +
|
| 96 | +```julia |
| 97 | +foreach_scalar(Yₜ, Y) do ᶜρχₜ, ᶜρχ, is_ρq_tot |
| 98 | + # Apply some operation, e.g., a sponge layer |
| 99 | + @. ᶜρχₜ += some_sponge_function(ᶜρχ) |
| 100 | + if is_ρq_tot |
| 101 | + # Perform an additional operation only for ρq_tot |
| 102 | + end |
| 103 | +end |
| 104 | +``` |
| 105 | +""" |
| 106 | +foreach_scalar(f::F, Yₜ, Y) where {F} = |
| 107 | + unrolled_foreach(scalar_names(Y.c)) do scalar_name |
| 108 | + ᶜρχₜ = MatrixFields.get_field(Yₜ.c, scalar_name) |
| 109 | + ᶜρχ = MatrixFields.get_field(Y.c, scalar_name) |
| 110 | + is_ρq_tot = scalar_name == @name(ρq_tot) |
| 111 | + f(ᶜρχₜ, ᶜρχ, is_ρq_tot) |
| 112 | + end |
| 113 | + |
54 | 114 | """
|
55 | 115 | sgs_weight_function(a, a_half)
|
56 | 116 |
|
|
0 commit comments