@@ -267,18 +267,30 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
267267 @assert n_prognostic_mass_flux_subdomains (atmos. turbconv_model) == 1
268268 if use_derivative (sgs_mass_flux_flag)
269269 (
270+ MatrixFields. unrolled_map (
271+ name ->
272+ (name, get_χʲ_name_from_ρχ_name (name)) =>
273+ similar (Y. c, TridiagonalRow),
274+ available_tracer_names,
275+ )... ,
276+ MatrixFields. unrolled_map (
277+ name ->
278+ (name, @name (c. sgsʲs.:(1 ). ρa)) =>
279+ similar (Y. c, TridiagonalRow),
280+ available_tracer_names,
281+ )... ,
282+ MatrixFields. unrolled_map (
283+ name ->
284+ (name, @name (f. sgsʲs.:(1 ). u₃)) =>
285+ similar (Y. c, BidiagonalRow_ACT3),
286+ available_tracer_names,
287+ )... ,
270288 (@name (c. ρe_tot), @name (c. sgsʲs.:(1 ). mse)) =>
271289 similar (Y. c, TridiagonalRow),
272- (@name (c. ρq_tot), @name (c. sgsʲs.:(1 ). q_tot)) =>
273- similar (Y. c, TridiagonalRow),
274290 (@name (c. ρe_tot), @name (f. sgsʲs.:(1 ). u₃)) =>
275291 similar (Y. c, BidiagonalRow_ACT3),
276- (@name (c. ρq_tot), @name (f. sgsʲs.:(1 ). u₃)) =>
277- similar (Y. c, BidiagonalRow_ACT3),
278292 (@name (c. ρe_tot), @name (c. sgsʲs.:(1 ). ρa)) =>
279293 similar (Y. c, TridiagonalRow),
280- (@name (c. ρq_tot), @name (c. sgsʲs.:(1 ). ρa)) =>
281- similar (Y. c, TridiagonalRow),
282294 )
283295 else
284296 ()
@@ -742,6 +754,8 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
742754 if use_derivative (sgs_advection_flag)
743755 (; ᶜgradᵥ_ᶠΦ) = p. core
744756 (; ᶜρʲs, ᶠu³ʲs, ᶜtsʲs, ᶜKʲs, bdmr_l, bdmr_r, bdmr) = p. precomputed
757+
758+ # upwinding options for q_tot and mse
745759 is_third_order =
746760 p. atmos. numerics. edmfx_mse_q_tot_upwinding == Val (:third_order )
747761 ᶠupwind = is_third_order ? ᶠupwind3 : ᶠupwind1
@@ -757,6 +771,24 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
757771 bottom = Operators. SetValue (zero (UpwindMatrixRowType{CT3{FT}})),
758772 ) # Need to wrap ᶠupwind_matrix in this for well-defined boundaries.
759773
774+ # upwinding options for other tracers
775+ is_tracer_upwinding_third_order =
776+ p. atmos. numerics. edmfx_tracer_upwinding == Val (:third_order )
777+ ᶠtracer_upwind = is_tracer_upwinding_third_order ? ᶠupwind3 : ᶠupwind1
778+ ᶠset_tracer_upwind_bcs = Operators. SetBoundaryOperator (;
779+ top = Operators. SetValue (zero (CT3{FT})),
780+ bottom = Operators. SetValue (zero (CT3{FT})),
781+ ) # Need to wrap ᶠtracer_upwind in this for well-defined boundaries.
782+ TracerUpwindMatrixRowType =
783+ is_tracer_upwinding_third_order ? QuaddiagonalMatrixRow :
784+ BidiagonalMatrixRow
785+ ᶠtracer_upwind_matrix =
786+ is_tracer_upwinding_third_order ? ᶠupwind3_matrix : ᶠupwind1_matrix
787+ ᶠset_tracer_upwind_matrix_bcs = Operators. SetBoundaryOperator (;
788+ top = Operators. SetValue (zero (TracerUpwindMatrixRowType{CT3{FT}})),
789+ bottom = Operators. SetValue (zero (TracerUpwindMatrixRowType{CT3{FT}})),
790+ ) # Need to wrap ᶠtracer_upwind_matrix in this for well-defined boundaries.
791+
760792 ᶠu³ʲ_data = ᶠu³ʲs.:(1 ). components. data.:1
761793
762794 ᶜkappa_mʲ = p. scratch. ᶜtemp_scalar
@@ -797,6 +829,7 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
797829 p. atmos. microphysics_model isa Microphysics1Moment ||
798830 p. atmos. microphysics_model isa Microphysics2Moment
799831 )
832+
800833 ᶜa = (@. lazy (draft_area (Y. c. sgsʲs.:(1 ). ρa, ᶜρʲs.:(1 ))))
801834 ᶜ∂a∂z =
802835 @. lazy (
@@ -832,15 +865,17 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
832865 dtγ * (
833866 DiagonalMatrixRow (ᶜadvdivᵥ (ᶠu³ʲs.:(1 ))) -
834867 ᶜadvdivᵥ_matrix () ⋅
835- ᶠset_upwind_matrix_bcs (ᶠupwind_matrix (ᶠu³ʲs.:(1 )))
868+ ᶠset_tracer_upwind_matrix_bcs (
869+ ᶠtracer_upwind_matrix (ᶠu³ʲs.:(1 )),
870+ )
836871 ) - (I,)
837872 ∂ᶜχʲ_err_∂ᶠu₃ʲ =
838873 matrix[χʲ_name, @name (f. sgsʲs.:(1 ). u₃)]
839874 @. ∂ᶜχʲ_err_∂ᶠu₃ʲ =
840875 dtγ * (
841876 - (ᶜadvdivᵥ_matrix ()) ⋅ DiagonalMatrixRow (
842- ᶠset_upwind_bcs (
843- ᶠupwind (CT3 (sign (ᶠu³ʲ_data)), ᶜχʲ),
877+ ᶠset_tracer_upwind_bcs (
878+ ᶠtracer_upwind (CT3 (sign (ᶠu³ʲ_data)), ᶜχʲ),
844879 ) * adjoint (C3 (sign (ᶠu³ʲ_data))),
845880 ) +
846881 DiagonalMatrixRow (ᶜχʲ) ⋅ ᶜadvdivᵥ_matrix ()
@@ -1267,6 +1302,64 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
12671302 (ᶠu³ʲs.:(1 ) - ᶠu³) *
12681303 ᶠinterp ((Y. c. sgsʲs.:(1 ). q_tot - ᶜq_tot)) / ᶠJ,
12691304 ) ⋅ ᶠinterp_matrix () ⋅ DiagonalMatrixRow (ᶜJ)
1305+
1306+ # grid-mean tracers
1307+ if p. atmos. moisture_model isa NonEquilMoistModel && (
1308+ p. atmos. microphysics_model isa Microphysics1Moment ||
1309+ p. atmos. microphysics_model isa Microphysics2Moment
1310+ )
1311+
1312+ microphysics_tracers = (
1313+ (@name (c. ρq_liq), @name (c. sgsʲs.:(1 ). q_liq)),
1314+ (@name (c. ρq_ice), @name (c. sgsʲs.:(1 ). q_ice)),
1315+ (@name (c. ρq_rai), @name (c. sgsʲs.:(1 ). q_rai)),
1316+ (@name (c. ρq_sno), @name (c. sgsʲs.:(1 ). q_sno)),
1317+ (@name (c. ρn_liq), @name (c. sgsʲs.:(1 ). n_liq)),
1318+ (@name (c. ρn_rai), @name (c. sgsʲs.:(1 ). n_rai)),
1319+ )
1320+ MatrixFields. unrolled_foreach (
1321+ microphysics_tracers,
1322+ ) do (ρχ_name, χʲ_name)
1323+ MatrixFields. has_field (Y, ρχ_name) || return
1324+ ᶜχʲ = MatrixFields. get_field (Y, χʲ_name)
1325+
1326+ ∂ᶜρχ_err_∂ᶜχʲ =
1327+ matrix[ρχ_name, χʲ_name]
1328+ @. ∂ᶜρχ_err_∂ᶜχʲ =
1329+ dtγ *
1330+ - (ᶜadvdivᵥ_matrix ()) ⋅
1331+ DiagonalMatrixRow (ᶠinterp (ᶜρʲs.:(1 ) * ᶜJ) / ᶠJ) ⋅
1332+ ᶠset_tracer_upwind_matrix_bcs (
1333+ ᶠtracer_upwind_matrix (ᶠu³ʲs.:(1 )),
1334+ ) ⋅
1335+ DiagonalMatrixRow (draft_area (Y. c. sgsʲs.:(1 ). ρa, ᶜρʲs.:(1 )))
1336+
1337+ ∂ᶜρχ_err_∂ᶜρa =
1338+ matrix[ρχ_name, @name (c. sgsʲs.:(1 ). ρa)]
1339+ @. ∂ᶜρχ_err_∂ᶜρa =
1340+ dtγ *
1341+ - (ᶜadvdivᵥ_matrix ()) ⋅
1342+ DiagonalMatrixRow (ᶠinterp (ᶜρʲs.:(1 ) * ᶜJ) / ᶠJ) ⋅
1343+ ᶠset_tracer_upwind_matrix_bcs (
1344+ ᶠtracer_upwind_matrix (ᶠu³ʲs.:(1 )),
1345+ ) ⋅
1346+ DiagonalMatrixRow (ᶜχʲ / ᶜρʲs.:(1 ))
1347+
1348+ ∂ᶜρχ_err_∂ᶠu₃ʲ =
1349+ matrix[ρχ_name, @name (f. sgsʲs.:(1 ). u₃)]
1350+ @. ∂ᶜρχ_err_∂ᶠu₃ʲ =
1351+ dtγ * (
1352+ - (ᶜadvdivᵥ_matrix ()) ⋅ DiagonalMatrixRow (
1353+ ᶠinterp (ᶜρʲs.:(1 ) * ᶜJ) / ᶠJ *
1354+ ᶠset_tracer_upwind_bcs (
1355+ ᶠtracer_upwind (CT3 (sign (ᶠu³ʲ_data)),
1356+ draft_area (Y. c. sgsʲs.:(1 ). ρa, ᶜρʲs.:(1 )) * ᶜχʲ,
1357+ ),
1358+ ) * adjoint (C3 (sign (ᶠu³ʲ_data))),
1359+ )) ⋅ DiagonalMatrixRow (g³³ (ᶠgⁱʲ))
1360+
1361+ end
1362+ end
12701363 end
12711364 elseif rs isa RayleighSponge
12721365 ∂ᶠu₃ʲ_err_∂ᶠu₃ʲ =
0 commit comments