zoomy_core.model.models.equations

zoomy_core.model.models.equations#

Balance-equation blueprints (Mass, Momentum, MomentumNonHydrostatic, Transport) that declare their state/closure variables and add their residual to a derivation Model, plus the tracked scaling steps applied to them. They feed the SME/VAM derivations, before the Model is lifted to a SystemModel.

Module Contents#

Classes#

Equation

Base balance blueprint: add_to(model) declares variables and adds the residual, and model.add_equation(blueprint) dispatches to it.

Mass

Incompressible mass balance sum_d d_d u_d + d_z w = 0; registers the horizontal velocities and w as state.

Momentum

General 3-D momentum balance with the full symmetric stress tensor tau_ij declared as closure variables (in every row, the vertical one included) and the pressure p as state. The shallow simplification is not built in; it is applied explicitly by moment_scaling.

Stress

How much of the bulk closure’s deviatoric stress a moment model keeps; the rule is applied by moment_scaling, per component, in physical coordinates before the sigma map.

MomentumNonHydrostatic

Non-hydrostatic momentum with the hydrostatic pressure pre-absorbed: horizontal rows momentum_<d> carry g d_d(eta) and p is only the non-hydrostatic part of -sigma_zz, and the vertical row momentum_z keeps d_z p; the full stress tensor is declared, the shallow form is applied by moment_scaling.

Transport

Conservative transport of a scalar field name, d_t c + sum_d d_d(u_d c) + d_z(w c) = source, registered as a state field (TKE, dissipation, tracer, …).

Functions#

evaluate_time_derivatives

.doit() only the Subs atoms and the derivatives carrying t of a residual, keeping every purely spatial flux divergence d_x(F) folded so it stays in the flux slot.

gravity_components

Gravity body-force vector per spatial direction, the single gravity path of every momentum blueprint (flat plane is e_d = 0).

moment_scaling

Stress scaling step of the moment models: Stress.shallow drops, from the full-tensor blueprint momentum, the in-plane stresses tau_de, tau_zz and the stress of the vertical row; Stress.full keeps everything. The choice is recorded as model.stress, which the bulk closure reads for the d_e w part of tau_ez (apply_stress_closures).

package_viscous

Route a retained viscous residual into conservative diffusion by rewriting C d_d d_e Q as d_d(C d_e Q) - (d_d C) d_e Q with the diffusive flux wrapped in a ViscousDiffusion marker; non-viscous terms pass through.

frame_slope

Opaque geometric-slope symbol of a boundary interface (tag is "b" or "eta") in horizontal direction "x" or "y", distinct from the physical d_d(interface).

small_slope_scaling

Tracked step resolving the opaque boundary frame to its small-slope limit (every frame_slope symbol to 0, n -> z_hat); skip it to keep the slope-aware tractions. Geometric sibling of moment_scaling; together they give the shallow-moment form.

slope_aware_scaling

Complement of small_slope_scaling: resolve each frame_slope symbol to the physical interface slope d_dir(interface), so the geometrically exact model has no opaque symbol left.

API#

zoomy_core.model.models.equations.evaluate_time_derivatives(expr, t)#

.doit() only the Subs atoms and the derivatives carrying t of a residual, keeping every purely spatial flux divergence d_x(F) folded so it stays in the flux slot.

class zoomy_core.model.models.equations.Equation(model=None)#

Base balance blueprint: add_to(model) declares variables and adds the residual, and model.add_equation(blueprint) dispatches to it.

Initialization

Store the (optional) model the blueprint is attached to.

abstract add_to(model)#

Declare variables and add the residual to model; implemented by subclasses.

class zoomy_core.model.models.equations.Mass(model=None, suffix='')#

Bases: zoomy_core.model.models.equations.Equation

Incompressible mass balance sum_d d_d u_d + d_z w = 0; registers the horizontal velocities and w as state.

Args

  • suffix: scopes the field names for a multilayer column ("_1" gives u_1, w_1).

Initialization

Store the model and the field-name suffix.

add_to(model)#

Declare u (v) and w as state and add the mass equation; returns it.

zoomy_core.model.models.equations.gravity_components(model, coords)#

Gravity body-force vector per spatial direction, the single gravity path of every momentum blueprint (flat plane is e_d = 0).

Returns

