zoomy_core.numerics.numerical_system_model module

zoomy_core.numerics.numerical_system_model module#

NumericalSystemModel — numerical sibling of SystemModel.

The NSM bundles a frozen SystemModel with everything a solver needs that is not symbolic-PDE-shaped:

  • the Riemann-solver class (a Numerics subclass)

  • the LSQ reconstruction spec (order, limiter)

  • the diffusion-scheme spec (Crank-Nicolson, ν override, …)

  • numerical regularization (eigenvalue eps, …)

  • the LSQ polynomial degree (auto-derived from the SystemModel’s aux_registry when not pinned explicitly)

This means a solver constructor no longer takes a pile of (model, riemann=, reconstruction_order=, eigenvalue_regularization=, …) kwargs. Solvers consume the NSM directly; everything else is a runtime knob (dt control, end time, IO, GMRES tolerances).

The class is read-only on the contained SystemModel — it never mutates the symbolic operators. Two reasons:

  1. Other agents may be revisiting SystemModel concurrently; we keep the seam clean by leaving the symbolic frozen-form untouched.

  2. Numerical operations (regularization, field-inversion-into-aux, splitting into sub-systems) belong on the NSM, not on the symbolic sibling — mirrors the user’s mental model that numerical transformations operate on a numerical container.

Pipeline: Model → SystemModel → NumericalSystemModel → Solver

class zoomy_core.numerics.numerical_system_model.ReconstructionSpec(order=1, limiter='venkatakrishnan', free_surface_aware=False)#

Bases: object

Numerical face-state reconstruction configuration.

order: 1 = piecewise-constant; 2 = LSQ-MUSCL with limiter. free_surface_aware: when True, use the wet-dry-aware MUSCL variant (clamps h 0 at faces, falls back to first order in dry cells).

Parameters:
  • order (int) –

  • limiter (str) –

  • free_surface_aware (bool) –

order: int = 1#
limiter: str = 'venkatakrishnan'#
free_surface_aware: bool = False#
class zoomy_core.numerics.numerical_system_model.DiffusionSpec(enabled=True, scheme='crank_nicolson', nu=None)#

Bases: object

Diffusion / viscous-flux configuration.

enabled is honoured by the solver; it is auto-set to False in NumericalSystemModel.from_system_model() when the SystemModel’s diffusion_matrix is identically zero. nu overrides the value pulled from sm.parameter_values['nu'].

Parameters:
  • enabled (bool) –

  • scheme (str) –

  • nu (Optional[float]) –

enabled: bool = True#
scheme: str = 'crank_nicolson'#
nu: Optional[float] = None#
class zoomy_core.numerics.numerical_system_model.RegularizationSpec(eigenvalue_eps=1e-08)#

Bases: object

Numerical regularization knobs.

eigenvalue_eps is added to the diagonal of the local quasi-linear matrix before eigenvalue decomposition in the numerical-eigenvalue path; without it, dry/near-dry SWE cells yield A·n matrices with repeated zero eigenvalues and the LAPACK eigensolve can spike spurious large modes.

Parameters:

eigenvalue_eps (float) –

eigenvalue_eps: float = 1e-08#
class zoomy_core.numerics.numerical_system_model.NumericalSystemModel(sm, riemann=None, reconstruction=<factory>, diffusion=<factory>, regularization=<factory>, source_derivative_specs=None, additional_systems=<factory>, scaled_q_indices=None)#

Bases: object

Numerical sibling of SystemModel.

Always constructed via from_system_model(). Direct instantiation is allowed (for tests, manual overrides) but the classmethod is the documented entry point.

Parameters:
  • sm (SystemModel) –

  • riemann (Optional[Type[Any]]) –

  • reconstruction (ReconstructionSpec) –

  • diffusion (DiffusionSpec) –

  • regularization (RegularizationSpec) –

  • source_derivative_specs (Optional[list]) –

  • additional_systems (list) –

  • scaled_q_indices (Optional[list]) –

sm: SystemModel#
riemann: Optional[Type[Any]] = None#
reconstruction: ReconstructionSpec#
diffusion: DiffusionSpec#
regularization: RegularizationSpec#
source_derivative_specs: Optional[list] = None#
additional_systems: list#
scaled_q_indices: Optional[list] = None#
classmethod from_system_model(sm, *, riemann=None, reconstruction=None, diffusion=None, regularization=None, additional_systems=None, scaled_q_indices=None)#

Build an NSM from a SystemModel (or a Model, auto-promoted via SystemModel.from_model()).

Defaults:
  • riemannNonconservativeRusanov

  • reconstruction → first-order constant

  • diffusion → enabled if the SystemModel carries a non-zero diffusion_matrix and a positive nu; otherwise disabled.

  • regularizationeigenvalue_eps=1e-8

LSQ polynomial degree is always auto-derived (from sm.aux_registry plus any additional_systems) — it is no longer a hand-adjustable knob. Composite solvers pass additional_systems=[sm_press, sm_corr, ...] so the predictor’s mesh stencil is large enough for the co-running sub-systems’ derivatives.

Parameters:
Return type:

NumericalSystemModel

resolved_lsq_degree()#

Return the LSQ polynomial degree the mesh should use.

Computed as the max spatial-derivative order across:

  • self.sm.aux_registry (every SystemModel carries this, populated by SystemModel.from_model()),

  • every entry in self.additional_systems (composite sub-systems that share the same mesh; both aux_registry and derivative_specs are consulted — entries may be either Models or SystemModels), and

  • self.source_derivative_specs (captured at promotion when the source was a StructuredDerivativeModel, whose D.dxx(...) calls are substituted by Symbols before SystemModel.from_model runs — so the source-side declaration is the only signal that survives).

Falls back to 1 when no signal exists. Never user-set.

Return type:

int

build_numerics()#

Instantiate the symbolic Riemann numerics over sm.

Threads self.scaled_q_indices into the Riemann constructor when set — the Audusse-HR variants (PositiveRusanov family) use it to control which state rows are rescaled by h*/h at face states. Default (None) lets the Riemann class fall back to its own heuristic (excluding only h and b).

build_runtime_numpy()#

Lambdify sm into a runtime model the NumPy solvers consume (callable .flux / .source / .eigenvalues / .boundary_conditions etc.).