zoomy_core.symbolic package#
Principled symbolic-derivation primitive layer for zoomy_core.
This package replaces the semi-automatic, partially sympy-driven
pipeline in zoomy_core.model.models.ins_generator with a closed
set of well-defined mathematical primitives. Every primitive is
ONE textbook calculus rule that fires only when explicitly invoked.
Sympy is used for arithmetic on Add/Mul/Pow and for
purely-structural xreplace; sympy is never used to fire chain
rule, Leibniz, IBP, common-denominator, factor, or .doit().
Public surface (Phase 0):
D(),Int(),Sub()— held-form sympy constructors (alwaysevaluate=False).PrimitiveDoesNotMatch— exception raised when a primitive’s preconditions fail.AutoEvalGuard— context manager that bans sympy auto-evaluation calls inside its block (used in tests + the slim walkthrough verifier).
Primitives are added incrementally during Phase 0:
primitives_canonical— purely-structural rewriters (AlphaRename,SplitIntegralOverAdd,MergeIntegralsOverAdd,DistributeMulOverAdd,ZeroDerivativeOfFreeSymbol,UnSubs).primitives_calculus— calculus rules (ProductRuleForward,ProductRuleInverse,ChainRule,Leibniz,FundamentalTheorem,IntegrationByParts,PolynomialIntegrate,DistributeDerivativeOverAdd,PullScalarOutOfDerivative,PushScalarIntoDerivative).primitives_change_of_variable—AffineChangeOfVariable.primitives_basis—CanonicalizePhiDerivativeSubs,ProjectBasisIntegrand.primitives_substitution—Subst,FunctionExpand,SubsAtPoint,SolveFor.canonicalise— the fixed, finite-stepcanonicalisepass that replaces the legacy_simplify_preserve_integrals6-iteration fixpoint loop.
- zoomy_core.symbolic.D(expr, *vars)#
Held
Derivative(expr, *vars).- Parameters:
expr (sympy.Expr) –
*vars – Each entry is either a single
Symbol(∂_v applied once) or a(symbol, n)tuple (∂_v^n). Same shape sympy’sDerivativeaccepts.
- Returns:
Always held — never auto-evaluated. The primitive layer decides when to apply chain/product/Leibniz rules.
- Return type:
sympy.Derivative
- zoomy_core.symbolic.Int(integrand, *limits)#
Held
Integral(integrand, *limits).Each limit is either a bare
Symbol(indefinite integral, single arg) or a(symbol, lower, upper)triple (definite integral).sp.Integralis held by default (it never auto-evaluates on construction), so this is a thin documenting wrapper. Only.doit()orsp.integrate(...)would evaluate it — both are forbidden inside the symbolic package.
- zoomy_core.symbolic.Sub(expr, var, value)#
Held
Subs(expr, var, value).sp.Subsis held by default, so this is a thin alias that documents intent: any “evaluateexpratvar = value” should go throughSuband produce a held atom rendered asexpr|_{var=value}by the latex printer.The primitive
UnSubsis the only thing that may unwrap this.
- zoomy_core.symbolic.held_function(name, *args, **kwargs)#
Construct a held
UndefinedFunctioncallf(*args).A passthrough wrapper for completeness — sympy’s default behaviour on UndefinedFunction calls is already non-evaluating, so this is just
sp.Function(name)(*args).
- exception zoomy_core.symbolic.PrimitiveDoesNotMatch(primitive, atom, reason='')#
Bases:
ExceptionThe primitive’s structural pattern did not match the input.
Carries the primitive name and the (sympy) atom that failed the match so the caller can localise the error.
- Parameters:
primitive (str) –
reason (str) –
- class zoomy_core.symbolic.AutoEvalGuard#
Bases:
objectMonkeypatch
sympy.Basic.doitand the eval-style sympy helpers to raise. Restored on exit.
- exception zoomy_core.symbolic.AutoEvalForbidden#
Bases:
RuntimeErrorRaised when a forbidden sympy auto-evaluation call fires.
The redesign’s invariant is: every math rule is invoked by an explicit primitive. Sympy’s auto-evaluation calls (
.doit(),sp.simplify, etc.) bypass that surface and cause subtle order-of-operations bugs. The guard makes any such call a hard failure.
- zoomy_core.symbolic.canonicalise(expr)#
Normalise
exprvia the fixed structural pipeline.Pure:
canonicalise(canonicalise(x)) == canonicalise(x). Equality-preserving:canonicalise(x - y) == 0iffxandyare structurally equal up to the canonicalisation rules (alpha-renaming of bound variables, Mul-over-Add distribution, Integral linearity, zero-collapse).
- zoomy_core.symbolic.alpha_rename(expr)#
Rename every
Integral‘s bound variable to a depth-keyed canonical Dummy.Lifted verbatim from
_canonicalize_integral_dummies(ins_generator.py:4154). Purexreplace; no math change — alpha-equivalence of bound variables is a definitional property of the integral.
- zoomy_core.symbolic.constant_integrand(expr)#
∫_a^b c dvar → c·(b − a)when integrand has novar.Lifted from the constant-integrand branch of
SimplifyIntegrals._leaf_sp(ins_generator.py:2373) andIsolateBasisIntegrand(ins_generator.py:2698).
- zoomy_core.symbolic.distribute_mul_over_add(expr)#
c·(a+b) → c·a + c·b— ring-axiom distribution.Uses
sp.expandwith all non-Mul branches disabled so the only rewrite that fires is Mul-over-Add distribution. Integrals are protected during the expansion so their integrands stay intact (sympy’sexpandwould otherwise fragmentIntegral(f+g, lim)intoIntegral(f, lim) + Integral(g, lim)— that’s a separate primitive,split_integral_over_add).Lifted from
_expand_preserve_integrals(ins_generator.py:4124).
- zoomy_core.symbolic.drop_zero_derivative_inner(expr)#
Derivative(0, …) → 0— structural.Lifted from the
∂(0)branch of_evaluate_linear_derivatives(ins_generator.py:4621).
- zoomy_core.symbolic.drop_zero_integrand(expr)#
Integral(0, …) → 0— structural.Lifted from the
∫0branch ofSimplifyIntegrals._leaf_sp(ins_generator.py:2371) andIsolateBasisIntegrand(ins_generator.py:2698).
- zoomy_core.symbolic.kill_zero_length_integral(expr)#
Integral(_, (var, a, a)) → 0— structural equality only.This is a tightened version of the legacy
_kill_zero_length_integrals(ins_generator.py:4366) which fell back tosp.simplify(lo - hi) == 0.sp.simplifycan fire arbitrary rules on the bounds — for the redesign we accept only structural equality (lo == hiorlo - hireduces toS.Zerovia sympy’sAddcanonicalisation alone, no further-simplification pass).Callers who want a deeper bound match must apply a
Substrule that makes the bounds structurally equal first.
- zoomy_core.symbolic.merge_integrals_over_add(expr)#
Combine sibling Integrals with matching
(limits, deriv-wrapper)signature into a singleIntegral(Σ c_i · f_i, lim).Inverse of
split_integral_over_add(). An outer factor moves inside the integral only if it doesn’t depend on the integration variable — otherwise the factor stays out (passthrough); moving it inside would change the math.Lifted from
_merge_integrals_expr(ins_generator.py:4263).
- zoomy_core.symbolic.protect_integrals(expr, *, also_derivative_of_integral=False)#
Replace every
Integral(and optionallyDerivative(Integral(...), ...)) atom with a freshDummyand return(protected_expr, restore_map).Restore via
protected_expr.xreplace(restore_map). Used to run arithmetic (sp.expandMul-over-Add) on the expression’s outer structure without sympy fragmenting the integrand.Lifted from
_expand_preserve_integrals(ins_generator.py:4124) and the protect-helper inside_simplify_preserve_integrals(ins_generator.py:4434).
- zoomy_core.symbolic.split_integral_over_add(expr)#
∫(f+g) dv → ∫f dv + ∫g dv— linearity of the integral.Distributes through
Derivative(Integral(...), v)by linearity of the derivative. Outer multiplicative factors stay attached.Lifted from
_split_integrals_expr(ins_generator.py:4217).
- zoomy_core.symbolic.un_subs(expr)#
Unwrap every
Subs(f, var, val)whose inner is safe toxreplace(var → val).Safety = none of:
varappears as aDerivativedifferentiation variable inf(would commit to chain-rule-through-valambiguity).varis the integration variable of a nestedIntegralinf(would shadow the binder and produce nonsense limits).varis the binding variable of a nestedSubsinf(same shadowing concern).
Lifted verbatim from
_resolve_subs_safe(ins_generator.py:4539). The redesign promotes this to a primitive — the previously implicit calls (insideExpression.apply,EvaluateIntegrals,ProjectBasisIntegrals) all become explicit user steps.
- zoomy_core.symbolic.zero_derivative_of_free_symbol(expr)#
∂_v sym → 0whensymis a freeSymboldistinct from every differentiation variable.These appear as Leibniz boundary residuals (
∂_x zwhenzis a coordinate, not a function). Sympy doesn’t auto-reduce.Lifted verbatim from
_kill_free_derivatives(ins_generator.py:4387).
- zoomy_core.symbolic.chain_rule(term, outer_predicate, var)#
∂_v f(g(v)) → f'(g)·∂_v gwhereouter_predicate(f) → boolselects the function families to expand.Walks the expression and applies the chain rule wherever the pattern matches.
outer_predicateis a callable taking aFunctioninstance (the call site, e.g.phi_1((z-b)/h)) and returningTrueif this primitive should chain-rule it.For example, to chain-rule every
phi_*family call:def is_basis(call): name = getattr(call.func, '__name__', '') return name.startswith('phi_') chain_rule(expr, is_basis, var=x)
Implementation: walks
Derivativeatoms whose inner is a matching function call; replaces with the explicit chain-rule expansion using heldDerivativeatoms. No.doit()— otherDerivativeatoms are not touched.
- zoomy_core.symbolic.distribute_derivative_over_add(expr)#
∂_v Add(t1, t2) → Add(∂_v t1, ∂_v t2)— linearity.Hoisted from the Add branch of
_evaluate_linear_derivatives(ins_generator.py:4651). Distinguishes:Inner is structurally an
Add→ distribute outer Derivative.Inner is a
Mulwhoseas_coeff_Mulseparates a numeric scalar → pull it out (separate primitivepull_scalar_out_of_derivative()does that; this one only does Add-distribution).Trivially zero (
inner == 0or inner doesn’t reference any diff-var) → returns 0.
No
.doit()— distributed Derivative atoms are held.
- zoomy_core.symbolic.fundamental_theorem(integrand, var, lower, upper)#
∫_lo^hi ∂_var g dvar = g|_hi − g|_lo.Lifted verbatim from
_rule_fundamental_theorem(ins_generator.py:1934). Handles single-order∂_var gand higher-order-in-var(onevarpeels off). Mixed-order∂_var ∂_other gstrips onevarfrom the diff-tuple.Returns
Noneif the integrand isn’t aDerivativewhose diff-vars includevar(caller convention preserved from ins_generator’s rule-registry:None= “rule does not apply”, not an exception).
- zoomy_core.symbolic.integration_by_parts(f, g, var, lower, upper)#
∫_lo^hi (∂_var f)·g dvar = [f·g]_lo^hi − ∫_lo^hi f·∂_var g dvar.Returns a 3-tuple
(volume_integrand, boundary_upper, boundary_lower)so the caller can place each piece in the appropriate term tag.volume_integrandalready carries the-sign and is wrapped in aIntegral(..., (var, lower, upper)).Lifted from
integrate_by_parts(ins_generator.py:4757), with theIBPResultwrapper unpacked since it lives in the legacy layer.
- zoomy_core.symbolic.leibniz(integrand, var, lower, upper)#
∫_lo^hi ∂_y f dvar = ∂_y(∫_lo^hi f dvar) − f(hi)·∂_y hi + f(lo)·∂_y lowheny ≠ varandfis polynomial invar.Lifted from
_rule_derivative_of_polynomial(ins_generator.py:1976) with the inner_doit_only_derivativeswalk removed. If the caller wantsvar-factors to surface fromDerivative(var·g, y)etc. they must rundistribute_derivative_over_add()first.Returns
Nonewhen:integrand is not a
Derivative,diff-tuple has more than one entry,
differentiation is w.r.t.
varitself (fundamental_theoremhandles that),the integrand is independent of
var,sp.Polycannot build a polynomial invar.
- zoomy_core.symbolic.leibniz_general(integrand, var, lower, upper)#
Conservative-form Leibniz that does NOT require
fto be polynomial invar.For
∫_lo^hi ∂_y f dvarwithy ≠ var:= ∂_y[ ∫_lo^hi f dvar ] − f|_hi · ∂_y hi + f|_lo · ∂_y lo
The volume
∫f dvarstays as a heldsympy.Integralatom — no attempt to evaluate it. Boundary terms are produced as heldsympy.Subsatoms when the bounds depend ony.Use this when the integrand’s antiderivative is unknown or opaque; use
leibniz()(poly-specialised) whenfis polynomial invarand you want the closed-form volume.Returns
Noneif:integrand is not a
Derivative,diff-tuple has more than one entry,
differentiation is w.r.t.
varitself (fundamental_theoremhandles that).
- zoomy_core.symbolic.polynomial_integrate(integrand, var, lower, upper)#
∫_lo^hi p(var) dvarviasp.Poly.integratefor polynomialp(with arbitrary opaque coefficients).Lifted from
_rule_polynomial_integrand(ins_generator.py:2061) with the inner_doit_derivswalk removed. If the caller wantsvar-factors to surface fromDerivative(var·g, y)etc. they must rundistribute_derivative_over_add()first.Returns
(hi − lo) · integrandforvar-free integrands (constant integrand rule). ReturnsNoneifsp.Polycannot build a polynomial.
- zoomy_core.symbolic.product_rule_forward(term, var)#
∂_v(Π fᵢ) → Σᵢ (Π_{j≠i} fⱼ)·∂_v fᵢand∂_v(f^n) → n·f^(n-1)·∂_v ffor integern ≥ 2.Acts on a single
Derivativeatom. Iftermis not aDerivative, returnstermunchanged (no-op). If the derivative has multiple variables or its inner is neither a Mul nor an integer-power Pow, returnstermunchanged.Lifted from the forward branch of
ProductRule._one_term(ins_generator.py:3358). No.doit()involved — every output factor is a heldDerivative.
- zoomy_core.symbolic.product_rule_inverse(term, var)#
coeff · ∂_v f → ∂_v(coeff · f) − ∂_v(coeff) · f.The legacy version (
ProductRule._one_terminverse branch, ins_generator.py:3402) calledDerivative(coeff, var).doit()on the residual. That.doit()was the exact bug-3 source: whencoeffis e.g.φ_1((z-b)/h),.doit()fires the chain rule against the moving frame at exactly the wrong pipeline position.The redesigned primitive leaves the residual as a held
Derivative(coeff, var)atom. Canonicalise will reduce it to zero whencoeffis genuinelyvar-free, otherwise the user callschain_rule()orproduct_rule_forward()explicitly to expand it.
- zoomy_core.symbolic.pull_scalar_out_of_derivative(expr)#
∂_v(c·f) → c·∂_v fwhencis a sympyNumber(Integer/Rational/Float).Hoisted from the
Mul.as_coeff_Mulbranch of_evaluate_linear_derivatives(ins_generator.py:4644). Numeric-only — free symbols stay inside.
- zoomy_core.symbolic.push_scalar_into_derivative(expr)#
c · ∂_v f → ∂_v(c · f)whencis a sympyNumber.Inverse of
pull_scalar_out_of_derivative(). Lifted verbatim from_fold_numeric_coeffs_into_derivative(ins_generator.py:4674).
- zoomy_core.symbolic.affine_change_of_variable(expr, var, lower, upper, ref_var, ref_lo=0, ref_hi=1)#
- Apply ``∫_{lower}^{upper} f(var) dvar
- = ((upper-lower)/(ref_hi-ref_lo)) ·
∫_{ref_lo}^{ref_hi} f(φ(ref_var)) d(ref_var)``
where
φ(s) = lower + (upper-lower)·(s-ref_lo)/(ref_hi-ref_lo).Walks
exprand rewrites everyIntegral(f, (var, lower, upper))whose limits structurally match the given tuple. Other Integral atoms are left untouched — call the primitive again with their limits if you want them transformed.Bottom-up walk: nested integrals’ integrands are processed first so an inner running integral is in the new variable form before the outer transform runs.
Examples
>>> from zoomy_core.symbolic import Int >>> from zoomy_core.symbolic.primitives_change_of_variable import affine_change_of_variable >>> import sympy as sp >>> z, h = sp.symbols('z h', real=True) >>> b = sp.Function('b')(sp.Symbol('t'), sp.Symbol('x')) >>> zeta = sp.Symbol(r'\hat{\zeta}', real=True) >>> e = Int(sp.Function('f')(z), (z, b, b + h)) >>> affine_change_of_variable(e, z, b, b + h, zeta)
- zoomy_core.symbolic.canonicalize_phi_derivative_subs(expr)#
Subs(Derivative(phi_k(ξ), ξ), ξ, val) → Derivative(phi_k(val), val).The chain-rule artefact sympy creates when a
phi_k(arg)is substituted into aDerivativecontext. Recanonicalising as a plainDerivative(phi_k(val), val)makes the pattern visible to downstream basis-cache lookups.Lifted verbatim from
ProjectBasisIntegrals._canon(ins_generator.py:2236). Purexreplace— no math change.
- zoomy_core.symbolic.has_phi_call(e)#
True iff
econtains anyphi_*function call.
- zoomy_core.symbolic.project_basis_integrand(expr, basis_cache)#
Look up every
Integral(kernel, (ζ̂, 0, 1))whose kernel contains aphi_*call in the givenbasis_cacheand substitute the polynomial result.Single-pass: walks the expression once, replacing each matching Integral in place. Outer factors are pulled out structurally: integrand factors that don’t reference the integration variable become an outer coefficient; the rest is the kernel handed to the cache.
Lifted from the Pass-3
_mapofProjectBasisIntegrals(ins_generator.py:2282), with the surrounding fixpoint loop (lines 2339-2344) removed — the caller is expected to compose this primitive withcanonicalize_phi_derivative_subs()andzoomy_core.symbolic.primitives_canonical.un_subs()for any boundary-Subs resolution.
- zoomy_core.symbolic.function_expand(expr, field_fn, rhs_callable)#
Rewrite every call of
field_fneverywhere inexpr.rhs_callable(*args)is invoked with the call’s positional arguments and must return the replacement expression. Used to insert a velocity ansatz likeu(t, x, arg) → α_0 + α_1·φ_1((arg − b)/h)
The walk goes through
Derivative,Subs,Integralintegrands — anywhere afield_fncall lives.Lifted verbatim from
_FieldExpansion.apply_to(ins_generator.py:3785) — already a clean primitive.
- zoomy_core.symbolic.solve_for(eq_expr, variable)#
Solve
eq_expr == 0forvariable; return a relation dict{variable: solution}.Derivative(Integral(...))atoms ineq_exprare protected as Dummies beforesp.solvesees them. Without this protection sympy eagerly Leibniz-expands such atoms — the legacy bug-1 source in_NodeProxy.solve_for(derived_system.py:326), which produced a substitution rule like∂_t h = ∫∂_x u dẑ − u(b+h)·∂_x(b+h) + u(b)·∂_x b
instead of the conservative form
∂_t h = −∂_x[Integral(u, (ẑ, b, b+h))]
that pen-and-paper uses. When applied to an equation containing
α·∂_t hand then composed with_FieldExpansion, the Leibniz-expanded form double-counts the moving-frame contribution. The Dummy-protect/unprotect bracket avoids the issue entirely.Returns a plain
dictso callers can pass it directly tosubst(). UsePrimitiveDoesNotMatchsemantics: if no solution exists, raise.Lifted verbatim from
_NodeProxy.solve_for(derived_system.py:326).
- zoomy_core.symbolic.subs_at_point(expr, var, value)#
Produce a held
Subs(expr, (var,), (value,)).The held form means the latex printer renders it as
expr|_{var=value}. Onlyun_subs()(inzoomy_core.symbolic.primitives_canonical) may unwrap it, and only when the safety guards pass.
- zoomy_core.symbolic.subst(expr, rule)#
Apply
rule(dict or Relation) via structuralxreplace.Pure
xreplace— no sympy.subs()mass-substitution behaviour, no Subs wrapping when the substitution lands inside aDerivativewhose differentiation variable matches a key. Sympy’sxreplaceis pure structural matching — what you ask for is what you get.Accepted
ruleshapes:dictof{lhs: rhs}.Any object with an
_as_relationattribute (a dict), typically produced bysolve_for().Any object with an
apply_to(expr)method, in which case the method is delegated to (matches the legacyRelation/Materialprotocol).
- zoomy_core.symbolic.BoundaryIntegral(integrand, domain)#
Construct a symbolic
∫_∂D f dsatom.domainshould be a boundary domain (e.g.K.boundary()). The result is an opaquesympy.Functioncall whose class carries_domainback todomain— operations likeDivergenceTheoremandMapToReferenceElementwalk for instances of this class to find boundary integrals.- Parameters:
integrand (Expr) –
domain (Domain) –
- Return type:
Expr
- class zoomy_core.symbolic.Box(intervals, name=None)#
Bases:
DomainTensor product of
Intervalfactors.- Parameters:
intervals (Sequence[Interval]) –
name (str) –
- boundary()#
- Return type:
- affine_map()#
Return
(B, V0)such thatx = V0 + B · ξmaps the reference element toself. Defined only on volume domains.- Return type:
tuple[sympy.matrices.dense.MutableDenseMatrix, sympy.matrices.dense.MutableDenseMatrix]
- class zoomy_core.symbolic.BoxBoundary(parent, name=None)#
Bases:
_BoundaryDomainOpaque boundary of a
Box— same convention asSimplexBoundary.- Parameters:
parent (Domain) –
name (str) –
- class zoomy_core.symbolic.Domain(coords, name)#
Bases:
objectContinuous integration region in symbolic form.
Subclasses fill in geometry (vertices, intervals) and override
boundary,reference,affine_map,normalas appropriate for their shape.- Parameters:
coords (tuple[sympy.core.symbol.Symbol, ...]) –
name (str) –
- coords: tuple[sympy.core.symbol.Symbol, ...]#
- name: str#
- property dim: int#
- affine_map()#
Return
(B, V0)such thatx = V0 + B · ξmaps the reference element toself. Defined only on volume domains.- Return type:
tuple[sympy.matrices.dense.MutableDenseMatrix, sympy.matrices.dense.MutableDenseMatrix]
- normal()#
Return the
sympy.Functionclass for the outward unit normal onself. Defined only on boundary domains.- Return type:
type
- property boundary_integral_fn: type#
sympy.Functionsubclass for∫_∂(self) f dsatoms.One class per
Domaininstance. The back-referencecls._domainlets operations recover the surrounding domain. Renders in LaTeX as∮_{<name>} f \, dSvia the_latexmethod.
- property normal_fn: type#
sympy.Functionsubclass for outward unit normal components.Calls
n(i)carry the back-referencecls._domainso downstream operations can verify “this normal belongs to that boundary”. Renders in LaTeX asn_<name>^{(i)}.
- class zoomy_core.symbolic.Interval(var, a, b, name=None)#
Bases:
Domain1D interval
[a, b]parametrised by a singlevar.- Parameters:
var (sp.Symbol) –
name (str) –
- affine_map()#
Return
(B, V0)such thatx = V0 + B · ξmaps the reference element toself. Defined only on volume domains.- Return type:
tuple[sympy.matrices.dense.MutableDenseMatrix, sympy.matrices.dense.MutableDenseMatrix]
- zoomy_core.symbolic.NormalVector(domain)#
Return the
sympy.Functionclass for outward unit normal components ondomain.Usage:
n = NormalVector(K.boundary()) flux = sp.diff(u, x) * n(0) + sp.diff(u, y) * n(1)
- Parameters:
domain (Domain) –
- Return type:
type
- class zoomy_core.symbolic.PointSet(var, points, name=None)#
Bases:
_BoundaryDomainDegenerate 0-dim boundary — the boundary of an
Interval.Bridge to the existing
Subs(f, var, bound)plumbing inins_generator: aBoundaryIntegralover aPointSetis semanticallyf|_{var=b} − f|_{var=a}and resolves through that convention rather than producing a new symbolic kind.- Parameters:
var (sp.Symbol) –
points (Sequence) –
name (str) –
- property dim: int#
- class zoomy_core.symbolic.Simplex(vertices, coords, name=None)#
Bases:
Domainn-dim simplex from a vertex tuple.verticesis a sequence ofn+1points, each a tuple/Matrix of lengthn(matchingcoords).B = [V₁−V₀ | V₂−V₀ | …],V₀is the offset, and the affine map isx = V₀ + B · ξ.- Parameters:
vertices (Sequence) –
coords (tuple[sympy.core.symbol.Symbol, ...]) –
name (str) –
- boundary()#
- Return type:
- affine_map()#
Return
(B, V0)such thatx = V0 + B · ξmaps the reference element toself. Defined only on volume domains.- Return type:
tuple[sympy.matrices.dense.MutableDenseMatrix, sympy.matrices.dense.MutableDenseMatrix]
- class zoomy_core.symbolic.SimplexBoundary(parent, name=None)#
Bases:
_BoundaryDomainOpaque boundary of a
Simplex— one symbolic atom covers∂K(no per-face decomposition in this layer).- Parameters:
parent (Domain) –
name (str) –
Submodules#
- zoomy_core.symbolic.auto_eval_guard module
- zoomy_core.symbolic.canonicalise module
- zoomy_core.symbolic.domains module
- zoomy_core.symbolic.errors module
- zoomy_core.symbolic.primitives_basis module
- zoomy_core.symbolic.primitives_calculus module
- zoomy_core.symbolic.primitives_canonical module
- zoomy_core.symbolic.primitives_change_of_variable module
- zoomy_core.symbolic.primitives_substitution module
- zoomy_core.symbolic.sp_safe module