Skip to content

manifold_rules

Manifold kinematic substitutions applied during EOM derivation.

For S2 (unit sphere) with manifold point q, tangent vector ω, variation vector ξ: - Variation(ω) → ξ̇ - ω × ξ (derived from δ/d/dt commutativity)

For SO3 (rotation group) with tangent vector Ω, variation vector η: - Variation(Ω) → η̇ + Ω × η (body-frame angular velocity convention)

The expansion of δ(ω) follows from the commutativity of δ and d/dt on the action integral. Starting from q̇ = ω × q and δq = ξ × q, setting δ(q̇) = d/dt(δq) and solving for δ(ω) gives δ(ω) = ξ̇ - ω × ξ.

Similarly, for SO3 with Ṙ = R·Hat(Ω) and δR = R·Hat(η), commutativity of δ and d/dt gives δ(Ω) = η̇ + Ω × η.

apply_manifold_rules(expr, variables)

Apply manifold kinematic substitutions to an expression.

Walks the expression tree and replaces Variation(TS2) and Variation(TSO3) nodes with their kinematic expansions.

Source code in geomech/core/transformations/manifold_rules.py
def apply_manifold_rules(expr, variables: SystemVariables):
    """Apply manifold kinematic substitutions to an expression.

    Walks the expression tree and replaces Variation(TS2) and
    Variation(TSO3) nodes with their kinematic expansions.
    """
    tangent_map = {}

    # S2 manifolds (vectors)
    for vec in variables.vectors:
        if isinstance(vec, S2):
            omega = vec.get_tangent_vector()
            xi = vec.get_variation_vector()
            tangent_map[str(omega)] = ("S2", vec, omega, xi)

    # SO3 manifolds (matrices)
    for mat in variables.matrices:
        if isinstance(mat, SO3):
            Omega = mat.get_tangent_vector()
            eta = mat.get_variation_vector()
            tangent_map[str(Omega)] = ("SO3", mat, Omega, eta)

    if not tangent_map:
        return expr

    return _substitute(expr, tangent_map)