Skip to content

trusty.embedded

Embedded (voxelized) elasticity with Nitsche weak Dirichlet BCs.

add_embedded_solid

add_embedded_solid(
    world: World,
    V: ndarray[float64, (N, M)],
    F: ndarray[int32, (N, M)],
    voxel_size: float,
    material: StableNeoHookean
    | Corotational
    | StableFung
    | NeohookeanBW
    | ARAP
    | QuadraticVolume,
    density: float,
    *,
    sizing_field: Callable[[ndarray[float64, (3,)]], float]
    | None = None,
    max_level: int = 0,
    order: ElementOrder = fem.ElementOrder.Linear,
    friction_mu: float = 0.0,
) -> int

Voxelize (V, F) into a hex solid. The keyword-only tail (sizing_field, max_level) configures the grid: pass a sizing_field callable (world point -> target edge length) with max_level > 0 for adaptive refinement, and voxel_size is then the coarsest cell size. order selects Q1/Q2 interpolation. friction_mu is the body's surface Coulomb coefficient (>= 0); 0 is frictionless.

attach_weak_pin

attach_weak_pin(
    world: World,
    body: int,
    pin_faces: Sequence[int],
    initial_targets: ndarray[float64, (N, 3)],
    gamma: float = 10.0,
) -> None

Attach a Nitsche weak-pin BC to body. A body carries at most one, so embedded.set_pin_targets(world, body, new_targets) addresses it by the body -- there is no separate handle to keep.

set_pin_targets

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

Move a weak pin's targets, shape (n_input_verts, 3). Takes effect on the next step.

pin_targets

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

Current target positions, shape (n_input_verts, 3).

pin_detached

pin_detached(world: World, body: int) -> bool

Whether detach_weak_pin has been called on this pin.

detach_weak_pin

detach_weak_pin(world: World, body: int) -> None

Detach a weak pin: the term it drives stops contributing (free boundary) from the next step. One-way; mirrors attach_weak_pin.

read_embedded_surface

read_embedded_surface(
    world: World, body: int
) -> ndarray[float64, (N, 3)]

surface_triangles

surface_triangles(
    world: World, body: int
) -> ndarray[int32, (N, 3)]

prolong_nodal_field

prolong_nodal_field(
    world: World, body: int, nodal: ndarray[float64, (N,)]
) -> ndarray[float64, (N,)]

Interpolate a per-hex-node scalar field (length = hex-node count, e.g. nodal von Mises from fem.read_von_mises(..., nodal=True)) onto the embedded surface vertices via the body's trilinear prolongation -- the same map read_embedded_surface uses for positions. Returns one value per surface vertex.