(g_h, g_z): in-plane component per horizontal coordinate (downslope g e_x along x, else 0) and the normal component -g.

class zoomy_core.model.models.equations.Momentum(model=None)#

Bases: zoomy_core.model.models.equations.Equation

General 3-D momentum balance with the full symmetric stress tensor tau_ij declared as closure variables (in every row, the vertical one included) and the pressure p as state. The shallow simplification is not built in; it is applied explicitly by moment_scaling.

Initialization

Store the (optional) model the blueprint is attached to.

add_to(model)#

Declare p and the stress components, and add the momentum equation (horizontal rows plus the vertical row); returns it.

class zoomy_core.model.models.equations.Stress#

Bases: zoomy_core.misc.options.Option

How much of the bulk closure’s deviatoric stress a moment model keeps; the rule is applied by moment_scaling, per component, in physical coordinates before the sigma map.

Initialization

Initialize self. See help(type(self)) for accurate signature.

shallow#

‘shallow’

full#

‘full’

zoomy_core.model.models.equations.moment_scaling(model, momentum, stress=Stress.shallow)#

Stress scaling step of the moment models: Stress.shallow drops, from the full-tensor blueprint momentum, the in-plane stresses tau_de, tau_zz and the stress of the vertical row; Stress.full keeps everything. The choice is recorded as model.stress, which the bulk closure reads for the d_e w part of tau_ez (apply_stress_closures).

zoomy_core.model.models.equations.package_viscous(expr, nu, states, space)#

Route a retained viscous residual into conservative diffusion by rewriting C d_d d_e Q as d_d(C d_e Q) - (d_d C) d_e Q with the diffusive flux wrapped in a ViscousDiffusion marker; non-viscous terms pass through.

Args

  • expr: projected residual.

  • nu: viscosity symbol identifying the viscous terms.

  • states: state functions Q that may carry second derivatives.

  • space: spatial coordinates d, e.

Returns

The residual with the viscous part in divergence form.

zoomy_core.model.models.equations.frame_slope(tag, direction)#

Opaque geometric-slope symbol of a boundary interface (tag is "b" or "eta") in horizontal direction "x" or "y", distinct from the physical d_d(interface).

zoomy_core.model.models.equations.small_slope_scaling(model)#

Tracked step resolving the opaque boundary frame to its small-slope limit (every frame_slope symbol to 0, n -> z_hat); skip it to keep the slope-aware tractions. Geometric sibling of moment_scaling; together they give the shallow-moment form.

zoomy_core.model.models.equations.slope_aware_scaling(model, interfaces)#

Complement of small_slope_scaling: resolve each frame_slope symbol to the physical interface slope d_dir(interface), so the geometrically exact model has no opaque symbol left.

Args

  • interfaces: map from frame tag to height expression, e.g. {"b": b, "eta": b + h}.

class zoomy_core.model.models.equations.MomentumNonHydrostatic(model=None, suffix='', tau_name='tau_xz', free_surface=None)#

Bases: zoomy_core.model.models.equations.Equation

Non-hydrostatic momentum with the hydrostatic pressure pre-absorbed: horizontal rows momentum_<d> carry g d_d(eta) and p is only the non-hydrostatic part of -sigma_zz, and the vertical row momentum_z keeps d_z p; the full stress tensor is declared, the shallow form is applied by moment_scaling.

Args

  • suffix: scopes the field names (multilayer column).

  • tau_name: stress field name for one horizontal direction (default tau_xz).

  • free_surface: overrides eta (default b + h).

References

  • Escalante et al. 2024, https://doi.org/10.1016/j.jcp.2024.112882

Initialization

Store the field-name suffix, the stress name and the optional free-surface override.

add_to(model)#

Declare p and the stress tensor (one shear stress per horizontal direction, the in-plane tau_de and tau_zz) and add the momentum_x (momentum_y) and momentum_z equations.

class zoomy_core.model.models.equations.Transport(model=None, name='c', source=None)#

Bases: zoomy_core.model.models.equations.Equation

Conservative transport of a scalar field name, d_t c + sum_d d_d(u_d c) + d_z(w c) = source, registered as a state field (TKE, dissipation, tracer, …).

Args

  • source: optional source field or expression; None for a passive scalar.

Initialization

Store the field name and the optional source.

add_to(model)#

Declare the scalar as state and add its transport equation; returns it.