zoomy_core.numerics.numerical_system_model

zoomy_core.numerics.numerical_system_model#

NumericalSystemModel: a SystemModel plus the numerics (Riemann solver, reconstruction, diffusion scheme, regularization, kernels table) that the solver templates consume. Pipeline: Model -> SystemModel -> NumericalSystemModel -> solver template -> backend runtime.

Module Contents#

Classes#

Limiter

Slope limiter of the order-2 reconstruction.

ReconstructedVariables

What the symbolic solvers reconstruct.

BedReconstruction

The bed’s face value with the model’s free-surface map (bed b, eta = b + h).

ReconstructionSpec

Face-state reconstruction configuration: order 1 (piecewise constant) or 2 (LSQ-MUSCL with limiter) and free_surface_aware wet/dry handling.

DiffusionSpec

Diffusion configuration: enabled (auto-False when diffusion_matrix is zero), time scheme and nu overriding sm.parameter_values['nu'].

NumericalSystemModel

SystemModel subclass that adds the numerics the solver templates consume: Riemann class, reconstruction, diffusion, regularization and extra_operations. Build it with from_system_model, which works on a numerical twin of the system; the BoundaryConditions container stays at _bc_source.

Functions#

construct_numerical

Build the numerical twin of sm: a deep copy whose state and aux symbols carry no sign assumptions, so sympy cannot delete a numerical guard as a tautology. This is the SystemModel -> NumericalSystemModel boundary; the caller’s sm keeps its assumptions.

assert_no_assumptions

Raise unless no state or aux symbol of the built object carries a sign predicate.

numerics_fluctuations_are_zero

True only if the built numerical_fluctuations of numerics is proven structurally zero; unknown counts as nonzero. It reads the built face kernel, not the model’s nonconservative_matrix.

operator_is_zero

True if operator arr is structurally zero (absent, empty or every entry proven zero), so a backend may skip evaluating it.

operator_zero_flags

{flag_name: bool} for every slot of OPERATOR_ZERO_FLAGS, read off sm with operator_is_zero so printers can loop.

implicit_stage_mode

Which implicit-stage path nsm needs: "coupled" (live implicit diffusion, or an implicit source reading a non-local aux), "local_source" (cell-local fast path) or "none". Derived from the operators, so a model with both implicit diffusion and source gives one coupled stage.

to_numerical_system_model

Coerce a Model, SystemModel or NSM to a NumericalSystemModel, the single front door of the core code printers; other types raise TypeError.

Data#

API#

class zoomy_core.numerics.numerical_system_model.Limiter#

Bases: zoomy_core.misc.options.Option

Slope limiter of the order-2 reconstruction.

Initialization

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

none#

‘none’

minmod#

‘minmod’

venkatakrishnan#

‘venkatakrishnan’

barth_jespersen#

‘barth_jespersen’

class zoomy_core.numerics.numerical_system_model.ReconstructedVariables#

Bases: zoomy_core.misc.options.Option

What the symbolic solvers reconstruct.

Initialization

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

model#

‘model’

conservative#

‘conservative’

class zoomy_core.numerics.numerical_system_model.BedReconstruction#

Bases: zoomy_core.misc.options.Option

The bed’s face value with the model’s free-surface map (bed b, eta = b + h).

Initialization

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

derived#

‘derived’

reconstructed#

‘reconstructed’

zoomy_core.numerics.numerical_system_model.construct_numerical(sm)#

Build the numerical twin of sm: a deep copy whose state and aux symbols carry no sign assumptions, so sympy cannot delete a numerical guard as a tautology. This is the SystemModel -> NumericalSystemModel boundary; the caller’s sm keeps its assumptions.

zoomy_core.numerics.numerical_system_model.assert_no_assumptions(sm) → None#

Raise unless no state or aux symbol of the built object carries a sign predicate.

zoomy_core.numerics.numerical_system_model.numerics_fluctuations_are_zero(numerics) → bool#

True only if the built numerical_fluctuations of numerics is proven structurally zero; unknown counts as nonzero. It reads the built face kernel, not the model’s nonconservative_matrix.

zoomy_core.numerics.numerical_system_model.IMPLICIT_MODE_NONE#

‘none’

zoomy_core.numerics.numerical_system_model.IMPLICIT_MODE_LOCAL_SOURCE#

‘local_source’

zoomy_core.numerics.numerical_system_model.IMPLICIT_MODE_COUPLED#

‘coupled’

zoomy_core.numerics.numerical_system_model.OPERATOR_ZERO_FLAGS#

None

zoomy_core.numerics.numerical_system_model.operator_is_zero(arr) → bool#

True if operator arr is structurally zero (absent, empty or every entry proven zero), so a backend may skip evaluating it.

