Skip to content

Commit ee1c274

Browse files
authored
Merge pull request #4094 from CliMA/sa/fix_sedimentatio_detr
fix sedimentation detr
2 parents 4a28a99 + 620a27c commit ee1c274

File tree

4 files changed

+84
-87
lines changed

4 files changed

+84
-87
lines changed

src/prognostic_equations/advection.jl

Lines changed: 73 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,6 @@ function edmfx_sgs_vertical_advection_tendency!(
396396

397397
for j in 1:n
398398
ᶜa = (@. lazy(draft_area(Y.c.sgsʲs.:($$j).ρa, ᶜρʲs.:($$j))))
399-
ᶜright_biased_∂a∂z =
400-
@. lazy(ᶜprecipdivᵥ(ᶠinterp(ᶜJ) / ᶠJ * ᶠright_bias(Geometry.WVector(ᶜa))))
401399

402400
# Flux form vertical advection of area farction with the grid mean velocity
403401
vtt =
@@ -462,7 +460,6 @@ function edmfx_sgs_vertical_advection_tendency!(
462460
ᶜqʲ = MatrixFields.get_field(Y, qʲ_name)
463461
ᶜqʲₜ = MatrixFields.get_field(Yₜ, qʲ_name)
464462
ᶜwʲ = MatrixFields.get_field(p.precomputed, wʲ_name)
465-
ᶜaqʲ = (@. lazy(ᶜa * ᶜqʲ))
466463

467464
# Advective form advection of tracers with updraft velocity
468465
va = vertical_advection(
@@ -473,21 +470,16 @@ function edmfx_sgs_vertical_advection_tendency!(
473470
@. ᶜqʲₜ += va
474471

475472
# Flux form sedimentation of tracers
476-
vtt = vertical_transport_sedimentation(
477-
ᶜρʲs.:($j),
478-
ᶜwʲ,
479-
ᶜaqʲ,
480-
ᶠJ,
481-
)
482-
sed_detr = sedimentation_detrainment(
473+
vtt = updraft_sedimentation(
483474
ᶜρʲs.:($j),
484475
ᶜwʲ,
476+
ᶜa,
485477
ᶜqʲ,
486-
ᶜright_biased_∂a∂z,
478+
ᶠJ,
487479
)
488-
@. ᶜqʲₜ += ᶜinv_ρ̂ * (vtt + sed_detr)
489-
@. Yₜ.c.sgsʲs.:($$j).q_tot += ᶜinv_ρ̂ * (vtt + sed_detr)
490-
@. ᶜ∂ρ∂t_sed += (vtt + sed_detr)
480+
@. ᶜqʲₜ += ᶜinv_ρ̂ * vtt
481+
@. Yₜ.c.sgsʲs.:($$j).q_tot += ᶜinv_ρ̂ * vtt
482+
@. ᶜ∂ρ∂t_sed += vtt
491483

492484
# Flux form sedimentation of energy
493485
if name in (@name(q_liq), @name(q_rai))
@@ -501,19 +493,15 @@ function edmfx_sgs_vertical_advection_tendency!(
501493
else
502494
error("Unsupported moisture tracer variable")
503495
end
504-
vtt = vertical_transport_sedimentation(
505-
ᶜρʲs.:($j),
506-
ᶜwʲ,
507-
ᶜaqʲ .* ᶜmse_li,
508-
ᶠJ,
509-
)
510-
sed_detr = sedimentation_detrainment(
496+
vtt = updraft_sedimentation(
511497
ᶜρʲs.:($j),
512498
ᶜwʲ,
499+
ᶜa,
513500
ᶜqʲ .* ᶜmse_li,
514-
ᶜright_biased_∂a∂z,
501+
ᶠJ,
515502
)
516-
@. Yₜ.c.sgsʲs.:($$j).mse += ᶜinv_ρ̂ * (vtt + sed_detr)
503+
@. Yₜ.c.sgsʲs.:($$j).mse +=
504+
ᶜinv_ρ̂ * vtt
517505
end
518506

519507
# Contribution of density variation due to sedimentation
@@ -552,7 +540,6 @@ function edmfx_sgs_vertical_advection_tendency!(
552540
ᶜχʲ = MatrixFields.get_field(Y, χʲ_name)
553541
ᶜχʲₜ = MatrixFields.get_field(Yₜ, χʲ_name)
554542
ᶜwʲ = MatrixFields.get_field(p.precomputed, wʲ_name)
555-
ᶜaχʲ = (@. lazy(ᶜa * ᶜχʲ))
556543

557544
# Advective form advection of tracers with updraft velocity
558545
va = vertical_transport(
@@ -563,23 +550,76 @@ function edmfx_sgs_vertical_advection_tendency!(
563550
@. ᶜχʲₜ += va
564551

565552
# Flux form sedimentation of tracers
566-
vtt = vertical_transport_sedimentation(
567-
ᶜρʲs.:($j),
568-
ᶜwʲ,
569-
ᶜaχʲ,
570-
ᶠJ,
571-
)
572-
sed_detr = sedimentation_detrainment(
553+
vtt = updraft_sedimentation(
573554
ᶜρʲs.:($j),
574555
ᶜwʲ,
556+
ᶜa,
575557
ᶜχʲ,
576-
ᶜright_biased_∂a∂z,
558+
ᶠJ,
577559
)
578-
@. ᶜχʲₜ += ᶜinv_ρ̂ * (vtt + sed_detr)
560+
@. ᶜχʲₜ += ᶜinv_ρ̂ * vtt
579561

580562
# Contribution of density variation due to sedimentation
581563
@. ᶜχʲₜ -= ᶜinv_ρ̂ * ᶜχʲ * ᶜ∂ρ∂t_sed
582564
end
583565
end
584566
end
585567
end
568+
569+
"""
570+
updraft_sedimentation(ᶜρ, ᶜw, ᶜa, ᶜχ, ᶠJ)
571+
572+
Compute the sedimentation tendency of tracer `χ` within an updraft, including lateral
573+
detrainment when the updraft area increases with height.
574+
575+
# Description
576+
Sedimenting particles fall with velocity `w` through an updraft of fractional area `a(z)`.
577+
The vertical flux divergence gives a tendency of ``∂(ρ w a χ)/∂z``.
578+
When `∂a/∂z > 0`, some sedimenting mass exits laterally through the expanding sides,
579+
producing a detrainment tendency of ``-ρ w χ ∂a/∂z``.
580+
The resulting net tendency in this case is ``a * ∂(ρ w χ)/∂z``.
581+
582+
# Equation
583+
The lateral flux through the updraft side surface `S` within one grid column is
584+
``F_side = ∫_S (ρ χ (w · n)) dS ≈ ρ χ (w · n) A_side,``
585+
where `n` is the outward unit normal and `A_side` the side area.
586+
For predominantly vertical sedimentation,
587+
``w·n A_side ≈ w A_grid [a(z+Δz) - a(z)] = w A_grid Δa.``
588+
Dividing by the grid column volume `A_grid·Δz` gives the flux divergence (tendency):
589+
``tendency ≈ ρ χ w ∂a/∂z.``
590+
A negative sign is applied to represent the loss (detrainment) from the updraft:
591+
``Dₛ = -ρ w χ ∂a/∂z.``
592+
593+
# Arguments
594+
- `ᶜρ`: air density
595+
- `ᶜw`: sedimentation velocity (positive downward)
596+
- `ᶜa`: updraft area fraction
597+
- `ᶜχ`: tracer mixing ratio
598+
- `ᶠJ`: face Jacobian (grid geometry)
599+
600+
# Returns
601+
Tracer tendency due to sedimentation and lateral detrainment.
602+
"""
603+
function updraft_sedimentation(
604+
ᶜρ,
605+
ᶜw,
606+
ᶜa,
607+
ᶜχ,
608+
ᶠJ,
609+
)
610+
ᶜJ = Fields.local_geometry_field(axes(ᶜρ)).J
611+
∂a∂z = @. lazy(ᶜprecipdivᵥ(ᶠinterp(ᶜJ) / ᶠJ * ᶠright_bias(Geometry.WVector(ᶜa))))
612+
return @. lazy(
613+
ifelse(
614+
∂a∂z < 0,
615+
-(ᶜprecipdivᵥ(
616+
ᶠinterp(ᶜρ * ᶜJ) / ᶠJ * ᶠright_bias(Geometry.WVector(-(ᶜw)) * ᶜa * ᶜχ),
617+
)),
618+
-(
619+
ᶜa * ᶜprecipdivᵥ(
620+
ᶠinterp(ᶜρ * ᶜJ) / ᶠJ * ᶠright_bias(Geometry.WVector(-(ᶜw)) * ᶜχ),
621+
)
622+
),
623+
),
624+
)
625+
end

src/prognostic_equations/edmfx_entr_detr.jl

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -526,40 +526,6 @@ function detrainment(
526526
return max(detr, 0)
527527
end
528528

529-
"""
530-
sedimentation_detrainment(ᶜρ, ᶜw, ᶜχ, ᶜ∂a∂z)
531-
532-
Compute the lateral detrainment tendency of a sedimenting tracer `χ` within a tilted updraft.
533-
534-
# Description
535-
Sedimenting particles moving downward through an updraft with a height-varying area fraction `a(z)`
536-
can exit laterally through its sloping sides. When the updraft area increases with height (`∂a/∂z > 0`),
537-
this produces a lateral outflow (detrainment) of tracer mass proportional to the local air density `ρ`,
538-
sedimentation velocity `w`, tracer mixing ratio `χ`, and the vertical gradient of area fraction `∂a/∂z`.
539-
540-
# Equation
541-
The lateral flux through the updraft side surface `S` within one grid column is
542-
F_side = ∫_S (ρ χ (w · n)) dS ≈ ρ χ (w · n) A_side,
543-
where `n` is the outward unit normal and `A_side` the side area.
544-
For predominantly vertical sedimentation,
545-
w·n A_side ≈ w A_grid [a(z+Δz) - a(z)] = w A_grid Δa.
546-
Dividing by the grid column volume `A_grid·Δz` gives the flux divergence (tendency):
547-
tendency ≈ ρ χ w ∂a/∂z. A negative sign is applied to represent the loss (detrainment) from the updraft:
548-
Dₛ = -ρ w χ ∂a/∂z.
549-
550-
# Arguments
551-
- `ᶜρ`: air density at cell center
552-
- `ᶜw`: sedimentation velocity (positive downward)
553-
- `ᶜχ`: tracer mixing ratio
554-
- `ᶜ∂a∂z`: vertical derivative of updraft area fraction
555-
556-
# Returns
557-
Lateral detrainment tendency of tracer `χ` due to sedimentation.
558-
"""
559-
function sedimentation_detrainment(ᶜρ, ᶜw, ᶜχ, ᶜ∂a∂z)
560-
return @. lazy(-1 * ᶜρ * ᶜw * ᶜχ * max(0, ᶜ∂a∂z))
561-
end
562-
563529
function turbulent_entrainment(turbconv_params, ᶜaʲ)
564530
turb_entr_param_vec = CAP.turb_entr_param_vec(turbconv_params)
565531
return max(turb_entr_param_vec[1] * exp(-turb_entr_param_vec[2] * ᶜaʲ), 0)

src/prognostic_equations/implicit/implicit_tendency.jl

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,18 +97,6 @@ function vertical_transport(ᶜρ, ᶠu³, ᶜχ, dt, ::Val{:third_order})
9797
return @. lazy(-(ᶜadvdivᵥ(ᶠinterp(ᶜρ * ᶜJ) / ᶠJ * ᶠupwind3(ᶠu³, ᶜχ))))
9898
end
9999

100-
function vertical_transport_sedimentation(
101-
ᶜρ,
102-
ᶜw,
103-
ᶜχ,
104-
ᶠJ,
105-
)
106-
ᶜJ = Fields.local_geometry_field(axes(ᶜρ)).J
107-
return @. lazy(
108-
-(ᶜprecipdivᵥ(ᶠinterp(ᶜρ * ᶜJ) / ᶠJ * ᶠright_bias(Geometry.WVector(-(ᶜw)) * ᶜχ))),
109-
)
110-
end
111-
112100
vertical_advection(ᶠu³, ᶜχ, ::Val{:none}) =
113101
@. lazy(-(ᶜadvdivᵥ(ᶠu³ * ᶠinterp(ᶜχ)) - ᶜχ * ᶜadvdivᵥ(ᶠu³)))
114102
vertical_advection(ᶠu³, ᶜχ, ::Val{:first_order}) =

src/prognostic_equations/implicit/manual_sparse_jacobian.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -871,15 +871,18 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
871871
DiagonalMatrixRow(ᶜχʲ) ᶜadvdivᵥ_matrix()
872872
) DiagonalMatrixRow(g³³(ᶠgⁱʲ))
873873

874-
# precipitation
874+
# sedimentation
875875
@. ᶜtridiagonal_matrix_scalar =
876-
dtγ * -(ᶜprecipdivᵥ_matrix())
877-
DiagonalMatrixRow(ᶠinterp(ᶜρʲs.:(1) * ᶜJ) / ᶠJ)
878-
ᶠright_bias_matrix()
879-
DiagonalMatrixRow(-Geometry.WVector(ᶜwʲ) * ᶜa)
880-
# precipitation detrainment
881-
@. ᶜtridiagonal_matrix_scalar +=
882-
dtγ * -DiagonalMatrixRow(ᶜρʲs.:(1) * ᶜwʲ * max(0, ᶜ∂a∂z))
876+
dtγ * ifelse(ᶜ∂a∂z < 0,
877+
-(ᶜprecipdivᵥ_matrix())
878+
DiagonalMatrixRow(ᶠinterp(ᶜρʲs.:(1) * ᶜJ) / ᶠJ)
879+
ᶠright_bias_matrix()
880+
DiagonalMatrixRow(-Geometry.WVector(ᶜwʲ) * ᶜa),
881+
-DiagonalMatrixRow(ᶜa) ᶜprecipdivᵥ_matrix()
882+
DiagonalMatrixRow(ᶠinterp(ᶜρʲs.:(1) * ᶜJ) / ᶠJ)
883+
ᶠright_bias_matrix()
884+
DiagonalMatrixRow(-Geometry.WVector(ᶜwʲ)),
885+
)
883886

884887
@. ∂ᶜχʲ_err_∂ᶜχʲ +=
885888
DiagonalMatrixRow(ᶜinv_ρ̂) ᶜtridiagonal_matrix_scalar

0 commit comments

Comments
 (0)