Skip to content

Commit

Permalink
clean up buoyancy routines -- some change to moist buoyancy (#1982)
Browse files Browse the repository at this point in the history
* clean up buoyancy routines -- some change to moist buoyancy

* remove unused

* update amrex submodule and clean up buoyancy some more

* need to allow buoyancy_type 2 again

* remove shadowing

---------

Co-authored-by: Aaron M. Lattanzi <[email protected]>
  • Loading branch information
asalmgren and AMLattanzi authored Nov 26, 2024
1 parent dade055 commit cc030ee
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 448 deletions.
5 changes: 3 additions & 2 deletions Docs/sphinx_doc/LinearSolvers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ Multigrid can also be used when the union of grids at a level is not in itself r
For simulations using grid stretching in the vertical but flat terrain, we must use the hybrid FFT solver in which
we perform 2D transforms only in the lateral directions and couple the solution in the vertical direction with a tridiagonal solve.
In both these cases we use a 7-point stencil.
To solve the Poisson equation on terrain-fitted coordinates with general terrain,
we rely on the FFT-preconditioned GMRES solver since the stencil effectively has variable coefficients and requires 19 points.
.. note::
**Currently only doubly periodic lateral boundary conditions are supported by the hybrid FFT, and therefore by the GMRES solver. More general boundary conditions are a work in progress.**
- .. note::
- **The FFT solver / preconditioner can only be used when the union of grids at a level is itself rectangular.
67 changes: 17 additions & 50 deletions Docs/sphinx_doc/theory/Buoyancy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,24 @@

.. _sec:Buoyancy:

ERF has several options for how to define the buoyancy force.

Buoyancy
=========

ERF has three options for how to define the buoyancy force. Even in the absence of moisture these
expressions are not equivalent.
When using the anelastic formulation, the expression for buoyancy used by ERF is

.. math::
\mathbf{B} = -\rho^\prime \mathbf{g} \approx -\rho_0 \mathbf{g} ( \frac{\theta_v^\prime}{\overline{\theta_0}}
where we define

.. math::
\theta_v = \theta_d (1 - (1 - \frac{R_v}{R_d}) (q_v + q_c) - \frac{R_v}{R_d} q_c)
When using the compressible formulation, the following choices are available.


Density of the mixture
-----------------------
Expand Down Expand Up @@ -52,56 +65,10 @@ for the background state. For eg., a usual scenario is that of a background stat
the total background density :math:`\rho_0 = \rho_{d_0}(1 + q_{v_0})`, where :math:`\rho_{d_0}` and :math:`q_{v_0}` are the background dry density and vapor mixing ratio respectively.
As a check, we observe that :math:`\rho^\prime_0 = 0`, which means that the background state is not buoyant.

Type 2
------

The second option for the buoyancy force is

.. math::
\mathbf{B} = -\rho_0 \mathbf{g} ( 0.61 q_v^\prime - q_c^\prime - q_i^\prime - q_p^\prime
+ \frac{T^\prime}{\bar{T}} (1.0 + 0.61 \bar{q_v} - \bar{q_i} - \bar{q_c} - \bar{q_p}) )
To derive this expression, we define :math:`T_v = T (1 + 0.61 q_v − q_c − q_i - q_p)`, then we can write

.. math::
p = \rho (R_d q_d + R_v q_v) T = \rho R_d T (1 + 0.61 q_v − q_c − q_i - q_p ) = \rho R_d T_v
Starting from :math:`p = \rho R_d T_v` and neglecting :math:`\frac{p^\prime}{\bar{p}}`, we now write

.. math::
\frac{\rho^\prime}{\overline{\rho}} = -\frac{T_v^\prime}{\overline{T_v}}
and define

.. math::
T_v^\prime = T_v - \overline{T_v} \approx \overline{T} [ 0.61 q_v^\prime - (q_c^\prime + q_i^\prime + q_p^\prime)] +
(T - \overline{T}) [1+ 0.61 \bar{q_v} - \bar{q_c} - \bar{q_i} - \bar{q_p} ] .
where we have retained only first order terms in perturbational quantities.

Then

.. math::
\mathbf{B} = \rho^\prime \mathbf{g} = -\overline{\rho} \frac{\overline{T}}{\overline{T_v}} \mathbf{g} [ 0.61 q_v^\prime - q_c^\prime - q_i^\prime - q_p^\prime ) + \frac{T^\prime}{\overline{T_v}} (1.0 + 0.61 \bar{q_v} - \bar{q_i} - \bar{q_c} - \bar{q_p}) ]
where the overbar represents a horizontal average of the current state and the perturbation is defined relative to that average.

Again keeping only the first order terms in the mass mixing ratios, we can simplify this to

.. math::
\mathbf{B} = \rho^\prime \mathbf{g} = -\rho_0 \mathbf{g} [ 0.61 q_v^\prime - q_c^\prime + q_i^\prime + q_p^\prime
+ \frac{T^\prime}{\overline{T}} (1.0 + 0.61 \bar{q_v} - \bar{q_i} - \bar{q_c} - \bar{q_p}) ]
We note that this reduces to Type 3 if the horizontal averages of the moisture terms are all zero.

Type 3
------

The third formulation of the buoyancy term assumes that the horizontal averages of the moisture quantities are negligible,
which removes the need to compute horizontal averages of these quantities. This reduces the Type 2 expression to the following:
This formulation of the buoyancy term assumes that the horizontal averages of the moisture quantities are negligible.

.. math::
\mathbf{B} = \rho^\prime \mathbf{g} \approx -\rho_0 \mathbf{g} ( \frac{T^\prime}{\overline{T}}
Expand All @@ -120,7 +87,7 @@ This expression for buoyancy is from `khairoutdinov2003cloud`_ and `bryan2002ben
.. math::
\begin{equation}
\mathbf{B} = \rho'\mathbf{g} \approx -\rho\Bigg(\frac{T'}{T} + 0.61 q_v' - q_c - q_p - \frac{p'}{p}\Bigg)\mathbf{g},
\mathbf{B} = \rho'\mathbf{g} \approx -\rho \mathbf{g} \Bigg(\frac{T'}{T} + 0.61 q_v' - q_c - q_p - \frac{p'}{p}\Bigg)
\end{equation}
The derivation follows. The total density is given by :math:`\rho = \rho_d(1 + q_v + q_c + q_p)`, which can be written as
Expand Down
9 changes: 5 additions & 4 deletions Source/DataStructs/ERF_DataStruct.H
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,15 @@ struct SolverChoice {
if (moisture_type == MoistureType::Kessler_NoRain ||
moisture_type == MoistureType::SAM ||
moisture_type == MoistureType::SAM_NoIce ||
moisture_type == MoistureType::SAM_NoPrecip_NoIce) {
buoyancy_type = 1; // asserted in make buoyancy
moisture_type == MoistureType::SAM_NoPrecip_NoIce)
{
buoyancy_type = 1; // uses Rhoprime
} else {
buoyancy_type = 2; // uses Tprime
}
}

// Which expression (1,2 or 3) to use for buoyancy
// Which expression (1,2/3 or 4) to use for buoyancy
pp.query("buoyancy_type", buoyancy_type);

// What type of land surface model to use
Expand Down Expand Up @@ -196,7 +197,7 @@ struct SolverChoice {
if (any_anelastic == 1) {
constant_density = true;
project_initial_velocity = true;
buoyancy_type = 2; // uses Tprime
buoyancy_type = 3; // (This isn't actually used when anelastic is set)
} else {
pp.query("project_initial_velocity", project_initial_velocity);

Expand Down
Loading

0 comments on commit cc030ee

Please sign in to comment.