zoomy_core.numerics.numerical_system_model.operator_zero_flags(sm) → dict#

{flag_name: bool} for every slot of OPERATOR_ZERO_FLAGS, read off sm with operator_is_zero so printers can loop.

zoomy_core.numerics.numerical_system_model.implicit_stage_mode(nsm) → str#

Which implicit-stage path nsm needs: "coupled" (live implicit diffusion, or an implicit source reading a non-local aux), "local_source" (cell-local fast path) or "none". Derived from the operators, so a model with both implicit diffusion and source gives one coupled stage.

References

  • Kennedy, Carpenter 2003, https://doi.org/10.1016/s0168-9274(02)00138-1

class zoomy_core.numerics.numerical_system_model.ReconstructionSpec#

Face-state reconstruction configuration: order 1 (piecewise constant) or 2 (LSQ-MUSCL with limiter) and free_surface_aware wet/dry handling.

Positivity on the symbolic solvers (zoomy_core.symsolver) is the hydrostatic reconstruction and the CFL step at order 1, MOOD (the solver’s mood) at order 2; positivity is read by the legacy zoomy_core.fvm solvers only and the symbolic solvers reject a non-empty value.

References

  • van Leer 1979, https://doi.org/10.1016/0021-9991(79)90145-1

  • Mavriplis 2003, https://doi.org/10.2514/6.2003-3986

  • Clain, Diot, Loubere 2011, https://doi.org/10.1016/j.jcp.2011.02.026

  • Venkatakrishnan 1995, https://doi.org/10.1006/jcph.1995.1084

order: int#

1

limiter: zoomy_core.numerics.numerical_system_model.Limiter#

None

free_surface_aware: bool#

False

positivity: str = <Multiline-String>#
variables: zoomy_core.numerics.numerical_system_model.ReconstructedVariables#

None

bed: zoomy_core.numerics.numerical_system_model.BedReconstruction#

None

limiters: dict#

‘field(…)’

ties: dict#

‘field(…)’

class zoomy_core.numerics.numerical_system_model.DiffusionSpec#

Diffusion configuration: enabled (auto-False when diffusion_matrix is zero), time scheme and nu overriding sm.parameter_values['nu'].

enabled: bool#

True

scheme: str#

‘crank_nicolson’

nu: Optional[float]#

None

class zoomy_core.numerics.numerical_system_model.NumericalSystemModel#

Bases: zoomy_core.systemmodel.system_model.SystemModel

SystemModel subclass that adds the numerics the solver templates consume: Riemann class, reconstruction, diffusion, regularization and extra_operations. Build it with from_system_model, which works on a numerical twin of the system; the BoundaryConditions container stays at _bc_source.

References

  • Rusanov 1962, https://doi.org/10.1016/0041-5553(62)90062-9

  • Pares 2006, https://doi.org/10.1137/050628052

riemann: Optional[Type[Any]]#

None

riemann_explicit: bool#

False

reconstruction: zoomy_core.numerics.numerical_system_model.ReconstructionSpec#

‘field(…)’

diffusion: zoomy_core.numerics.numerical_system_model.DiffusionSpec#

‘field(…)’

eigenvalue_eps: float#

1e-08

dt_max: float#

5.0

depth_round_off: Optional[float]#

1e-12

extra_operations: list#

‘field(…)’

source_derivative_specs: Optional[list]#

None

additional_systems: list#

‘field(…)’

scaled_q_indices: Optional[list]#

None

source_treatment: str#

‘explicit’

depth_regularization: Optional[str]#

None

regularization_eps: float#

0.01

eigenvalue_treatment: str#

‘regularize’

eigenvalue_guard: Optional[str]#

‘gate’

normalize_normal: bool#

True

property sm: zoomy_core.systemmodel.system_model.SystemModel#

Return self, keeping the historical nsm.sm.<x> access working.

property fluctuations_are_zero: bool#

True iff the built numerical_fluctuations is structurally zero, i.e. no fluctuation term is emitted. It depends on the (model x Riemann solver x current representation) triple and is re-read on every access.

property implicit_mode: str#

Implicit-stage path this system needs ("none", "local_source", "coupled"), re-read from the operators on every access; see implicit_stage_mode.

References

  • Kennedy, Carpenter 2003, https://doi.org/10.1016/s0168-9274(02)00138-1

property operators_are_zero: dict#

{flag_name: bool} of the structural-zero flag of every operator slot (see operator_is_zero), re-read on every access.

property flux_is_zero: bool#

True iff flux is structurally zero.

property hydrostatic_pressure_is_zero: bool#

True iff hydrostatic_pressure is structurally zero (hand-built SWE keeps g h^2/2 in flux instead).

property nonconservative_matrix_is_zero: bool#

