Skip to content

calculus

TimeDerivative(expr) dataclass

Bases: _CalcUnaryMixin, Expr

Time derivative d/dt{expr}. Preserves the type of its inner expression.

Source code in geomech/core/operations/calculus.py
def __init__(self, expr):
    self.nodes = [expr]

t_integrate()

∫(d/dt(x)) dt = x — cancellation.

Source code in geomech/core/operations/calculus.py
def t_integrate(self):
    """∫(d/dt(x)) dt = x — cancellation."""
    return self.expr

TimeIntegral(expr) dataclass

Bases: _CalcUnaryMixin, Expr

Time integral ∫{expr}dt. Preserves the type of its inner expression.

Source code in geomech/core/operations/calculus.py
def __init__(self, expr):
    self.nodes = [expr]

t_diff()

d/dt(∫x dt) = x — cancellation.

Source code in geomech/core/operations/calculus.py
def t_diff(self):
    """d/dt(∫x dt) = x — cancellation."""
    return self.expr

Variation(expr) dataclass

Bases: _CalcUnaryMixin, Expr

Variation operator δ{expr}. Preserves the type of its inner expression.

Source code in geomech/core/operations/calculus.py
def __init__(self, expr):
    from geomech.core.base.expressions import TS2, TSO3

    # δ(δ(...)) is a second-order variation — vanishes in Hamilton's principle
    if isinstance(expr, Variation):
        raise ValueError(
            f"Cannot take variation of a variation: δ(δ({expr.expr})). "
            f"Second-order variations vanish in Hamilton's principle."
        )
    # δ(ξ) or δ(η) where ξ/η are already variation vectors is nonsensical
    if isinstance(expr, TS2) and expr.S2 is not None:
        var_name = expr.S2.manifold_info.variation_vector_name
        if expr.name == var_name:
            raise ValueError(
                f"Cannot take variation of variation vector {expr}. "
                f"The variation vector is already an infinitesimal perturbation."
            )
    if isinstance(expr, TSO3) and expr.SO3 is not None:
        var_name = expr.SO3.manifold_info.variation_vector_name
        if expr.name == var_name:
            raise ValueError(
                f"Cannot take variation of variation vector {expr}. "
                f"The variation vector is already an infinitesimal perturbation."
            )
    self.nodes = [expr]

t_diff()

d/dt(δx) — put TimeDerivative on the outside.

δ and d/dt commute, but the expression tree produces TimeDerivative(Variation(x)) when taking the variation of d/dt(x). This override ensures the IBP target matches that structure.

Source code in geomech/core/operations/calculus.py
def t_diff(self):
    """d/dt(δx) — put TimeDerivative on the outside.

    δ and d/dt commute, but the expression tree produces
    TimeDerivative(Variation(x)) when taking the variation of d/dt(x).
    This override ensures the IBP target matches that structure.
    """
    return TimeDerivative(self)