Skip to content

trusty.boundary_conditions

Boundary conditions: Dirichlet (stitch, attach, soft pins) + Neumann (surface loads, pressure cavities) + cable actuation.

CableMode

Bases: Enum

Tension class-attribute instance-attribute

Tension = 0

Length class-attribute instance-attribute

Length = 1

stitch

stitch(
    world: World,
    follower: int,
    verts: Sequence[int],
    anchor: int,
) -> None

Kinematically bond verts (indices into the follower mesh's vertices) of follower onto anchor: the bonded verts carry no DOFs and their elastic energy is lifted onto the anchor's DOFs. follower must be a FEM, shell, or rod body; anchor is any body whose module supplies an interpolating point prolongation (FEM, embedded, affine or shell). Call before the first world.step(). When contact is built it bars the follower-vs-anchor pair itself, since a coincident bonded interface diverges the barrier.

attach

attach(
    world: World,
    follower: int,
    follower_verts: Sequence[int],
    anchor: int,
    stiffness: float = 1000000.0,
) -> None

Pin follower_verts (indices into the follower mesh's nodes) of follower to anchor with a stiff penalty spring (0.5stiffnesssum|x_follower - x_anchor|^2). Unlike stitch, neither side's DOFs are eliminated -- the bond is an energy term, so it works when the bonded point is not itself a DOF (subspace x0+Bz, affine A x_bar + p). The follower bonds at its nodes (subspace, FEM); the anchor interpolates them at their rest positions (FEM, affine, embedded, subspace, shell). Replaces the old subspace.add_attachment. Call before the first world.step().

pin_to_target

pin_to_target(
    world: World,
    body: int,
    nodes: Sequence[int],
    targets: ndarray[float64, (N, 3)],
    stiffness: float,
) -> int

Pin nodes of body toward the matching rows of targets with the one-sided spring 0.5 * k * V_node * |x - t|^2, where V_node is the lumped nodal volume -- so k is a stiffness density (Pa) and the condition is mesh-resolution-independent. Works on any body whose vertices are nodal DOFs (FEM solid, shell, rod). Returns the pin entity. Use this when the body is also tracked by IPC contact -- hard Dirichlet would silently violate the barrier.

set_pin_targets

set_pin_targets(
    world: World,
    pin: int,
    targets: ndarray[float64, (N, 3)],
) -> None

Update a pin's targets, shape (len(nodes), 3). pin is a handle from pin_to_target. Takes effect on the next step.

set_pin_stiffness

set_pin_stiffness(
    world: World, pin: int, stiffness: float
) -> None

Update a pin's stiffness (Pa). Takes effect on the next step.

pin_nodes

pin_nodes(world: World, pin: int) -> list[int]

pin_targets

pin_targets(
    world: World, pin: int
) -> ndarray[float64, (N, 3)]

pin_stiffness

pin_stiffness(world: World, pin: int) -> float

pin_forces

pin_forces(
    world: World, pin: int
) -> ndarray[float64, (N, 3)]

Per-node spring force k * V * (x - t) from the last accepted step, as a (len(nodes), 3) array. Zero before the first step.

pin_total_force

pin_total_force(
    world: World, pin: int
) -> tuple[float, float, float]

Sum of per-node forces for the given pin as a 3-tuple.

num_pins

num_pins(world: World, body: int) -> int

Number of spring pins attached to a body.

set_tractions

set_tractions(
    world: World,
    load: int,
    tractions: ndarray[float64, (N, 3)],
) -> None

Replace the load's whole field: num_faces x 3, row k the traction on load_faces[k]. Takes effect on the next step.

tractions

tractions(
    world: World, load: int
) -> ndarray[float64, (N, 3)]

The load's current per-face tractions, num_faces x 3 (Pa, world frame).

num_loaded_faces

num_loaded_faces(world: World, load: int) -> int

Faces the load's traction field spans (rows of tractions).

attach_surface_load

attach_surface_load(
    world: World,
    body: int,
    load_faces: Sequence[int],
    tractions: ndarray[float64, (N, 3)],
) -> int

Attach a Neumann surface load to body: prescribe per-face tractions (|load_faces| x 3, Pa, world frame; row k the traction on load_faces[k]) over load_faces (indices into the body's boundary-surface triangles). Use np.tile(t, (len(load_faces), 1)) for a load that is the same on every face. Dead load -- world-frame traction over the rest area, discretization-agnostic and contact-free. Call before the first step. Returns the load entity, a child of body; a body may carry several, each retargeted with boundary_conditions.set_tractions(world, load, ...).

add_pressure_cavity

add_pressure_cavity(
    world: World,
    body: int,
    faces: Sequence[int],
    pressure: float = 0.0,
) -> int

Drive the volume enclosed by faces (indices into the body's boundary-surface triangles, e.g. one component of trusty.triangle_components) with a gauge pressure (Pa): the conservative potential -pressure * V(x), a follower pressure on the cavity walls. The faces must close; an internal void of a solid and a closed shell both work, whichever way they are wound. Returns the cavity entity.

set_cavity_pressure

set_cavity_pressure(
    world: World, cavity: int, pressure: float
) -> None

Set a cavity's gauge pressure (Pa). Takes effect on the next step.

cavity_volume

cavity_volume(world: World, cavity: int) -> float

Volume (m^3) the cavity encloses at the last accepted step. Raises before the first step.

add_cable

add_cable(
    world: World,
    body: int,
    points: ndarray[float64, (N, 3)],
    mode: CableMode = CableMode.Tension,
    stiffness: float = 10000.0,
) -> int

Attach a cable (tendon) to body through rest-space points ((n >= 2, 3), meters, path order). Each point moves as the body interpolates it, so the cable can run through the interior or along the skin. FEM (any element), embedded, affine and subspace bodies take points inside their rest volume, shells points on their rest midsurface; rods and MPM carry no cable. mode (CableMode.Tension, the default, or CableMode.Length) is fixed for the cable's life. stiffness is its axial stiffness EA / L0 (N/m), read by the Length mode; the default is a 0.5 mm nylon tendon about 4 cm long. The cable starts slack: zero tension, or a target length equal to its rest length. Returns the cable entity.

set_cable_tension

set_cable_tension(
    world: World, cable: int, tension: float
) -> None

Set a Tension cable's tension (N, >= 0): energy T * L. Takes effect on the next step; raises for a Length cable.

set_cable_length

set_cable_length(
    world: World, cable: int, length: float
) -> None

Set a Length cable's target length (m): a winch sets its rest length to length, so energy 0.5 * k * max(L - length, 0)^2 with the cable's stiffness k; it goes slack once shorter. Takes effect on the next step; raises for a Tension cable.

cable_mode

cable_mode(world: World, cable: int) -> CableMode

cable_length

cable_length(world: World, cable: int) -> float

Path length at the last accepted step (m); the rest length before the first.

cable_tension

cable_tension(world: World, cable: int) -> float

Tension at the last accepted step (N); 0 before the first.

cable_points

cable_points(
    world: World, cable: int
) -> ndarray[float64, (N, 3)]

World positions of the cable points at the last accepted step, (n, 3); the rest points before the first.

num_cables

num_cables(world: World, body: int) -> int

Number of cables attached to a body.