zoomy_core.systemmodel.operations#
Reusable SystemModel.apply operations (op(sm) callables) that rewrite operator slots:
aux registration, 1/h regularization, eigenvalue guards.
They run on the way from SystemModel to NumericalSystemModel; sweeping operations cover
every slot of OPERATOR_SLOTS unless a slot is explicitly excluded.
Module Contents#
Functions#
Apply |
|
Operation: impose |
|
Kurganov-Petrova desingularized inverse depth |
|
Operation: add the algebraic aux variable |
|
Operation: replace every |
|
Operation: multiply each algebraic (zero mass-matrix) row by the minimal power of |
|
Operation: register the |
|
Operation: derive the closed-form spectrum of the normal-projected quasilinear matrix into
|
|
Operation: substitute the Kurganov-Petrova reciprocal inline for every |
|
Operation: register the aux |
|
Operation: replace the base of each negative or fractional power in the source that
involves a |
|
Operation: wrap every fractional power of the depth in |
|
Operation: publish a timestep-only spectrum |
|
Operation: shift the base of every fractional power by |
Data#
API#
- zoomy_core.systemmodel.operations.OPERATOR_SLOTS#
(‘flux’, ‘hydrostatic_pressure’, ‘nonconservative_matrix’, ‘source’, ‘source_explicit’, ‘mass_matrix…
- zoomy_core.systemmodel.operations.KERNEL_SLOTS#
(‘boundary_conditions’, ‘aux_boundary_conditions’, ‘boundary_gradients’)
- zoomy_core.systemmodel.operations.map_operator_slots(sm, rewrite, *, exclude=(), skip_rows=None) dict#
Apply
rewrite(expr) -> exprto every slot ofOPERATOR_SLOTSexceptexclude, freezing the lazyquasilinear_matrixfrom the clean primaries first.Args
exclude: slot names to leave alone; a name outsideOPERATOR_SLOTSraisesKeyError.skip_rows:{slot: rows}left untouched inside a swept slot.
Returns
{slot: "rewritten" | "unchanged" | "absent" | "excluded"}.
- zoomy_core.systemmodel.operations.normalize_face_normal(*, exclude=())#
Operation: impose
|n| = 1on every slot (default scopeOPERATOR_SLOTS), which separates the SWE celerity from the1/hof the momentum terms. It is aNumericalSystemModeldefault (normalize_normal=True).
- zoomy_core.systemmodel.operations.kp_hinv(h, eps)#
Kurganov-Petrova desingularized inverse depth
sqrt(2) h / sqrt(h^4 + max(h, eps)^4), equal to1/hforh >= epsand tending to 0 ash -> 0. The numerator is bareh(no clamp), so a negative depth gives a negativehinvand the failure stays visible.Args
h: depth, sympy expression or numpy/jax array.eps: regularization scale.
References
Kurganov, Petrova 2007, https://doi.org/10.4310/CMS.2007.v5.n1.a6
- zoomy_core.systemmodel.operations.register_aux(name: str, formula, **assumptions)#
Operation: add the algebraic aux variable
name = formulatoaux_stateandupdate_aux_variables(identity on existing rows) and refresh the derived operators.**assumptionsgo to the new Symbol (defaultreal=True).
- zoomy_core.systemmodel.operations.regularize_pow(field: Union[str, sympy.Symbol], aux_name: str)#
Operation: replace every
field**(-n)in the physical, derived and reconstruction operators byaux_name**n; eigenvalues get a floored plain1/max(1e-14, h)instead. The lazy derived operators are frozen from the clean primaries first, so the exactd(q^2/h)/dhterm survives the substitution.
- zoomy_core.systemmodel.operations.equilibrate_constraint_rows(mode=True)#
Operation: multiply each algebraic (zero mass-matrix) row by the minimal power of
hthat clears its negative powers ofh. This changes the conditioning of the elliptic block, not the constraint manifold, wherever ``h0``.
- zoomy_core.systemmodel.operations.desingularize_hinv(mode='kp')#
Operation: register the
hinvaux with the Kurganov-Petrova inverse depth (eps=wet_dry_eps) and rewrite everyh**(-n)tohinv**n;modeisTrueor"kp", falsy is a no-op. Legacy NSM depth default; the depth-law study usesregularize_depth_direct/regularize_depth_aux.References
Kurganov, Petrova 2007, https://doi.org/10.4310/CMS.2007.v5.n1.a6
- zoomy_core.systemmodel.operations.symbolic_spectrum()#
Operation: derive the closed-form spectrum of the normal-projected quasilinear matrix into
sm.eigenvalues; opt-in because it is expensive for high moment levels.
- zoomy_core.systemmodel.operations.regularize_depth_direct(eps=None, *, field: str = 'h', eigenvalues: str = 'regularize', exclude=())#
Operation: substitute the Kurganov-Petrova reciprocal inline for every
field**(-n)in every slot (the DIRECT path); no aux row is added. Mutually exclusive withregularize_depth_aux.Args
eps: regularization scale (notwet_dry_eps).eigenvalues:"regularize"sweeps the spectrum,"exclude"keeps the exact1/h.exclude: further slots to leave alone (opt out, never opt in).
References
Kurganov, Petrova 2007, https://doi.org/10.4310/CMS.2007.v5.n1.a6
- zoomy_core.systemmodel.operations.regularize_depth_aux(eps=None, *, name: str = 'hinv', field: str = 'h', eigenvalues: str = 'regularize', exclude=())#
Operation: register the aux
namewhose update row is the Kurganov-Petrova reciprocal and rewrite everyfield**(-n)toname**nin every slot (the AUX path). Mutually exclusive withregularize_depth_direct; takes the sameeps/eigenvalues/excludearguments, and the row definingnameis not rewritten.References
Kurganov, Petrova 2007, https://doi.org/10.4310/CMS.2007.v5.n1.a6
- zoomy_core.systemmodel.operations.desingularize_positivity(floor)#
Operation: replace the base of each negative or fractional power in the source that involves a
positive_statesymbol bysqrt(base**2 + floor**2)and re-derive the source Jacobians. A no-op if the model declares nopositive_state.
- zoomy_core.systemmodel.operations.guard_eigenvalue_powers()#
Operation: wrap every fractional power of the depth in
sm.eigenvaluesinMax(., 0)so wave speeds stay real at a transienth < 0(no dry zeroing). Half A of the guard/gate split;gate_eigenvalues_dryis half B.
- zoomy_core.systemmodel.operations.gate_eigenvalues_dry(eps=None)#
Operation: publish a timestep-only spectrum
conditional(h > eps, e, 0)intosm.eigenvalues_cfl, leavingsm.eigenvaluesphysical (with its power guard) for the Riemann dissipation. The dry gate carries the power guard because a branchless backend evaluates both arms; without a closed form it gatesnumerical_eigenvalues(or the model’s publishedeigenvalues_cfl) and is idempotent.
- zoomy_core.systemmodel.operations.regularize_fractional_powers(eps, *, exclude=())#
Operation: shift the base of every fractional power by
eps**2(b**r -> (b + eps**2)**r) so the operators stay differentiable atb = 0under AD. Opt-in and idempotent;epsmust be positive, and the value changes byO(eps**2)away fromb = 0.