zoomy_core.model.derivation.basisfunctions#
Concrete polynomial bases in z (Legendre, Chebyshev, splines, layered, BC-aware) for the
moment/Galerkin derivation. They resolve the opaque Galerkin brackets of a Model into numbers on the
way to a SystemModel.
Module Contents#
Classes#
Base class of a concrete basis: polynomials |
|
Monomial basis |
|
Multi-layer basis: an inner basis rescaled onto each of |
|
Shifted Legendre basis |
|
Wrap an orthogonal basis with an explicit test weight (e.g. a curvilinear metric), so projections resolve concretely. It has no delta closed forms because the wrapped family is orthogonal only under unit weight. |
|
Chebyshev-U basis on |
|
Chebyshev-U basis |
|
Legendre-based basis on |
|
Boundary-condition-aware basis: |
|
Raw B-spline hat-function basis on |
|
Legacy B-spline basis with fixed knots; use |
|
B-spline basis plus a constant, orthonormalised on |
API#
- class zoomy_core.model.derivation.basisfunctions.Basisfunction(level=0, symbol='phi', **kwargs)#
Base class of a concrete basis: polynomials
basisplus opaque headsphi_fn(k, zeta)andc_fn(zeta)that point back to the instance. ResolveBasis routes Galerkin brackets built from these heads toresolve.Args
level: highest basis index (level + 1functions).symbol: name of the opaquephi_fnFunction class.
Initialization
Build the concrete
basis, the opaque headsphi_fn/c_fnand the bracket cache.- name#
‘Basisfunction’
- bounds()#
Return the integration interval
[0, 1].
- basis_definition()#
Return the monomials
z**kfork = 0..level.
- weight(z)#
Return the weight
omega(z) = 1.
- mean_coefficients()#
Return coefficients
c_kwithsum(c_k phi_k) = 1, so the depth mean issum(c_k alpha_k)`. Default `[1, 0, ...]assumesphi_0 = 1; override when the constant is a combination (e.g. B-splines).
- weight_eval(z)#
Evaluate
weightnumerically via lambdify.
- weight_name#
‘c’
- closed_form_bracket(name, args)#
Return the closed form of a named bracket (
"Gram"/"Weight") in symbolic indices, orNone. The base class has none; orthogonal bases override it, e.g.Legendre_shifted.Args
name: bracket family name.args: its index tuple.
- resolve_atoms(expr)#
Replace each
phi_fn(k, arg)with integerkby the polynomialeval(k, arg); symbolickstays opaque. Atoms of other bases are untouched.
- evaluate_bracket(body, var, lower=0, upper=1)#
Evaluate one Galerkin bracket
int_lower^upper body d(var)to a number by concretising and using the antiderivative; memoised per instance.Args
body: product of opaquephi/cheads, their derivatives and nested running integrals.var: integration variable.
- analytical_weighted_integral_bounds(poly_expr, var, lower, upper)#
Return
int_lower^upper poly_expr d(var)by antiderivative.
- resolve(expr, var)#
Resolve every Galerkin bracket in
exprto a number against this basis (closed forms forGram/Weight,evaluate_bracketotherwise). Only inserts values: outer derivatives are not evaluated and deferred integrals stay compact.Args
expr: sympy expression containing brackets.var: bracket integration variable.
- get(k)#
Return the polynomial of basis function
k.
- gram(i, j)#
Return the Galerkin mass-matrix entry
<phi_i, phi_j> = int omega phi_i phi_j dz, from the closed form if the basis has one.Args
i: row index.j: column index.
- eval(k, _z)#
Evaluate basis function
kat_z.
- at0(k)#
Return basis function
kat the bottom of the layer,eval(k, bounds[0]).
- at1(k)#
Return basis function
kat the free surface,eval(k, bounds[1]).
- eval_psi(k, _z)#
Evaluate the running integral of basis function
kfrom the lower bound to_z.
- get_lambda(k)#
Return a numeric callable of basis function
kaccepting scalars, lists or arrays.
- plot(ax)#
Plot every basis function on
boundsinto the matplotlib axesax.
- reconstruct_velocity_profile(alpha, N=100)#
Return
sum(alpha_i phi_i)onNequispaced points ofbounds.
- reconstruct_velocity_profile_at(alpha, z)#
Return
sum(alpha_i phi_i)at the pointz.
- reconstruct_alpha(velocities, z)#
Return per-mode coefficients of sampled
velocitiesat pointszby trapezoid quadrature (assumes an orthogonal basis).
- project_onto_basis(Y)#
Return the unnormalised projections
int Y phi_k omega dzof the samplesY(equispaced onbounds) by trapezoid quadrature.
- projection_rows(nodes, weights, samples, norm=None)#
Return one symbolic row per basis function that projects a profile sampled at fixed nodes onto the basis (discrete least squares, full inverse Gram matrix). Each row is plain arithmetic in
samples, so every code printer can lower it.Args
nodes: sample pointszeta_j.weights: quadrature weightsw_j(same length).samples: input symbolsfield(zeta_j)(same length).norm: optional per-row scale, a callable ofkor a sequence.
Returns
List of
len(basis)sympy rows.
- get_diff_basis()#
Return the
z-derivatives of all basis polynomials.
- class zoomy_core.model.derivation.basisfunctions.Monomials(level=0, symbol='phi', **kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionMonomial basis
z**k(the base-class default).Initialization
Build the concrete
basis, the opaque headsphi_fn/c_fnand the bracket cache.- name#
‘Monomials’
- class zoomy_core.model.derivation.basisfunctions.LayeredBasis(inner_cls=None, inner_level=0, interfaces=None, n_layers=None, **inner_kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionMulti-layer basis: an inner basis rescaled onto each of
Nsub-intervals and zero outside, givingN * (inner_level + 1)functions with flat indexi*m + k.inner_level=0gives piecewise constants (multi-layer SWE),Legendre_shiftedmulti-layer moments.Args
inner_cls: per-layer Basisfunction subclass.inner_level: level of the inner basis.interfaces: explicit breakpoints (N + 1), in zeta or physical z.n_layers: number of equal layers on[0, 1]wheninterfacesis not given.
References
Audusse et al. 2011, https://doi.org/10.1051/m2an/2010036
Initialization
Build the inner basis and the layered piecewise polynomials.
- name#
‘LayeredBasis’
- basis_definition()#
Return the inner functions rescaled to each layer as Piecewise, zero outside the layer.
- bounds()#
Return the outer interfaces
[first, last].
- weight(z)#
Return the inner-basis weight.
- mean_coefficients()#
Return the inner mean coefficients repeated for every layer.
- flat_index(layer_idx, moment_idx)#
Map
(layer_idx, moment_idx)to the flat basis index.
- layer_zeta(layer_idx, z_value)#
Return the local coordinate
(z_value - lower_i) / h_iin layerlayer_idx.
- class zoomy_core.model.derivation.basisfunctions.Legendre_shifted(level=0, symbol='phi', **kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionShifted Legendre basis
phi_k(z) = P_k(2z - 1)on[0, 1], orthogonal under unit weight; the standard SME moment basis.References
Kowalski, Torrilhon 2019, https://doi.org/10.4208/cicp.OA-2017-0263
Initialization
Build the concrete
basis, the opaque headsphi_fn/c_fnand the bracket cache.- name#
‘Legendre_shifted’
- basis_definition()#
Return
legendre(k, 2z - 1), sophi_k(0) = (-1)^kat the bed andphi_k(1) = 1at the free surface.
- analytical_weighted_integral(poly_expr, var)#
Return
int_0^1 poly_expr d(var)(unit weight) by antiderivative.
- closed_form_bracket(name, args)#
Return
Gram(i, l) = delta_il / (2l + 1)andWeight(l) = delta_l0, orNonefor any other bracket.
- class zoomy_core.model.derivation.basisfunctions.WeightedBasis(inner, weight, level=None)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionWrap an orthogonal basis with an explicit test weight (e.g. a curvilinear metric), so projections resolve concretely. It has no delta closed forms because the wrapped family is orthogonal only under unit weight.
Args
inner: wrapped Basisfunction.weight: weight expression in the integration variable.level: basis level (default: that ofinner).
Initialization
Store the wrapped basis and the weight.
- name#
‘WeightedBasis’
- basis_definition()#
Return the wrapped basis polynomials unchanged.
- bounds()#
Return the bounds of the wrapped basis.
- property weight#
Return the geometric weight.
- analytical_weighted_integral(poly_expr, var)#
Return
int_0^1 poly_expr * weight d(var)by antiderivative.
- closed_form_bracket(name, args)#
Return
None: no delta closed form under a non-unit weight.
- class zoomy_core.model.derivation.basisfunctions.Chebyshevu(level=0, symbol='phi', **kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionChebyshev-U basis on
[-1, 1]with weightsqrt(1 - z**2)and normalisationsqrt(2/pi).Initialization
Build the concrete
basis, the opaque headsphi_fn/c_fnand the bracket cache.- name#
‘Chebyshevu’
- bounds()#
Return
[-1, 1].
- weight(z)#
Return
sqrt(1 - z**2).
- basis_definition()#
Return
sqrt(2/pi) * U_k(z).
- class zoomy_core.model.derivation.basisfunctions.Chebyshevu_shifted(level=0, symbol='phi', **kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionChebyshev-U basis
U_k(2z - 1)on[0, 1]with weightsqrt(z(1 - z))andphi_0 = 1, orthogonal with normpi/8.Initialization
Build the concrete
basis, the opaque headsphi_fn/c_fnand the bracket cache.- name#
‘Chebyshevu_shifted’
- bounds()#
Return
[0, 1].
- weight(z)#
Return
sqrt(z (1 - z)).
- basis_definition()#
Return
U_k(2z - 1).
- analytical_weighted_integral(poly_expr, var)#
Return
int_0^1 poly_expr * sqrt(z(1 - z)) d(var)via U-orthogonality, orNoneifpoly_expris not a polynomial.
- quadrature_nodes(n=None)#
Return Gauss-Chebyshev-U nodes and weights on
[0, 1]for the weightsqrt(z(1 - z)).Args
n: node count minus one; default2 * (level + 1).
Returns
Tuple
(nodes, weights)of arrays.
- class zoomy_core.model.derivation.basisfunctions.Legendre_DN(level=0, symbol='phi', **kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionLegendre-based basis on
[-1, 1]satisfying no-slip at the bottomz = -1and no-stress at the topz = 1by construction; not an SWE-limit basis.Initialization
Build the concrete
basis, the opaque headsphi_fn/c_fnand the bracket cache.- name#
‘Legendre_DN - satifying no-slip and no-stress. This is a non-SWE basis’
- bounds()#
Return
[-1, 1].
- basis_definition()#
Return
P_k + alpha_k P_{k+1} + beta_k P_{k+2}with fixed rationalalpha_k,beta_k.
- class zoomy_core.model.derivation.basisfunctions.GalerkinBasis(level=0, parent='legendre', bc_bottom='slip', bc_top='nostress', slip_length=None, **kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionBoundary-condition-aware basis:
phi_0 = 1andphi_krecombined from parent polynomials (Legendre or Chebyshev-U) to satisfy ‘free’, ‘noslip’, ‘nostress’ or ‘slip’ conditions at bottom and top.Args
level: highest basis index.parent: parent family,'legendre'or'chebyshev'.bc_bottom: condition atz = 0.bc_top: condition atz = 1.slip_length: slip length for'slip'(symbolicslip_lengthif None).
References
Shen 1994, https://doi.org/10.1137/0915089
Initialization
Store the parent family and boundary conditions, then build the basis.
- name#
‘GalerkinBasis’
- bounds()#
Return
[0, 1].
- weight(z)#
Return the unit weight.
- basis_definition()#
Return
[1, phi_1, ...]with eachphi_ksolved from the linear boundary conditions (one condition: two parents, two conditions: three).
- class zoomy_core.model.derivation.basisfunctions.SplineBasis(level=0, degree=1, **kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionRaw B-spline hat-function basis on
[0, 1]with nodal coefficients and partition of unity (sum B_k = 1). Providesget_knot_spansfor piecewise integration.Args
level: highest basis index.degree: spline degree.
Initialization
Store the spline degree, then build the basis.
- name#
‘SplineBasis’
- bounds()#
Return
[0, 1].
- weight(z)#
Return the unit weight.
- basis_definition()#
Return the first
level + 1B-splines, padded with zeros.
- get_knot_spans()#
Return the
(a, b)intervals between consecutive distinct knots.
- mean_coefficients()#
Return all ones, since B-splines are a partition of unity.
- class zoomy_core.model.derivation.basisfunctions.Spline(level=0, symbol='phi', **kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionLegacy B-spline basis with fixed knots; use
SplineBasisinstead.Initialization
Build the concrete
basis, the opaque headsphi_fn/c_fnand the bracket cache.- name#
‘Spline’
- basis_definition(degree=1, knots=[0, 0, 0.001, 1, 1])#
Return the B-spline set of the given degree and knots.
- class zoomy_core.model.derivation.basisfunctions.OrthogonalSplineWithConstant(level=0, symbol='phi', **kwargs)#
Bases:
zoomy_core.model.derivation.basisfunctions.BasisfunctionB-spline basis plus a constant, orthonormalised on
[0, 1]by Gram-Schmidt.Initialization
Build the concrete
basis, the opaque headsphi_fn/c_fnand the bracket cache.- name#
‘OrthogonalSplineWithConstant’
- basis_definition(degree=1, knots=[0, 0, 0.5, 1, 1])#
Return the Gram-Schmidt orthonormalised basis
[1] + B-splines[:-1].