zoomy_core.model.equation#
Equation primitives — Term, _TermGroup, Equation.
Direct port of the framework developed in the transparent-derivation
notebooks (thesis/notebooks/legacy/modeling/transparent_derivations/ sme_clean.py etc.). Same classes, same auto-history mechanics, same
simplify pipeline (sp.expand → pull var-independent factors out of
Derivative atoms → recover fluxes by pulling var-independent coeffs back
inside Derivative arguments).
Lives in its own module so the Model class (in basemodel.py) and
the derivation subclasses (sigmaref.py, sme.py, vam.py) can import
Equation without dragging in the full operations / state surface.
Module Contents#
Classes#
API#
- class zoomy_core.model.equation.Term(expr, tag=None, parent=None)#
One additive term of an
Equation.Initialization
- apply(*args, **kwargs)#
- class zoomy_core.model.equation.Equation(expression, name='eq', model=None)#
Bases:
zoomy_core.model.operations.RelationMixinLinear list of
Termcarrying the residual of one PDE/algebraic equation.applydelegates toExpression.apply(the library operation-dispatch layer) and auto-records a history entry on the parentModelif one is set.Via
RelationMixinan Equation can be ORIENTED — built fromsp.Eq(lhs, rhs)or produced bysolve_for— in which case it carries_as_relation = {lhs: rhs}and acts as a substitution under.apply(with.lhs/.rhs/.subs_map). That is what replaces the formerSubstitution/Relationclasses.Initialization
- property solver_tags#
Dict of solver tags (canonical names) → sub-expression, or empty dict if none set.
- get_solver_tag(name)#
Return the sp.Expr for a solver tag, or None if not set.
nameis normalised throughcanonical_solver_tag.
- untagged_remainder()#
Return
self.expr - sum(solver_tags.values()), simplified. Zero ⇒ every term has been routed to a solver tag; non-zero drivescollect_solver_tag’suntagged_policy.
- static to_terms(expression)#
- static to_expression(terms)#
- property expr#
- property terms#
- property term#
ADDITIVE-TERM accessor —
eq.term[i](one term),eq.term[i, j]/eq.term[[i, j]](a term group). Each view’s.apply(op)rewrites ONLY those terms back into this equation.Disambiguated from
[l]MOMENT access (MomentFamily/VectorEquation): a scalarEquationis no longer term-indexable via bareeq[i]— useeq.term[i].
- apply(*args, **kwargs)#
- simplify()#
Canonical form (three sub-steps):
sp.expand— flatten Mul/Add nesting and combine like terms.Pull var-independent factors out of every Derivative argument:
Derivative(g·h, x) → g·Derivative(h, x),Derivative(0, x) → 0.Recover fluxes — for each term
c · Derivative(_, x)wherecis var-independent, pullcback inside so the tagger sees the conservative atom.
- solve_for(symbol)#
Algebraically isolate
symbolfrom this equation’s residual (self.expr == 0); returns a NEW orientedEquationsymbol = solved-expr(carrying_as_relation = {symbol: sol}).The result stays an Equation — pass it straight to
.applyand it acts as the substitutionsymbol -> sol(.lhs/.rhs/.subs_mapexpose the rule). This is what the oldSubstitutionreturn value did, with no separate class.Pure algebra —
solve_fordoes not integrate. Ifsymbolappears under aDerivativethe residual is differential in it; integrate the balance first (e.g.eq.apply(Integrate(var, lo, hi))followed by a boundary-condition substitution) and thensolve_forthe resulting algebraic relation.
- remove()#
Delete this equation from its parent model (triggers Q refresh).
- describe(strip_args=False, header=True, show_tags=False)#
Render this equation as a
Description.Terms print in their current order (so a
SortByTagshows). An oriented equation (fromsolve_for/sp.Eq) renderslhs = rhsrather thanresidual = 0.show_tags=Trueunderbraces each physics-tag group.
- describe_line(strip_args=False, bullet=False, show_tags=False)#
One-line markdown render (used by
Model.describe). An oriented equation renders aslhs = rhs; a plain residual as… = 0with terms in their current order.show_tagsunderbraces each tag group (same render asdescribe).