True iff the model’s nonconservative_matrix is structurally zero; not the same as fluctuations_are_zero, which reads the built face kernel.

property eigenvalues_are_zero: bool#

True iff eigenvalues is structurally zero, i.e. no hyperbolic transport.

property source_is_zero: bool#

True iff the implicit source is structurally zero.

property source_explicit_is_zero: bool#

True iff source_explicit is structurally zero.

property diffusion_matrix_is_zero: bool#

True iff the implicit diffusion_matrix is structurally zero, so a backend may skip building its diffusion operator.

property diffusion_matrix_explicit_is_zero: bool#

True iff diffusion_matrix_explicit is structurally zero.

default_operations() → list#

Operations derive applies to every NSM before extra_operations, in load-bearing order: face-normal normalization, the selected depth regularization, then the eigenvalue guard. Only shallow-water transport systems (depth state h, flux or NCP) get the Kurganov-Petrova desingularization.

References

  • Kurganov, Petrova 2007, https://doi.org/10.4310/CMS.2007.v5.n1.a6

derive() → zoomy_core.numerics.numerical_system_model.NumericalSystemModel#

Run default_operations() + extra_operations on this NSM in place via SystemModel.apply; returns self.

apply(operation, *, name=None, description=None)#

Apply a system operation, then refresh every Numerics already built from this NSM so its registered functions see the new operators.

classmethod from_model(model, **kwargs) → zoomy_core.numerics.numerical_system_model.NumericalSystemModel#

Shortcut for from_system_model(SystemModel.from_model(model), **kwargs).

classmethod from_system_model(sm, *, riemann=None, reconstruction: Optional[zoomy_core.numerics.numerical_system_model.ReconstructionSpec] = None, diffusion: Optional[zoomy_core.numerics.numerical_system_model.DiffusionSpec] = None, eigenvalue_eps: float = 1e-08, dt_max: float = 5.0, depth_round_off: Optional[float] = 1e-12, tag_rules: Optional[dict] = None, extra_operations: Optional[list] = None, additional_systems: Optional[list] = None, scaled_q_indices: Optional[list] = None, source_treatment: str = 'explicit', depth_regularization: Optional[str] = None, regularization_eps: float = 0.01, eigenvalue_treatment: str = 'regularize', eigenvalue_guard: Optional[str] = 'gate', normalize_normal: bool = True) → zoomy_core.numerics.numerical_system_model.NumericalSystemModel#

Build an NSM from a SystemModel (or a Model, auto-promoted) on its numerical twin, resolving the numerics defaults and running derive.

Args

  • riemann: Riemann class; defaults to the tag rule, else NonconservativeRusanov.

  • reconstruction: ReconstructionSpec; defaults to first order.

  • diffusion: DiffusionSpec; enabled iff diffusion_matrix is nonzero.

  • eigenvalue_eps: regularization of the numerical eigensolve.

  • dt_max: timestep cap shared by all backends.

  • tag_rules: per-call override of the tag -> numerics defaults.

  • extra_operations: opt-in operations run by derive.

  • additional_systems: co-running sub-systems whose derivatives size the LSQ stencil.

  • scaled_q_indices: rows a hydrostatic reconstruction rescales by h*/h.

  • source_treatment: "explicit" or "linearized" (point-implicit).

  • depth_regularization, regularization_eps, eigenvalue_treatment, eigenvalue_guard, normalize_normal: depth-law axes, see depth_law_study.

Returns

The derived NSM; the LSQ degree is always auto-derived.

resolved_lsq_degree() → int#

LSQ polynomial degree for the mesh: the maximum derivative order over the aux registry, additional_systems and source_derivative_specs (at least 1); never set by hand.

References

  • Mavriplis 2003, https://doi.org/10.2514/6.2003-3986

build_numerics()#

Instantiate the symbolic Riemann numerics over this NSM (threading scaled_q_indices) and register it weakly so later operations refresh it.

property call#

The kernels table: one KernelCall per kernel the NSM carries (operators, boundary kernels, numerics functions), None where empty, printed as <_symbolic_name>.<slot>. Two boundary kernels exist: boundary_conditions (face value, for the Riemann problem) and boundary_ghost_state (mirror-image ghost, for gradients, limiters, derivative aux and diffusion).

property aux_derivatives#

Aux rows filled from mesh derivatives: aux_registry plus aux_input_registry.

build_runtime_numpy()#

Lambdify this NSM into the runtime model the NumPy solvers consume.

zoomy_core.numerics.numerical_system_model.to_numerical_system_model(obj) → zoomy_core.numerics.numerical_system_model.NumericalSystemModel#

Coerce a Model, SystemModel or NSM to a NumericalSystemModel, the single front door of the core code printers; other types raise TypeError.