Update
PinCFlow.Update — Module
UpdateModule for integrating the prognostic equations.
Provides functions for updating the prognostic variables at the various stages of the semi-implicit time scheme.
See also
PinCFlow.Update.Cartesian — Type
CartesianSingleton for transformations from the terrain-following system to the Cartesian one.
PinCFlow.Update.LHS — Type
LHSSingleton for the integration of the left-hand side of an equation.
PinCFlow.Update.RHS — Type
RHSSingleton for the integration of the right-hand side of an equation.
PinCFlow.Update.Transformed — Type
TransformedSingleton for transformations from the Cartesian system to the terrain-following one.
PinCFlow.Update.X — Type
XSingleton for $\widehat{x}$-axis along which a calculation should be performed.
PinCFlow.Update.Y — Type
YSingleton for $\widehat{y}$-axis along which a calculation should be performed.
PinCFlow.Update.Z — Type
ZSingleton for $\widehat{z}$-axis along which a calculation should be performed.
PinCFlow.Update.apply_lhs_sponge! — Function
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::AbstractPredictand,
)Perform an implicit substep to integrate the Rayleigh-damping term that represents the LHS sponge in the prognostic equation for variable by dispatching to the appropriate model-specific method.
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::Rho,
model::Boussinesq,
)Return in Boussinesq mode (constant density).
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::Rho,
model::Union{PseudoIncompressible, Compressible},
)Integrate the Rayleigh-damping term that represents the LHS sponge in the continuity equation.
The update is given by
\[\rho \rightarrow \left(1 + \alpha_\mathrm{R} \Delta t\right)^{- 1} \left(\rho + \alpha_\mathrm{R} \Delta t \overline{\rho}\right),\]
where $\alpha_\mathrm{R}$ is the Rayleigh-damping coefficient computed by PinCFlow.Update.compute_sponges! and $\Delta t$ is the time step given as input to this method.
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::RhoP,
model::Compressible,
)Integrate the Rayleigh-damping term that represents the LHS sponge in the auxiliary equation in compressible mode.
The update is given by
\[\rho' \rightarrow \left(1 + \alpha_\mathrm{R} \Delta t\right)^{- 1} \left[\rho' + \alpha_\mathrm{R} \Delta t \overline{\rho} \left(1 - \frac{P}{\rho \overline{\theta}}\right)\right].\]
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::RhoP,
model::Union{Boussinesq, PseudoIncompressible},
)Integrate the Rayleigh-damping term that represents the LHS sponge in the auxiliary equation in non-compressible modes.
The update is given by
\[\rho' \rightarrow \left(1 + \alpha_\mathrm{R} \Delta t\right)^{- 1} \rho'.\]
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::U,
model::AbstractModel,
)Integrate the Rayleigh-damping term that represents the LHS sponge in the zonal-momentum equation.
The update is given by
\[u_{i + 1 / 2} \rightarrow \left(1 + \alpha_{\mathrm{R}, i + 1 / 2} \Delta t\right)^{- 1} \left(u_{i + 1 / 2} + \alpha_{\mathrm{R}, i + 1 / 2} \Delta t u_{\mathrm{R}, i + 1 / 2}\right).\]
If state.namelists.sponge.relax_to_mean is false, $u_{\mathrm{R}, i + 1 / 2}$ is computed with state.namelist.sponge.relaxed_u. Otherwise, it is replaced with the average of $u_{i + 1 / 2}$ across the terrain-following coordinate surface.
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::V,
model::AbstractModel,
)Integrate the Rayleigh-damping term that represents the LHS sponge in the meridional-momentum equation.
The update is given by
\[v_{j + 1 / 2} \rightarrow \left(1 + \alpha_{\mathrm{R}, j + 1 / 2} \Delta t\right)^{- 1} \left(v_{j + 1 / 2} + \alpha_{\mathrm{R}, j + 1 / 2} \Delta t v_{\mathrm{R}, j + 1 / 2}\right).\]
If state.namelists.sponge.relax_to_mean is false, $v_{\mathrm{R}, j + 1 / 2}$ is computed with state.namelist.sponge.relaxed_v. Otherwise, it is replaced with the average of $v_{j + 1 / 2}$ across the terrain-following coordinate surface.
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::W,
model::AbstractModel,
)Integrate the Rayleigh-damping term that represents the LHS sponge in the transformed-vertical-momentum equation.
The update is given by
\[\widehat{w}_{k + 1 / 2} \rightarrow \left(1 + \alpha_{\mathrm{R}, k + 1 / 2} \Delta t\right)^{- 1} \left(\widehat{w}_{k + 1 / 2} + \alpha_{\mathrm{R}, k + 1 / 2} \Delta t \widehat{w}_{\mathrm{R}, k + 1 / 2}\right).\]
If state.namelists.sponge.relax_to_mean is false, $\widehat{w}_{\mathrm{R}, k + 1 / 2}$ is computed with the functions relaxed_u, relaxed_v and relaxed_w in state.namelists.sponge. Otherwise, it is replaced with the average of $\widehat{w}_{k + 1 / 2}$ across the terrain-following coordinate surface.
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::PiP,
model::Union{Boussinesq, PseudoIncompressible},
)Return in non-compressible modes (Exner-pressure fluctuations are only updated in the corrector step).
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::PiP,
model::Compressible,
)Update the Exner-pressure fluctuations to account for the Rayleigh damping applied to the mass-weighted potential temperature.
The update is given by
\[\pi' \rightarrow \pi' - \alpha_\mathrm{R} \Delta t P \frac{\partial \pi'}{\partial P} \left(1 - \frac{\overline{\rho}}{\rho}\right).\]
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::P,
model::Union{Boussinesq, PseudoIncompressible},
)Return in non-compressible modes (mass-weighted potential temperature is constant in time).
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
variable::P,
model::Compressible,
)Integrate the Rayleigh-damping term that represents the LHS sponge in the thermodynamic-energy equation.
The update is given by
\[P \rightarrow \left(1 + \alpha_\mathrm{R} \Delta t\right)^{- 1} P \left(1 + \alpha_\mathrm{R} \Delta t \frac{\overline{\rho}}{\rho}\right).\]
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
tracer_setup::NoTracer,
)Return for configurations without tracer transport.
apply_lhs_sponge!(
state::State,
dt::AbstractFloat,
time::AbstractFloat,
tracer_setup::TracerOn,
)Integrate the Rayleigh-damping terms that represent the LHS sponge in the tracer equations.
In each tracer equation, the update is given by
\[\left(\rho \chi\right) \rightarrow \left(1 + \alpha_\mathrm{R} \Delta t\right)^{- 1} \left[\rho \chi + \alpha_\mathrm{R} \Delta t \left(\rho \chi\right)^{\left(0\right)}\right].\]
Arguments
state: Model state.dt: Time step.time: Simulation time.variable: Variable to apply Rayleigh damping to.model: Dynamic equations.tracer_setup: General tracer-transport configuration.
PinCFlow.Update.compute_buoyancy_factor — Function
compute_buoyancy_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::Union{RhoP, W},
)::AbstractFloatCompute the factor by which the buoyancy term should be multiplied at $\left(i, j, k\right)$ or $\left(i, j, k + 1 / 2\right)$, by dispatching to a method specific for the dynamic equations and variable, and return the result.
In pseudo-incompressible mode, $\rho'$ are deviations of the total density from $\overline{\rho}$, which describes the reference atmosphere. However, in compressible mode, $\rho' = \rho - P / \overline{\theta}$ does not reduce to this, i.e. the density background has a spatiotemporal dependence. As a consequence, the right-hand side of the prognostic equation for $\rho'$ is given by
\[\left(\frac{\partial \rho'}{\partial t}\right)_{N^2} = f_{\rho'} \frac{N^2 \rho w}{g},\]
with $f_{\rho'} = \overline{\rho} / \rho$ in pseudo-incompressible mode and $f_{\rho'} = P / \left(\rho \overline{\theta}\right)$ in compressible mode. This method returns either $f_{\rho'}$ at $\left(i, j, k\right)$ or $f_w$, which is the interpolation of $f_{\rho'}$ to $\left(i, j, k + 1 / 2\right)$, based on the type of variable.
compute_buoyancy_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::RhoP,
model::Compressible,
)::AbstractFloatReturn $f_{\rho'} = P / \left(\rho \overline{\theta}\right)$ as the factor by which the buoyancy term should be multiplied at $\left(i, j, k\right)$ in compressible mode.
compute_buoyancy_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::RhoP,
model::Union{Boussinesq, PseudoIncompressible},
)::AbstractFloatReturn $f_{\rho'} = \overline{\rho} / \rho$ as the factor by which the buoyancy term should be multiplied at $\left(i, j, k\right)$ in pseudo-incompressible mode (this method is also used in Boussinesq mode).
compute_buoyancy_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::W,
model::Compressible,
)::AbstractFloatReturn $f_w = \left(P / \overline{\theta}\right)_{k + 1 / 2} / \rho_{k + 1 / 2}$ as the factor by which the buoyancy term should be multiplied in compressible mode.
compute_buoyancy_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::W,
model::Union{Boussinesq, PseudoIncompressible},
)::AbstractFloatReturn $f_w = \overline{\rho}_{k + 1 / 2} / \rho_{k + 1 / 2}$ as the factor by which the buoyancy term should be multiplied at $\left(i, j, k + 1 / 2\right)$ in pseudo-incompressible mode (this method is also used in Boussinesq mode).
Arguments
state: Model state.i: Zonal grid-cell index.j: Meridional grid-cell index.k: Vertical grid-cell index.variable: Variable for which the factor is needed.model: Dynamic equations.
PinCFlow.Update.compute_compressible_wind_factor — Function
compute_compressible_wind_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::Union{U, V, W},
)::AbstractFloatCompute the factor by which the wind should be multiplied at $\left(i + 1 / 2, j, k\right)$, $\left(i, j + 1 / 2, k\right)$ or $\left(i, j, k + 1 / 2\right)$, by dispatching to a method specific for the dynamic equations and the component indicated by variable, and return the result.
In compressible mode, the Euler steps that are used to integrate the right-hand side of the momentum equation update $\left(J P\right)_{i + 1 / 2} u_{i + 1 / 2}$, $\left(J P\right)_{j + 1 / 2} v_{j + 1 / 2}$ and $\left(J P\right)_{k + 1 / 2} \widehat{w}_{k + 1 / 2}$ instead of $u_{i + 1 / 2}$, $v_{j + 1 / 2}$ and $\widehat{w}_{k + 1 / 2}$.
compute_compressible_wind_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::Union{U, V, W},
model::Union{Boussinesq, PseudoIncompressible},
)::AbstractFloatReturn $1$ as the factor by which the wind should be multiplied in non-compressible mode.
compute_compressible_wind_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::U,
model::Compressible,
)::AbstractFloatReturn $\left(J P\right)_{i + 1 / 2}$ as the factor by which the zonal wind should be multiplied in compressible mode.
compute_compressible_wind_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::V,
model::Compressible,
)::AbstractFloatReturn $\left(J P\right)_{j + 1 / 2}$ as the factor by which the meridional wind should be multiplied in compressible mode.
compute_compressible_wind_factor(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::W,
model::Compressible,
)::AbstractFloatReturn $\left(J P\right)_{k + 1 / 2}$ as the factor by which the transformed vertical wind should be multiplied in compressible mode.
Arguments
state: Model state.i: Zonal grid-cell index.j: Meridional grid-cell index.k: Vertical grid-cell index.variable: Variable for which the factor is needed.model: Dynamic equations.
PinCFlow.Update.compute_momentum_diffusion_terms — Function
compute_momentum_diffusion_terms(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::U,
direction::X,
)::AbstractFloatCompute and return the diffusive zonal momentum fluxes in $\widehat{x}$-direction, i.e.
\[\widehat{\left(\boldsymbol{\nabla} u\right)}^{\widehat{x}} = \frac{u_{i + 1 / 2} - u_{i - 1 / 2}}{\Delta \widehat{x}} + G^{13} \frac{u_{k + 1} - u_{k - 1}}{2\Delta \widehat{z}}.\]
compute_momentum_diffusion_terms(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::U,
direction::Y,
)::AbstractFloatCompute and return the diffusive zonal momentum fluxes in $\widehat{y}$-direction, i.e.
\[\widehat{\left(\boldsymbol{\nabla} u\right)}^{\widehat{y}} = \frac{u_{j + 1} - u_{j - 1}}{2\Delta \widehat{y}} + G^{23} \frac{u_{k + 1} - u_{k - 1}}{2\Delta \widehat{z}}.\]
compute_momentum_diffusion_terms(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::U,
direction::Z,
)::AbstractFloatCompute and return the diffusive zonal momentum fluxes in $\widehat{z}$-direction, i.e.
\[\widehat{\left(\boldsymbol{\nabla} u\right)}^{\widehat{z}} = G^{13}\frac{u_{i + 1 / 2} - u_{i - 1 / 2}}{\Delta \widehat{x}} + G^{23} \frac{u_{j + 1} - u_{j - 1}}{2 \Delta \widehat{y}} + G^{33} \frac{u_{k + 1} - u_{k - 1}}{2 \Delta \widehat{z}}.\]
compute_momentum_diffusion_terms(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::V,
direction::X,
)::AbstractFloatCompute and return the diffusive meridional momentum fluxes in $\widehat{x}$-direction, i.e.
\[\widehat{\left(\boldsymbol{\nabla} v\right)}^{\widehat{x}} = \frac{v_{i + 1} - v_{i - 1}}{2 \Delta \widehat{x}} + G^{13} \frac{v_{k + 1} - v_{k - 1}}{2 \Delta \widehat{z}}.\]
compute_momentum_diffusion_terms(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::V,
direction::Y,
)::AbstractFloatCompute and return the diffusive meridional momentum fluxes in $\widehat{y}$-direction, i.e.
\[\widehat{\left(\boldsymbol{\nabla} v\right)}^{\widehat{y}} = \frac{v_{j + 1 / 2} - v_{j - 1 / 2}}{\Delta \widehat{y}} + G^{23} \frac{v_{k + 1} - v_{k - 1}}{2 \Delta \widehat{z}}.\]
compute_momentum_diffusion_terms(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::V,
direction::Z,
)::AbstractFloatCompute and return the diffusive meridional momentum fluxes in $\widehat{z}$-direction, i.e.
\[\widehat{\left(\boldsymbol{\nabla} v\right)}^{\widehat{z}} = G^{13}\frac{v_{i + 1} - v_{i - 1}}{2 \Delta \widehat{x}} + G^{23} \frac{v_{j + 1 / 2} - v_{j - 1 / 2}}{\Delta \widehat{y}} + G^{33} \frac{v_{k + 1} - v_{k - 1}}{2 \Delta \widehat{z}}.\]
compute_momentum_diffusion_terms(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::W,
direction::X,
)::AbstractFloatCompute and return the diffusive vertical momentum fluxes in $\widehat{x}$-direction, i.e.
\[\widehat{\left(\boldsymbol{\nabla} w\right)}^{\widehat{x}} = \frac{w_{i + 1} - w_{i - 1}}{2 \Delta \widehat{x}} + G^{13} \frac{w_{k + 1 / 2} - w_{k - 1 / 2}}{\Delta \widehat{z}}.\]
compute_momentum_diffusion_terms(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::W,
direction::Y,
)::AbstractFloatCompute and return the diffusive vertical momentum fluxes in $\widehat{y}$-direction, i.e.
\[\widehat{\left(\boldsymbol{\nabla} w\right)}^{\widehat{y}} = \frac{w_{j + 1} - w_{j - 1}}{2 \Delta \widehat{y}} + G^{23} \frac{w_{k + 1 / 2} - w_{k - 1 / 2}}{\Delta \widehat{z}}.\]
compute_momentum_diffusion_terms(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::W,
direction::Z,
)::AbstractFloatCompute and return the diffusive vertical momentum fluxes in $\widehat{z}$-direction, i.e.
\[\widehat{\left(\boldsymbol{\nabla} w\right)}^{\widehat{z}} = G^{13} \frac{w_{i + 1} - w_{i - 1}}{2 \Delta \widehat{x}} + G^{23} \frac{w_{j + 1} - w_{j - 1}}{2 \Delta \widehat{y}} + G^{33} \frac{w_{k + 1 / 2} - w_{k - 1 / 2}}{\Delta \widehat{z}}.\]
Arguments
state: Model state.i: Grid-cell index on the $\widehat{x}$-axis.j: Grid-cell index on the $\widehat{y}$-axis.k: Grid-cell index on the $\widehat{z}$-axis.variable: Wind direction.direction: Direction of the flux.
PinCFlow.Update.compute_pressure_gradient — Function
compute_pressure_gradient(
state::State,
pip::AbstractArray{<:AbstractFloat, 3},
i::Integer,
j::Integer,
k::Integer,
variable::U,
)::AbstractFloatCompute and return the pressure(-difference)-gradient term in the zonal-wind equation at $\left(i + 1 / 2, j, k\right)$, using the pressure(-difference) field pip.
The pressure-gradient component is given by
\[\mathcal{P}^{\rho u}_{i + 1 / 2} = \frac{\pi'_{i + 1} - \pi'}{\Delta \widehat{x}} + G^{13}_{i + 1 / 2} \frac{\pi'_{i + 1 / 2, k + 1} - \pi'_{i + 1 / 2, k - 1}}{2 \Delta \widehat{z}}.\]
Since the Exner-pressure is not known in the vertical ghost cells, a different discretization is needed at the vertical boundaries. At $k = k_0$ (in the first process in $\widehat{z}$), the alternative second-order-accurate approximation
\[\mathcal{P}^{\rho u}_{i + 1 / 2} = \frac{\pi'_{i + 1} - \pi'}{\Delta \widehat{x}} + G^{13}_{i + 1 / 2} \frac{- \pi'_{i + 1 / 2, k + 2} + 4 \pi'_{i + 1 / 2, k + 1} - 3 \pi'_{i + 1 / 2}}{2 \Delta \widehat{z}}\]
is used and, in a similar manner, one has
\[\mathcal{P}^{\rho u}_{i + 1 / 2} = \frac{\pi'_{i + 1} - \pi'}{\Delta \widehat{x}} + G^{13}_{i + 1 / 2} \frac{\pi'_{i + 1 / 2, k - 2} - 4 \pi'_{i + 1 / 2, k - 1} + 3 \pi'_{i + 1 / 2}}{2 \Delta \widehat{z}}\]
at $k = k_1$ (in the last process in $\widehat{z}$). The corresponding pressure-difference-gradient component $\mathcal{D}^{\rho u}_{i + 1 / 2}$ is obtained by replacing $\pi'$ with $\Delta \pi'$. The returned quantity also includes the factor $c_p \left(P_{i + 1 / 2} / \rho_{i + 1 / 2}\right)$.
compute_pressure_gradient(
state::State,
pip::AbstractArray{<:AbstractFloat, 3},
i::Integer,
j::Integer,
k::Integer,
variable::V,
)::AbstractFloatCompute and return the pressure-gradient term in the meridional-wind equation at $\left(i, j + 1 / 2, k\right)$, using the pressure(-difference) field pip.
The pressure-gradient component is given by
\[\mathcal{P}^{\rho v}_{j + 1 / 2} = \frac{\pi'_{j + 1} - \pi'}{\Delta \widehat{y}} + G^{23}_{j + 1 / 2} \frac{\pi'_{j + 1 / 2, k + 1} - \pi'_{j + 1 / 2, k - 1}}{2 \Delta \widehat{z}}.\]
Analogous to the component in the zonal-wind equation, one has
\[\mathcal{P}^{\rho v}_{j + 1 / 2} = \frac{\pi'_{j + 1} - \pi'}{\Delta \widehat{y}} + G^{23}_{j + 1 / 2} \frac{- \pi'_{j + 1 / 2, k + 2} + 4 \pi'_{j + 1 / 2, k + 1} - 3 \pi'_{j + 1 / 2}}{2 \Delta \widehat{z}}\]
at $k = k_0$ (in the first process in $\widehat{z}$) and
\[\mathcal{P}^{\rho v}_{j + 1 / 2} = \frac{\pi'_{j + 1} - \pi'}{\Delta \widehat{y}} + G^{23}_{j + 1 / 2} \frac{\pi'_{j + 1 / 2, k - 2} - 4 \pi'_{j + 1 / 2, k - 1} + 3 \pi'_{j + 1 / 2}}{2 \Delta \widehat{z}}\]
at $k = k_1$ (in the last process in $\widehat{z}$). The corresponding pressure-difference-gradient component $\mathcal{D}^{\rho v}_{j + 1 / 2}$ is obtained by replacing $\pi'$ with $\Delta \pi'$. The returned quantity also includes the factor $c_p \left(P_{j + 1 / 2} / \rho_{j + 1 / 2}\right)$.
compute_pressure_gradient(
state::State,
pip::AbstractArray{<:AbstractFloat, 3},
i::Integer,
j::Integer,
k::Integer,
variable::W,
)::AbstractFloatCompute and return the pressure(-difference)-gradient term in the transformed-vertical-wind equation at $\left(i, j, k + 1 / 2\right)$, using the pressure(-difference) field pip.
The pressure-gradient component is given by
\[\begin{align*} \mathcal{P}^{\rho \widehat{w}}_{k + 1 / 2} & = G^{13}_{k + 1 / 2} \frac{\pi'_{i + 1, k + 1 / 2} - \pi'_{i - 1, k + 1 / 2}}{2 \Delta \widehat{x}} + G^{23}_{k + 1 / 2} \frac{\pi'_{j + 1, k + 1 / 2} - \pi'_{j - 1, k + 1 / 2}}{2 \Delta \widehat{y}}\\ & \quad + G^{33}_{k + 1 / 2} \frac{\pi'_{k + 1} - \pi'}{\Delta \widehat{z}}. \end{align*}\]
At $k = k_0 - 1$ (in the first process in $\widehat{z}$) and $k = k_1$ (in the last process in $\widehat{z}$), it is set to zero. The corresponding pressure-difference-gradient component $\mathcal{D}^{\rho \widehat{w}}_{k + 1 / 2}$ is obtained by replacing $\pi'$ with $\Delta \pi'$. The returned quantity also includes the factor $c_p \left(P_{k + 1 / 2} / \rho_{k + 1 / 2}\right)$.
Arguments
state: Model state.pip: Pressure field.i: Zonal grid-cell index.j: Meridional grid-cell index.k: Vertical grid-cell index.variable: Equation in which the respective pressure-gradient component is needed.
PinCFlow.Update.compute_sponges! — Function
compute_sponges!(state::State, dt::AbstractFloat, time::AbstractFloat)Compute the Rayleigh-damping coefficients of the two sponges.
The coefficients are computed with the functions lhs_sponge and rhs_sponge in state.namelists.sponge.
Arguments
state: Model state.dt: Time step.time: Simulation time.
See also
PinCFlow.Update.compute_stress_tensor — Function
compute_stress_tensor(
i::Integer,
j::Integer,
k::Integer,
mu::Integer,
nu::Integer,
state::State,
)::AbstractFloatCompute and return the element $\left(\mu, \nu\right)$ of the Cartesian stress tensor at the grid point $\left(i, j, k\right)$.
The discretized elements of the Cartesian stress tensor are given by
\[\begin{align*} \Pi^{1 1} & = \frac{2}{\Delta \widehat{x}} \left(u_{i + 1 / 2} - u_{i - 1 / 2}\right) + \frac{G^{1 3}}{\Delta \widehat{z}} \left(u_{k + 1} - u_{k - 1}\right) - \frac{2}{3} \delta,\\ \Pi^{1 2} & = \frac{1}{2 \Delta \widehat{y}} \left(u_{j + 1} - u_{j - 1}\right) + \frac{G^{2 3}}{2 \Delta \widehat{z}} \left(u_{k + 1} - u_{k - 1}\right) + \frac{1}{2 \Delta \widehat{x}} \left(v_{i + 1} - v_{i - 1}\right) + \frac{G^{1 3}}{2 \Delta \widehat{z}} \left(v_{k + 1} - v_{k - 1}\right),\\ \Pi^{1 3} & = \frac{1}{2 J \Delta \widehat{z}} \left(u_{k + 1} - u_{k - 1}\right) + \frac{1}{2 \Delta \widehat{x}} \left(w_{i + 1} - w_{i - 1}\right) + \frac{G^{1 3}}{\Delta \widehat{z}} \left(w_{k + 1 / 2} - w_{k - 1 / 2}\right),\\ \Pi^{2 2} & = \frac{2}{\Delta \widehat{y}} \left(v_{j + 1 / 2} - v_{j - 1 / 2}\right) + \frac{G^{2 3}}{\Delta \widehat{z}} \left(v_{k + 1} - v_{k - 1}\right) - \frac{2}{3} \delta,\\ \Pi^{2 3} & = \frac{1}{2 J \Delta \widehat{z}} \left(v_{k + 1} - v_{k - 1}\right) + \frac{1}{2 \Delta \widehat{y}} \left(w_{j + 1} - w_{j - 1}\right) + \frac{G^{2 3}}{\Delta \widehat{z}} \left(w_{k + 1 / 2} - w_{k - 1 / 2}\right),\\ \Pi^{3 3} & = \frac{2}{J \Delta \widehat{z}} \left(w_{k + 1 / 2} - w_{k - 1 / 2}\right) - \frac{2}{3} \delta, \end{align*}\]
where
\[\begin{align*} \delta & = \frac{1}{J} \left[\frac{1}{\Delta \widehat{x}} \left(J_{i + 1 / 2} u_{i + 1 / 2} - J_{i - 1 / 2} u_{i - 1 / 2}\right) + \frac{1}{\Delta \widehat{y}} \left(J_{j + 1 / 2} v_{j + 1 / 2} - J_{j - 1 / 2} v_{j - 1 / 2}\right)\right.\\ & \qquad \quad + \left.\frac{1}{\Delta \widehat{z}} \left(J_{k + 1 / 2} \widehat{w}_{k + 1 / 2} - J_{k - 1 / 2} \widehat{w}_{k - 1 / 2}\right)\right]. \end{align*}\]
Arguments
i: Zonal grid-cell index.j: Meridional grid-cell index.k: Vertical grid-cell index.mu: First contravariant tensor index.nu: Second contravariant tensor index.state: Model state.
See also
PinCFlow.Update.compute_vertical_wind — Function
compute_vertical_wind(
i::Integer,
j::Integer,
k::Integer,
state::State,
)::AbstractFloatCompute and return the Cartesian vertical wind at the grid point $\left(i, j, k + 1 / 2\right)$.
Arguments
i: Zonal grid-cell index.j: Meridional grid-cell index.k: Vertical grid-cell index.state: Model state.
See also
PinCFlow.Update.compute_volume_force — Function
compute_volume_force(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::Union{U, V, W, P, Chi},
)::AbstractFloatReturn the volume force in the equation specified by variable, by dispatching to an equation-and-WKB-mode specific method.
compute_volume_force(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::Union{U, V, W, Chi},
wkb_mode::NoWKB,
)::AbstractFloatReturn $0$ as the volume force in non-WKB configurations (for all variables except the mass-weighted potential temperature).
compute_volume_force(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::U,
wkb_mode::Union{SteadyState, SingleColumn, MultiColumn},
)::AbstractFloatReturn the gravity-wave drag on the zonal momentum, interpolated to $\left(i + 1 / 2, j, k\right)$.
compute_volume_force(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::V,
wkb_mode::Union{SteadyState, SingleColumn, MultiColumn},
)::AbstractFloatReturn the gravity-wave drag on the meridional momentum, interpolated to $\left(i, j + 1 / 2, k\right)$.
compute_volume_force(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::W,
wkb_mode::Union{SteadyState, SingleColumn, MultiColumn},
)::AbstractFloatReturn the gravity-wave drag on the transformed vertical momentum, interpolated to $\left(i, j, k + 1 / 2\right)$, as given by
\[\left(\frac{\partial \widehat{w}}{\partial t}\right)_\mathrm{w} = \left[G^{1 3} \left(\frac{\partial u}{\partial t}\right)_\mathrm{w}\right]_{k + 1 / 2} + \left[G^{2 3} \left(\frac{\partial v}{\partial t}\right)_\mathrm{w}\right]_{k + 1 / 2}.\]
compute_volume_force(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::P,
wkb_mode::NoWKB,
)::AbstractFloatReturn the conductive heating.
compute_volume_force(
state::State,
i::Integer,
j::Integer,
k::Integer,
variable::P,
wkb_mode::Union{SteadyState, SingleColumn, MultiColumn},
)::AbstractFloatReturn the sum of gravity-wave impact on the mass-weighted potential temperature and conductive heating.
compute_volume_force(
state::State,
i::Integer,
j::Integer,
k::Integer,
variables::Chi,
wkb_mode::Union{SteadyState, SingleColumn, MultiColumn},
)::AbstractFloatReturn the tracer flux convergence due to gravity waves.
Arguments
state: Model state.i: Zonal grid-cell index.j: Meridional grid-cell index.k: Vertical grid-cell index.variable: Variable (equation) of choice.wkb_mode: Approximations used by MS-GWaM.
See also
PinCFlow.Update.conductive_heating — Function
conductive_heating(
state::State,
i::Integer,
j::Integer,
k::Integer,
)::AbstractFloatCompute and return the conductive heating by dispatching to specialized methods dependent on the model.
conductive_heating(
state::State,
i::Integer,
j::Integer,
k::Integer,
model::Boussinesq,
)::AbstractFloatReturn $0$ as conductive heating in Boussinesq mode.
conductive_heating(
state::State,
i::Integer,
j::Integer,
k::Integer,
model::PseudoIncompressible,
)::AbstractFloatReturn $0$ as conductive heating in PseudoIncompressible mode.
conductive_heating(
state::State,
i::Integer,
j::Integer,
k::Integer,
model::Compressible,
)::AbstractFloatCompute and return the conductive heating as the convergence of potential temperature fluxes (weighted by the density), i.e.
\[\left(\frac{\partial P}{\partial t}\right)_\lambda = - \frac{\rho}{J} \left(\frac{\mathcal{F}_{i + 1 / 2}^{\theta, \widehat{x}} - \mathcal{F}_{i - 1 / 2}^{\theta, \widehat{x}}}{\Delta \widehat{x}} + \frac{\mathcal{F}_{j + 1 / 2}^{\theta, \widehat{y}} - \mathcal{F}_{j - 1 / 2}^{\theta, \widehat{y}}}{\Delta \widehat{y}} + \frac{\mathcal{F}_{k + 1 / 2}^{\theta, \widehat{z}} - \mathcal{F}_{k - 1 / 2}^{\theta, \widehat{z}}}{\Delta \widehat{z}}\right).\]
Arguments
state: Model state.i: Zonal grid-cell index.j: Meridional grid-cell index.k: Vertical grid-cell index.model: Dynamic equations.
PinCFlow.Update.transform — Function
transform(
i::Integer,
j::Integer,
k::Integer,
uedger::AbstractFloat,
uuedger::AbstractFloat,
uedgel::AbstractFloat,
uuedgel::AbstractFloat,
vedgef::AbstractFloat,
vuedgef::AbstractFloat,
vedgeb::AbstractFloat,
vuedgeb::AbstractFloat,
wedgeu::AbstractFloat,
coordinate::Cartesian,
state::State,
)::AbstractFloatPerform the transformation of a vertical-wind-like variable from the transformed system to the Cartesian one, given the wind-like components at the grid points surrounding $\left(i, j, k + 1 / 2\right)$, and return the result.
The discretized transformation rule for the vertical wind is given by
\[w_{k + 1 / 2} = J_{k + 1 / 2} \left[- \left(G^{1 3} u\right)_{k + 1 / 2} - \left(G^{2 3} v\right)_{k + 1 / 2} + \widehat{w}_{k + 1 / 2}\right].\]
transform(
i::Integer,
j::Integer,
k::Integer,
uedger::AbstractFloat,
uuedger::AbstractFloat,
uedgel::AbstractFloat,
uuedgel::AbstractFloat,
vedgef::AbstractFloat,
vuedgef::AbstractFloat,
vedgeb::AbstractFloat,
vuedgeb::AbstractFloat,
wedgeu::AbstractFloat,
coordinate::Transformed,
state::State,
)::AbstractFloatPerform the transformation of a vertical-wind-like variable from the Cartesian system to the transformed one, given the wind-like components at the grid points surrounding $\left(i, j, k + 1 / 2\right)$, and return the result.
The discretized transformation rule for the vertical wind is given by
\[\widehat{w}_{k + 1 / 2} = \left(G^{1 3} u\right)_{k + 1 / 2} + \left(G^{2 3} v\right)_{k + 1 / 2} + \frac{w_{k + 1 / 2}}{J_{k + 1 / 2}}.\]
Arguments
i: Zonal grid-cell index.j: Meridional grid-cell index.k: Vertical grid-cell index.uedger: Zonal-wind equivalent at $\left(i + 1 / 2, j, k\right)$.uuedger: Zonal-wind equivalent at $\left(i + 1 / 2, j, k + 1\right)$.uedgel: Zonal-wind equivalent at $\left(i - 1 / 2, j, k\right)$.uuedgel: Zonal-wind equivalent at $\left(i - 1 / 2, j, k + 1\right)$.vedgef: Meridional-wind equivalent at $\left(i, j + 1 / 2, k\right)$.vuedgef: Meridional-wind equivalent at $\left(i, j + 1 / 2, k + 1\right)$.vedgeb: Meridional-wind equivalent at $\left(i, j - 1 / 2, k\right)$.vuedgeb: Meridional-wind equivalent at $\left(i, j - 1 / 2, k + 1\right)$.wedgeu: Transformed-vertical-wind equivalent at $\left(i, j, k + 1 / 2\right)$coordinate: Coordinate system to transform to.state: Model state.
PinCFlow.Update.update! — Function
update!(state::State, dt::AbstractFloat, m::Integer, variable::Rho)Update the density if the atmosphere is not Boussinesq by dispatching to the appropriate method.
update!(
state::State,
dt::AbstractFloat,
m::Integer,
variable::Rho,
model::Boussinesq,
)Return in Boussinesq mode (the density is constant).
update!(
state::State,
dt::AbstractFloat,
m::Integer,
variable::Rho,
model::Union{PseudoIncompressible, Compressible},
)Update the density with a Runge-Kutta step on the left-hand side of the equation (the right-hand side is zero).
The update is given by
\[\begin{align*} q^\rho & \rightarrow - \frac{\Delta t}{J} \left(\frac{\mathcal{F}^{\rho, \widehat{x}}_{i + 1 / 2} - \mathcal{F}^{\rho, \widehat{x}}_{i - 1 / 2}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{\rho, \widehat{y}}_{j + 1 / 2} - \mathcal{F}^{\rho, \widehat{y}}_{j - 1 / 2}}{\Delta \widehat{y}} + \frac{\mathcal{F}^{\rho, \widehat{z}}_{k + 1 / 2} - \mathcal{F}^{\rho, \widehat{z}}_{k - 1 / 2}}{\Delta \widehat{z}}\right) + \alpha_\mathrm{RK} q^\rho,\\ \rho & \rightarrow \rho + \beta_\mathrm{RK} q^\rho, \end{align*}\]
where $\Delta t$ is the time step given as input to this method.
update!(state::State, dt::AbstractFloat, m::Integer, variable::RhoP, side::LHS)Update the density fluctuations with a Runge-Kutta step on the left-hand-side of the equation.
The update is given by
\[\begin{align*} q^{\rho'} & \rightarrow - \frac{\Delta t}{J} \left(\frac{\mathcal{F}^{\rho', \widehat{x}}_{i + 1 / 2} - \mathcal{F}^{\rho', \widehat{x}}_{i - 1 / 2}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{\rho', \widehat{y}}_{j + 1 / 2} - \mathcal{F}^{\rho', \widehat{y}}_{j - 1 / 2}}{\Delta \widehat{y}} + \frac{\mathcal{F}^{\rho', \widehat{z}}_{k + 1 / 2} - \mathcal{F}^{\rho', \widehat{z}}_{k - 1 / 2}}{\Delta \widehat{z}}\right) + \alpha_\mathrm{RK} q^{\rho'},\\ \rho' & \rightarrow \rho' + \beta_\mathrm{RK} q^{\rho'} \end{align*}\]
in Boussinesq/pseudo-incompressible mode and
\[\begin{align*} q^{\rho'} & \rightarrow \Delta t \left[- \frac{1}{J} \left(\frac{\mathcal{F}^{\rho', \widehat{x}}_{i + 1 / 2} - \mathcal{F}^{\rho', \widehat{x}}_{i - 1 / 2}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{\rho', \widehat{y}}_{j + 1 / 2} - \mathcal{F}^{\rho', \widehat{y}}_{j - 1 / 2}}{\Delta \widehat{y}} + \frac{\mathcal{F}^{\rho', \widehat{z}}_{k + 1 / 2} - \mathcal{F}^{\rho', \widehat{z}}_{k - 1 / 2}}{\Delta \widehat{z}}\right) + \frac{F^P}{\overline{\theta}}\right] + \alpha_\mathrm{RK} q^{\rho'},\\ \rho' & \rightarrow \rho' + \beta_\mathrm{RK} q^{\rho'} \end{align*}\]
in compressible mode.
update!(
state::State,
dt::AbstractFloat,
variable::RhoP,
side::RHS,
integration::Explicit,
)Update the density fluctuations with an explicit Euler step the on right-hand side of the equation, without the Rayleigh-damping term.
The update is given by
\[\rho' \rightarrow - \frac{\rho}{g} \left(b' - \Delta t N^2 \frac{\overline{\rho}}{\rho} w\right)\]
in Boussinesq/pseudo-incompressible mode and
\[\rho' \rightarrow - \frac{\rho}{g} \left[b' - \Delta t N^2 \frac{P / \overline{\theta}}{\rho} \left(\frac{W_{k + 1 / 2}}{\left(J P\right)_{k + 1 / 2}}\right)\right]\]
in compressible mode, where $b' = - g \rho' / \rho$.
update!(
state::State,
dt::AbstractFloat,
variable::RhoP,
side::RHS,
integration::Implicit,
rayleigh_factor::AbstractFloat,
)Update the density fluctuations with an implicit Euler step on the right-hand side of the equation.
The update is given by
\[\begin{align*} \rho' & \rightarrow - \frac{\rho}{g} \left[1 + \beta_\mathrm{R} \Delta t + \frac{\overline{\rho}}{\rho} \left(N \Delta t\right)^2\right]^{- 1}\\ & \quad \times \left\{- \frac{\overline{\rho}}{\rho} N^2 \Delta t J \left[\widehat{w}_\mathrm{old} + \Delta t \left(- \left(c_p \frac{P_{k + 1 / 2}}{\rho_{k + 1 / 2}} \mathcal{P}_{k + 1 / 2}^{\rho \widehat{w}}\right) + \left(\frac{F_{k + 1 / 2}^{\rho \widehat{w}}}{\rho_{k + 1 / 2}}\right)\right)\right] + \left(1 + \beta_\mathrm{R} \Delta t\right) b'\right.\\ & \qquad \quad + \left.\frac{\overline{\rho}}{\rho} N^2 \Delta t J \left(1 + \beta_\mathrm{R} \Delta t\right) \left(G^{13} u + G^{23} v\right)\vphantom{\left[\left(\frac{F_{k + 1 / 2}^{\rho \widehat{w}}}{\rho_{k + 1 / 2}}\right)\right]}\right\}, \end{align*}\]
in Boussinesq/pseudo-incompressible mode and
\[\begin{align*} \rho' & \rightarrow - \frac{\rho}{g} \left[1 + \beta_\mathrm{R} \Delta t + \frac{P / \overline{\theta}}{\rho} \left(N \Delta t\right)^2\right]^{- 1}\\ & \quad \times \left\{- \frac{P / \overline{\theta}}{\rho} N^2 \Delta t J \left[\left(\frac{\widehat{W}_{\mathrm{old}, k + 1 / 2}}{\left(J P\right)_{k + 1 / 2}}\right) + \Delta t \left(- \left(c_p \frac{P_{k + 1 / 2}}{\rho_{k + 1 / 2}} \mathcal{P}_{k + 1 / 2}^{\rho \widehat{w}}\right) + \left(\frac{F_{k + 1 / 2}^{\rho \widehat{w}}}{\rho_{k + 1 / 2}}\right)\right)\right]\right.\\ & \qquad \quad + \left(1 + \beta_\mathrm{R} \Delta t\right) b' + \frac{P / \overline{\theta}}{\rho} N^2 \Delta t J \left(1 + \beta_\mathrm{R} \Delta t\right)\\ & \qquad \quad \times \left.\left[G^{13} \left(\frac{U_{i + 1 / 2}}{\left(J P\right)_{i + 1 / 2}}\right) + G^{23} \left(\frac{V_{j + 1 / 2}}{\left(J P\right)_{j + 1 / 2}}\right)\right]\right\}, \end{align*}\]
in compressible mode, where $\widehat{w}_\mathrm{old}$ is the transformed vertical wind stored in state.variables.backups.
update!(state::State, dt::AbstractFloat, m::Integer, variable::U, side::LHS)Update the zonal momentum with a Runge-Kutta step on the left-hand side of the equation.
The update is given by
\[\begin{align*} q^{\rho u}_{i + 1 / 2} & \rightarrow \Delta t \left[- \frac{1}{J_{i + 1 / 2}} \left(\frac{\mathcal{F}^{\rho u, \widehat{x}}_{i + 1} - \mathcal{F}^{\rho u, \widehat{x}}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{\rho u, \widehat{y}}_{i + 1 / 2, j + 1 / 2} - \mathcal{F}^{\rho u, \widehat{y}}_{i + 1 / 2, j - 1 / 2}}{\Delta \widehat{y}}\right.\right.\\ & \qquad \qquad \qquad \qquad + \left.\left.\frac{\mathcal{F}^{\rho u, \widehat{z}}_{i + 1 / 2, k + 1 / 2} - \mathcal{F}^{\rho u, \widehat{z}}_{i + 1 / 2, k - 1 / 2}}{\Delta \widehat{z}}\right) + f \left(\rho_\mathrm{old} v\right)_{i + 1 / 2}\right] + \alpha_\mathrm{RK} q^{\rho u}_{i + 1 / 2},\\ u_{i + 1 / 2} & \rightarrow \rho_{i + 1 / 2}^{- 1} \left(\rho_{\mathrm{old}, i + 1 / 2} u_{i + 1 / 2} + \beta_\mathrm{RK} q^{\rho u}_{i + 1 / 2}\right), \end{align*}\]
where $\rho_\mathrm{old}$ is the density stored in state.variables.backups.
update!(
state::State,
dt::AbstractFloat,
variable::U,
side::RHS,
integration::Explicit,
)Update the zonal wind with an explicit Euler step on the right-hand side of the equation, without the Rayleigh-damping term.
The update is given by
\[u_{i + 1 / 2} \rightarrow u_{i + 1 / 2} + \Delta t \left(- c_p \frac{P_{i + 1 / 2}}{\rho_{i + 1 / 2}} \mathcal{P}_{i + 1 / 2}^{\rho u} + \frac{F_{i + 1 / 2}^{\rho u}}{\rho_{i + 1 / 2}}\right)\]
in Boussinesq/pseudo-incompressible mode and
\[U_{i + 1 / 2} \rightarrow U_{i + 1 / 2} + \Delta t \left(J P\right)_{i + 1 / 2} \left(- c_p \frac{P_{i + 1 / 2}}{\rho_{i + 1 / 2}} \mathcal{P}_{i + 1 / 2}^{\rho u} + \frac{F_{i + 1 / 2}^{\rho u}}{\rho_{i + 1 / 2}}\right)\]
in compressible mode.
update!(
state::State,
dt::AbstractFloat,
variable::U,
side::RHS,
integration::Implicit,
rayleigh_factor::AbstractFloat,
)Update the zonal wind with an implicit Euler step on the right-hand side of the equation.
The update is given by
\[u_{i + 1 / 2} \rightarrow \left(1 + \beta_{\mathrm{R}, i + 1 / 2} \Delta t\right)^{- 1} \left[u_{i + 1 / 2} + \Delta t \left(- c_p \frac{P_{i + 1 / 2}}{\rho_{i + 1 / 2}} \mathcal{P}_{i + 1 / 2}^{\rho u} + \frac{F_{i + 1 / 2}^{\rho u}}{\rho_{i + 1 / 2}}\right)\right]\]
in Boussinesq/pseudo-incompressible mode and
\[U_{i + 1 / 2} \rightarrow \left(1 + \beta_{\mathrm{R}, i + 1 / 2} \Delta t\right)^{- 1} \left[U_{i + 1 / 2} + \Delta t \left(J P\right)_{i + 1 / 2} \left(- c_p \frac{P_{i + 1 / 2}}{\rho_{i + 1 / 2}} \mathcal{P}_{i + 1 / 2}^{\rho u} + \frac{F_{i + 1 / 2}^{\rho u}}{\rho_{i + 1 / 2}}\right)\right]\]
in compressible mode.
update!(state::State, dt::AbstractFloat, m::Integer, variable::V, side::LHS)Update the meridional momentum with a Runge-Kutta step on the left-hand side of the equation.
The update is given by
\[\begin{align*} q^{\rho v}_{j + 1 / 2} & \rightarrow \Delta t \left[- \frac{1}{J_{j + 1 / 2}} \left(\frac{\mathcal{F}^{\rho v, \widehat{x}}_{i + 1 / 2, j + 1 / 2} - \mathcal{F}^{\rho v, \widehat{x}}_{i - 1 / 2, j + 1 / 2}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{\rho v, \widehat{y}}_{j + 1} - \mathcal{F}^{\rho v, \widehat{y}}}{\Delta \widehat{y}}\right.\right.\\ & \qquad \qquad \qquad \qquad + \left.\left.\frac{\mathcal{F}^{\rho v, \widehat{z}}_{j + 1 / 2, k + 1 / 2} - \mathcal{F}^{\rho v, \widehat{z}}_{j + 1 / 2, k - 1 / 2}}{\Delta \widehat{z}}\right) - f \left(\rho_\mathrm{old} u_\mathrm{old}\right)_{j + 1 / 2}\right] + \alpha_\mathrm{RK} q^{\rho v}_{j + 1 / 2},\\ v_{j + 1 / 2} & \rightarrow \rho_{j + 1 / 2}^{- 1} \left(\rho_{\mathrm{old}, j + 1 / 2} v_{j + 1 / 2} + \beta_\mathrm{RK} q^{\rho v}_{j + 1 / 2}\right), \end{align*}\]
where $\rho_\mathrm{old}$ and $u_{\mathrm{old}, i + 1 / 2}$ are the density and zonal wind stored in state.variables.backups.
update!(
state::State,
dt::AbstractFloat,
variable::V,
side::RHS,
integration::Explicit,
)Update the meridional wind with an explicit Euler step on the right-hand side of the equation, without the Rayleigh-damping term.
The update is given by
\[v_{i + 1 / 2} \rightarrow v_{j + 1 / 2} + \Delta t \left(- c_p \frac{P_{j + 1 / 2}}{\rho_{j + 1 / 2}} \mathcal{P}_{j + 1 / 2}^{\rho v} + \frac{F_{j + 1 / 2}^{\rho v}}{\rho_{j + 1 / 2}}\right)\]
in Boussinesq/pseudo-incompressible mode and
\[V_{j + 1 / 2} \rightarrow V_{j + 1 / 2} + \Delta t \left(J P\right)_{j + 1 / 2} \left(- c_p \frac{P_{j + 1 / 2}}{\rho_{j + 1 / 2}} \mathcal{P}_{j + 1 / 2}^{\rho v} + \frac{F_{j + 1 / 2}^{\rho v}}{\rho_{j + 1 / 2}}\right)\]
in compressible mode.
update!(
state::State,
dt::AbstractFloat,
variable::V,
side::RHS,
integration::Implicit,
rayleigh_factor::AbstractFloat,
)Update the meridional wind with an implicit Euler step on the right-hand side of the equation.
The update is given by
\[v_{j + 1 / 2} \rightarrow \left(1 + \beta_{\mathrm{R}, j + 1 / 2} \Delta t\right)^{- 1} \left[v_{j + 1 / 2} + \Delta t \left(- c_p \frac{P_{j + 1 / 2}}{\rho_{j + 1 / 2}} \mathcal{P}_{j + 1 / 2}^{\rho v} + \frac{F_{j + 1 / 2}^{\rho v}}{\rho_{j + 1 / 2}}\right)\right]\]
in Boussinesq/pseudo-incompressible mode and
\[V_{j + 1 / 2} \rightarrow \left(1 + \beta_{\mathrm{R}, j + 1 / 2} \Delta t\right)^{- 1} \left[V_{j + 1 / 2} + \Delta t \left(J P\right)_{j + 1 / 2} \left(- c_p \frac{P_{j + 1 / 2}}{\rho_{j + 1 / 2}} \mathcal{P}_{j + 1 / 2}^{\rho v} + \frac{F_{j + 1 / 2}^{\rho v}}{\rho_{j + 1 / 2}}\right)\right]\]
in compressible mode.
update!(state::State, dt::AbstractFloat, m::Integer, variable::W, side::LHS)Update the transformed vertical momentum with a Runge-Kutta step on the left-hand side of the equation.
The update is given by
\[\begin{align*} q^{\rho \widehat{w}}_{k + 1 / 2} & \rightarrow \Delta t \left\{- \left[G^{13} \left(\frac{1}{J_{i + 1 / 2}} \left(\frac{\mathcal{F}^{\rho u, \widehat{x}}_{i + 1} - \mathcal{F}^{\rho u, \widehat{x}}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{\rho u, \widehat{y}}_{i + 1 / 2, j + 1 / 2} - \mathcal{F}^{\rho u, \widehat{y}}_{i + 1 / 2, j - 1 / 2}}{\Delta \widehat{y}}\right.\right.\right.\right.\\ & \qquad \qquad \qquad \qquad \qquad \qquad + \left.\left.\left.\frac{\mathcal{F}^{\rho u, \widehat{z}}_{i + 1 / 2, k + 1 / 2} - \mathcal{F}^{\rho u, \widehat{z}}_{i + 1 / 2, k - 1 / 2}}{\Delta \widehat{z}}\right)\right)\right]_{k + 1 / 2}\\ & \qquad \qquad - \left[G^{23} \left(\frac{1}{J_{j + 1 / 2}} \left(\frac{\mathcal{F}^{\rho v, \widehat{x}}_{i + 1 / 2, j + 1 / 2} - \mathcal{F}^{\rho v, \widehat{x}}_{i - 1 / 2, j + 1 / 2}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{\rho v, \widehat{y}}_{j + 1} - \mathcal{F}^{\rho v, \widehat{y}}}{\Delta \widehat{y}}\right.\right.\right.\\ & \qquad \qquad \qquad \qquad \qquad \qquad + \left.\left.\left.\frac{\mathcal{F}^{\rho v, \widehat{z}}_{j + 1 / 2, k + 1 / 2} - \mathcal{F}^{\rho v, \widehat{z}}_{j + 1 / 2, k - 1 / 2}}{\Delta \widehat{z}}\right)\right)\right]_{k + 1 / 2}\\ & \qquad \qquad - \frac{1}{J_{k + 1 / 2}^2} \left(\frac{\mathcal{F}^{\rho w, \widehat{x}}_{i + 1 / 2, k + 1 / 2} - \mathcal{F}^{\rho w, \widehat{x}}_{i - 1 / 2, k + 1 / 2}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{\rho w, \widehat{y}}_{j + 1 / 2, k + 1 / 2} - \mathcal{F}^{\rho w, \widehat{y}}_{j - 1 / 2, k + 1 / 2}}{\Delta \widehat{y}}\right.\\ & \qquad \qquad \qquad \qquad \quad + \left.\frac{\mathcal{F}^{\rho w, \widehat{z}}_{k + 1} - \mathcal{F}^{\rho w, \widehat{z}}}{\Delta \widehat{z}}\right)\\ & \qquad \qquad + \left.G^{13} f \left(\rho_\mathrm{old} v_\mathrm{old}\right)_{k + 1 / 2} - G^{23} f \left(\rho_\mathrm{old} u_\mathrm{old}\right)_{k + 1 / 2}\vphantom{- \frac{1}{J^2} \left(\frac{\mathcal{F}^{\rho w, \widehat{z}}_{k + 1} - \mathcal{F}^{\rho w, \widehat{z}}}{\Delta \widehat{z}}\right)}\right\} + \alpha_\mathrm{RK} q^{\rho \widehat{w}}_{k + 1 / 2},\\ \widehat{w}_{k + 1 / 2} & \rightarrow \rho_{k + 1 / 2}^{- 1} \left(\rho_{\mathrm{old}, k + 1 / 2} \widehat{w}_{k + 1 / 2} + \beta_\mathrm{RK} q^{\rho \widehat{w}}_{k + 1 / 2}\right), \end{align*}\]
where $\rho_\mathrm{old}$, $u_{\mathrm{old}, i + 1 / 2}$ and $v_{\mathrm{old}, j + 1 / 2}$ are the density, zonal wind and meridional wind stored in state.variables.backups.
update!(
state::State,
dt::AbstractFloat,
variable::W,
side::RHS,
integration::Explicit,
)Update the transformed vertical wind with an explicit Euler step on the right-hand side of the equation, without the Rayleigh-damping term.
The update is given by
\[\widehat{w}_{k + 1 / 2} \rightarrow \widehat{w}_{k + 1 / 2} + \Delta t \left[- c_p \frac{P_{k + 1 / 2}}{\rho_{k + 1 / 2}} \mathcal{P}_{k + 1 / 2}^{\rho \widehat{w}} + \left(\frac{b'_\mathrm{old}}{J}\right)_{k + 1 / 2} + \frac{F_{k + 1 / 2}^{\rho \widehat{w}}}{\rho_{k + 1 / 2}}\right]\]
in Boussinesq/pseudo-incompressible mode and
\[\widehat{W}_{k + 1 / 2} \rightarrow \widehat{W}_{k + 1 / 2} + \Delta t \left(J P\right)_{k + 1 / 2} \left[- c_p \frac{P_{k + 1 / 2}}{\rho_{k + 1 / 2}} \mathcal{P}_{k + 1 / 2}^{\rho \widehat{w}} + \left(\frac{b'_\mathrm{old}}{J}\right)_{k + 1 / 2} + \frac{F_{k + 1 / 2}^{\rho \widehat{w}}}{\rho_{k + 1 / 2}}\right]\]
in compressible mode, where $b'_\mathrm{old} = - g \rho'_\mathrm{old} / \rho$, with $\rho'_\mathrm{old}$ being the density fluctuations stored in state.variables.backups.
update!(
state::State,
dt::AbstractFloat,
variable::W,
side::RHS,
integration::Implicit,
rayleigh_factor::AbstractFloat,
)Update the transformed vertical wind with an implicit Euler step on the right-hand side of the equation.
The update is given by
\[\begin{align*} \widehat{w}_{k + 1 / 2} & \rightarrow \left[1 + \beta_{\mathrm{R}, k + 1 / 2} \Delta t + \frac{\overline{\rho}_{k + 1 / 2}}{\rho_{k + 1 / 2}} N^2_{k + 1 / 2} \left(\Delta t\right)^2\right]^{- 1}\\ & \quad \times \left\{\widehat{w}_{k + 1 / 2} + \Delta t \left(- c_p \frac{P_{k + 1 / 2}}{\rho_{k + 1 / 2}} \mathcal{P}_{k + 1 / 2}^{\rho \widehat{w}} + \left(\frac{b'}{J}\right)_{k + 1 / 2} + \frac{F_{k + 1 / 2}^{\rho \widehat{w}}}{\rho_{k + 1 / 2}}\right)\right.\\ & \qquad \quad + \left.\frac{\overline{\rho}_{k + 1 / 2}}{\rho_{k + 1 / 2}} N^2_{k + 1 / 2} \left(\Delta t\right)^2 \left[\left(G^{13} u\right)_{k + 1 / 2} + \left(G^{2 3} v\right)_{k + 1 / 2}\right]\vphantom{\left(\frac{F_{k + 1 / 2}^{\rho \widehat{w}}}{\rho_{k + 1 / 2}}\right)}\right\} \end{align*}\]
in Boussinesq/pseudo-incompressible mode and
\[\begin{align*} \widehat{W}_{k + 1 / 2} & \rightarrow \left[1 + \beta_{\mathrm{R}, k + 1 / 2} \Delta t + \frac{\left(P / \overline{\theta}\right)_{k + 1 / 2}}{\rho_{k + 1 / 2}} N^2_{k + 1 / 2} \left(\Delta t\right)^2\right]^{- 1}\\ & \quad \times \left\{\widehat{W}_{k + 1 / 2} + \Delta t \left(J P\right)_{k + 1 / 2} \left(- c_p \frac{P_{k + 1 / 2}}{\rho_{k + 1 / 2}} \mathcal{P}_{k + 1 / 2}^{\rho \widehat{w}} + \left(\frac{b'}{J}\right)_{k + 1 / 2} + \frac{F_{k + 1 / 2}^{\rho \widehat{w}}}{\rho_{k + 1 / 2}}\right)\right.\\ & \qquad \quad + \left(J P\right)_{k + 1 / 2} \frac{\left(P / \overline{\theta}\right)_{k + 1 / 2}}{\rho_{k + 1 / 2}} N^2_{k + 1 / 2} \left(\Delta t\right)^2\\ & \qquad \quad \times \left.\left[\left(G^{13} \left(\frac{U_{i + 1 / 2}}{\left(J P\right)_{i + 1 / 2}}\right)\right)_{k + 1 / 2} + \left(G^{2 3} \left(\frac{V_{j + 1 / 2}}{\left(J P\right)_{j + 1 / 2}}\right)\right)_{k + 1 / 2}\right]\vphantom{\left(\frac{F_{k + 1 / 2}^{\rho \widehat{w}}}{\rho_{k + 1 / 2}}\right)}\right\} \end{align*}\]
in compressible mode.
update!(state::State, dt::AbstractFloat, variable::PiP)Update the Exner-pressure if the atmosphere is compressible by dispatching to the appropriate method.
update!(
state::State,
dt::AbstractFloat,
variable::PiP,
model::Union{Boussinesq, PseudoIncompressible},
)Return in non-compressible modes.
update!(state::State, dt::AbstractFloat, variable::PiP, model::Compressible)Update the Exner-pressure such that it is synchronized with the updated mass-weighted potential temperature.
The update is given by
\[\begin{align*} \pi' & \rightarrow \pi' + \Delta t \left(\frac{\partial \pi'}{\partial P}\right) \left[- \frac{1}{J} \left(\frac{U_{\mathrm{old}, i + 1 / 2} - U_{\mathrm{old}, i - 1 / 2}}{\Delta \widehat{x}} + \frac{V_{\mathrm{old}, j + 1 / 2} - V_{\mathrm{old}, j - 1 / 2}}{\Delta \widehat{y}}\right.\right.\\ & \qquad \qquad \qquad \qquad \qquad \qquad + \left.\left.\frac{\widehat{W}_{\mathrm{old}, k + 1 / 2} - \widehat{W}_{\mathrm{old}, k - 1 / 2}}{\Delta \widehat{z}}\right) + F^P\right], \end{align*}\]
where $U_{\mathrm{old}, i + 1 / 2}$, $V_{\mathrm{old}, j + 1 / 2}$ and $\widehat{W}_{\mathrm{old}, k + 1 / 2}$ are the transformed wind components (including the factor $J P$) stored in state.variables.backups.
update!(state::State, dt::AbstractFloat, m::Integer, variable::P)Update the mass-weighted potential temperature if the atmosphere is compressible by dispatching to the appropriate method.
update!(
state::State,
dt::AbstractFloat,
m::Integer,
variable::P,
model::Union{Boussinesq, PseudoIncompressible},
)Return in non-compressible modes.
update!(
state::State,
dt::AbstractFloat,
m::Integer,
variable::P,
model::Compressible,
)Update the mass-weighted potential temperature with a Runge-Kutta step on the left-hand side of the equation (the right-hand side is zero).
The update is given by
\[\begin{align*} q^P & \rightarrow \Delta t \left[- \frac{1}{J} \left(\frac{\mathcal{F}^{P, \widehat{x}}_{i + 1 / 2} - \mathcal{F}^{P, \widehat{x}}_{i - 1 / 2}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{P, \widehat{y}}_{j + 1 / 2} - \mathcal{F}^{P, \widehat{y}}_{j - 1 / 2}}{\Delta \widehat{y}} + \frac{\mathcal{F}^{P, \widehat{z}}_{k + 1 / 2} - \mathcal{F}^{P, \widehat{z}}_{k - 1 / 2}}{\Delta \widehat{z}}\right) + F^P\right] + \alpha_\mathrm{RK} q^P,\\ P & \rightarrow P + \beta_\mathrm{RK} q^P. \end{align*}\]
update!(state::State, dt::AbstractFloat, m::Integer, tracer_setup::NoTracer)Return for configurations without tracer transport.
update!(state::State, dt::AbstractFloat, m::Integer, tracer_setup::TracerOn)Update the tracers with a Runge-Kutta step on the left-hand sides of the equations with WKB right-hand side terms according to namelists configuration.
The update is given by
\[\begin{align*} q^{\rho \chi} & \rightarrow \Delta t \left[- \frac{1}{J} \left(\frac{\mathcal{F}^{\rho \chi, \widehat{x}}_{i + 1 / 2} - \mathcal{F}^{\rho \chi, \widehat{x}}_{i - 1 / 2}}{\Delta \widehat{x}} + \frac{\mathcal{F}^{\rho \chi, \widehat{y}}_{j + 1 / 2} - \mathcal{F}^{\rho \chi, \widehat{y}}_{j - 1 / 2}}{\Delta \widehat{y}} + \frac{\mathcal{F}^{\rho \chi, \widehat{z}}_{k + 1 / 2} - \mathcal{F}^{\rho \chi, \widehat{z}}_{k - 1 / 2}}{\Delta \widehat{z}}\right) + F^{\rho \chi}\right] + \alpha_\mathrm{RK} q^{\rho \chi},\\ \left(\rho \chi\right) & \rightarrow \left(\rho \chi\right) + \beta_\mathrm{RK} q^{\rho \chi}. \end{align*}\]
Arguments
state: Model state.dt: Time step.m: Runge-Kutta-stage index.variable: Variable to update.model: Dynamic equations.side: Side of the equation.integration: Type of the Euler step.rayleigh_factor: Factor by which the Rayleigh-damping coefficient is multiplied.tracer_setup: General tracer-transport configuration.
See also