Skip to main content

Module model

Module model 

Source

Modules§

continuum
Isoparametric machinery shared by the continuum elements: shape functions and their reference derivatives (shape), Gauss rules (quadrature), the Jacobian and physical derivatives (jacobian), and scale-aware geometry validation (validate). Everything here is dimension-agnostic bookkeeping; what is specific to an element (the B matrix shape, the constitutive reduction) stays in the element.

Structs§

DispBeamColumn
A 2-node, displacement-based, fiber-discretized 2D beam-column: nodal displacements directly give the strain/curvature field along the length (cubic Hermite transverse + linear axial shape functions, same as ElasticBeamColumn’s), each BeamIntegration point’s FiberSection converts that to stress-resultants, and one length-integral gives the element’s resisting force/tangent — a single, direct evaluation, unlike ForceBeamColumn, which needs its own internal equilibrium iteration per element.
DispBeamColumn3
DispBeamColumn’s spatial (biaxial) counterpart: a 2-node, displacement-based, fiber-discretized 3D beam-column. Bending in both planes comes directly from FiberSection3 the same way DispBeamColumn gets its single bending plane from FiberSection; torsion is not fiber-derived (see FiberSection3’s doc comment) and is instead a simple decoupled elastic G*J/L term, folded directly into the local tangent/resistance alongside the fiber-integrated axial/biaxial-bending terms — the same decoupling ElasticBeamColumn3 uses for torsion.
DofMask
Which node DOF slots an element touches, one bit per slot. One mask per element, applied to every node the element connects.
Domain
Owns all nodes, elements, and load patterns. No serialization/broker machinery — this is the whole model, in memory, for one worker. Clone backs Analysis/TransientAnalysis’s snapshot-and-restore-on- failure (a failed step shouldn’t leave nodal displacement/velocity/ acceleration partway through a discarded Newton iteration) — see Material’s doc comment for why materials themselves don’t need this protection. Also what makes multi-phase analysis composition possible: Analysis::into_domain/TransientAnalysis::into_domain hand this same Domain (nodal state, committed material history, and load-pattern freeze state all intact) to the next phase’s builder.
ElasticBeamColumn
A 2-node, prismatic, linear-elastic 2D beam-column (Euler-Bernoulli, no shear deformation): closed-form stiffness, no iteration — unlike Truss/ZeroLength, there’s no Material dispatch here, since the element’s response is fully determined by e/a/iz with no nonlinear stress-strain law to evaluate.
ElasticBeamColumn3
ElasticBeamColumn’s spatial counterpart: a 2-node, prismatic, linear-elastic 3D Euler-Bernoulli beam-column (E, G, A, J, Iy, Iz), closed-form, GeomTransf3::Linear3 only — see this struct’s module-level context for why 3D P-Delta isn’t implemented yet: it needs force/tangent recovery already consistent in the linear case first.
Element3Id
Generational index into Domain3’s element store. Distinct from ElementId for the same reason Node3Id is distinct from NodeId (see its doc comment).
ElementForce
An element’s local nodal force (or equivalent-load) vector, for results recording. Its length is ElementOps::local_force_width. Heap-backed: this is only ever used on recorder paths, never in assembly.
ElementId
Generational index into Domain’s element store.
ElementLoad
The load on a 2D element: an additive accumulator with one field group per load kind, so that the sum of every pattern’s load on an element (each scaled by its factor) is just a field-wise sum. Uniform + Body is simply both fields set. Which kinds an element accepts is decided by ElementOps::accepts_load, checked by Domain::validate before any load is accumulated.
ElementLoad3
ElementLoad’s 3D counterpart: an additive accumulator, one field group per load kind. ElementOps::Load for the 3D profile.
Fiber
One fiber: a small patch of cross-section area at distance y from the section centroid, carrying a Material. 2D only: y alone, no z, since bending is about the section’s local z-axis only.
Fiber3
FiberSection’s spatial (biaxial) counterpart: each fiber carries both a y and a z coordinate, since bending can now occur about either local section axis. Torsion is deliberately not modeled here — a fiber’s uniaxial material only sees axial strain, so torsional stiffness needs a separate (elastic, G*J) term, kept on the element (DispBeamColumn3/ForceBeamColumn3) rather than the section, the same decoupled treatment ElasticBeamColumn3 already uses. This mirrors Xara’s FiberSection3d, which likewise keeps torsion out of the fiber loop and folds it in afterward via a separate elastic term.
FiberSection
A fiber-discretized cross-section: given the section’s axial strain eps0 (at the centroid) and curvature kappa, each fiber’s strain is eps0 - y*kappa. Work-conjugate to [eps0, kappa] is [N, M] (N = sum(stress*area), M = -sum(stress*area*y)) — derived directly from virtual work, not assumed: d(stress power) = integral(stress * d(strain)) dA = integral(stress*(d(eps0) - y*d(kappa))) dA = d(eps0)*N + d(kappa)*M with M as defined above.
FiberSection3
Biaxial fiber-discretized cross-section: given axial strain eps0, curvature about local z kappa_z (bending that displaces local y, the plane FiberSection/ElasticBeamColumn3’s Iz governs), and curvature about local y kappa_y (displaces local z, Iy’s plane), each fiber’s strain is eps0 - y*kappa_z + z*kappa_y — the natural biaxial extension of FiberSection’s eps0 - y*kappa, verified against Xara’s FiberSection3d::addFiber/getStressResultant (matData/sData layout: strain = e0 - y*e1 + z*e2, N = sum(stress*A), Mz = sum(-y*stress*A), My = sum(z*stress*A)) rather than re-derived from scratch.
ForceBeamColumn
A 2-node, force-based (flexibility-method) 2D beam-column: unlike every other element in the catalog, its section forces are determined directly from the element’s basic (reduced, rigid-body-mode- free) end forces via statics-exact force-interpolation functions — always in equilibrium, regardless of material state — while section deformations (and hence the element’s tangent) come from inverting each section’s nonlinear force-deformation response. That inversion is why this element needs its own internal Newton iteration (state_determination) every time form_tangent_and_resistance is called, instead of a single direct evaluation like DispBeamColumn.
ForceBeamColumn3
ForceBeamColumn’s spatial (biaxial) counterpart: a 2-node, force-based 3D beam-column. Basic system, force interpolation, and state- determination algorithm are the direct biaxial generalization of ForceBeamColumn’s (see that type’s doc comment for the algorithm itself, ported unchanged in structure — only NSD/NBD and the matrices below grow); torsion is excluded from the basic system and handled as a decoupled elastic G*J/L term, same as DispBeamColumn3.
Friction
Couples one “shear” DOF to a different DOF’s own material — the normal direction’s current force — via a bilinear-kinematic-hardening Coulomb return map: sticks (stiffness k0) until |V| reaches mu * yield-eligible normal force, then slides with post-slip tangent b*k0 (see the b field doc comment for why b is required, not optional).
Friction3
Friction’s spatial counterpart: one normal DOF, two shear DOFs, each run independently through Friction’s return map against the same normal force (a square, not circular, interaction surface between the two shear directions — the physically correct circular friction cone is a materially harder shared-slip-vector return-map problem, deferred until needed).
GaussResponse
One integration point’s committed strain and stress, for continuum elements. Plane elements report [x, y, xy] with engineering shear (PlaneMaterial’s convention).
LoadPatternId
Generational index into Domain’s load-pattern store.
Node
A node in a concrete kinematic profile. Coordinates have NDIM components; state, boundary conditions, and mass have NDOF components. Node defaults to the existing planar (2, 3) profile, so its public API remains source-compatible; Node3 is the spatial (3, 6) specialization.
Node3Id
Generational index for a future spatial Domain3 node store. It is distinct from NodeId, so planar elements cannot connect to spatial nodes at compile time.
NodeId
Generational index into the planar Domain node store. Stays valid across removals of other nodes; using a stale key against a different domain is a logic error the type cannot catch, but a use-after-free within one domain’s lifetime is.
NodeView
Read access to the domain’s nodes, handed to every element method that needs node coordinates or state. A thin wrapper so the element interface does not expose how Domain stores nodes.
Orientation
Local axes of a zero-length element, built the OpenSees way. In 3D that is -orient x1 x2 x3 yp1 yp2 yp3: local x is x, local z is x × yp, and local y is z × x. In 2D OpenSees takes only x (see in_plane) and derives y by a 90 degree turn. Every per-DOF material (and a section’s axial and flexural directions) is then evaluated on the relative displacement and rotation projected onto these axes rather than the global ones. Without an orientation the local axes are the global axes.
Quad4
Shell3
Shell4
ShellResponse
One shell integration point’s committed generalized strain and stress resultants in the element’s local axes, in ShellSection’s ordering and sign convention: [eps_x, eps_y, gamma_xy, kappa_x, kappa_y, 2 kappa_xy, gamma_xz, gamma_yz] and [Nx, Ny, Nxy, Mx, My, Mxy, Qx, Qy].
Tri3
Truss
A 2-node axial truss: fixed-size element-local linear algebra, no heap allocation in the hot path. Only ever populates the translational DOF entries of the (3-DOF-per-node) local/global matrices; the rotation entries stay zero. Its dof_mask is therefore translations only, so a node connected only to trusses has no rotation unknown and the model need not fix it.
Truss3
A small-displacement axial 3D truss.
ZeroLength
A 2-node, zero-length connector: no geometry or integration, just direct per-DOF material evaluation — each direction with a material assigned independently relates that DOF’s relative displacement between the two nodes to a force along that same direction. Directions are the global DOF axes (including rotation) unless an Orientation (OpenSees’ -orient) rotates them to local axes.
ZeroLength3
ZeroLength‘s spatial counterpart: independent per-DOF materials along the six directions [ux, uy, uz, rx, ry, rz] — global by default, or the local axes of an Orientation (OpenSees’ -orient). friction — see ZeroLength’s doc comment — adds two independent (see Friction3) shear-DOF couplings on top of the independent materials.
ZeroLengthSection
A 2-node, zero-length connector driven by a coupled FiberSection instead of ZeroLength’s independent per-DOF materials — the axial (ux) and flexural (rz) response come out of the same fiber discretization, so axial force and bending moment interact through shared fiber strain, the way a concentrated-plasticity “fiber hinge” needs (e.g. at a beam-column end) and ZeroLength structurally cannot produce. Modeled on OpenSees/Xara’s ZeroLengthSection (SRC/element/Point/ZeroLengthSection.cpp): the section’s basic deformation is the direct nodal DOF difference (no shape functions or integration — there’s no length to integrate over), and K/P are Bᵀ*k_section*B/Bᵀ*q with B selecting [ux, rz], the same pattern DispBeamColumn::form_tangent_and_resistance uses per integration point (here with a single “point” and unit scale).
ZeroLengthSection3
ZeroLengthSection’s spatial counterpart: coupled axial-biaxial-moment response (ux, ry, rz) from a FiberSection3, plus optional independent springs (via with_material) for uy, uz (shear) and rx (torsion) — the three DOFs the section has no resultant for. FiberSection3 deliberately excludes torsion from its fiber loop (see its doc comment), and there’s no meaningful G*J/length term at zero length the way DispBeamColumn3 has, so an explicit rx material is the only way to give this element torsional stiffness at all.

Enums§

Axis3
A global coordinate axis (0..SPATIAL_NDIM) — used where a spatial API needs to name one of [x, y, z] itself rather than a DOF (e.g. Domain3::rigid_diaphragm_about’s diaphragm-normal parameter), where a bare usize would silently also accept a rotational SpatialDof index. as usize gives the matching translational SpatialDof/coordinate index directly (Axis3::Y as usize == SpatialDof::Uy as usize == 1).
BeamIntegration
Numerical integration scheme along a frame element’s length, relating per-section response (FiberSection) to element-level response — needed by DispBeamColumn. Closed enum.
Element
Element catalog. Closed enum, match-based dispatch, no Box<dyn Trait> .
Element3
3D element catalog — Domain3’s counterpart to Element. Closed enum, match-based dispatch, same reasoning as Element.
GeomTransf
Coordinate-transformation strategy for planar frame elements: relates an element’s local (basic) stiffness/forces to the global system. The co-rotational option follows the deformed chord and removes rigid-body translation/rotation from the element’s basic deformations.
GeomTransf3
GeomTransf’s spatial counterpart: builds a member’s local basis and local↔global rotation from its two end-node coordinates and an orientation vector (vec_xz): x = normalize(pJ - pI), y = normalize(vec_xz × x), z = x × y). Unlike planar GeomTransf, this isn’t just a behavior flag: the local-axis construction is real, nontrivial, and shared by every spatial frame element (ElasticBeamColumn3 today; DispBeamColumn3/ForceBeamColumn3 will reuse it once they exist), so it’s a real type rather than something each element inlines a copy of. Verified against Xara’s LinearCrdTransf3d.
LoadSeries
The pseudo-time-to-load-factor function a LoadPattern scales its reference loads by — Xara/OpenSees’s TimeSeries family, cut down to exactly the three shapes Carapace’s scope actually needs (Trig/ Rectangular/Pulse etc. are for shaping a dynamic excitation pattern, not a quasi-static load/displacement protocol — out of scope until something needs them). Closed enum.
Material
ModelError
A model that cannot be analyzed as built, found by Domain::validate before any equation is assembled. Node and element indices are insertion order (the order the objects were added to the Domain), so a caller that created them from a table can map them straight back to a row.
OrientationError
Pinching4DmgCyc
Pinching4Material’s DmgCyc flag (a raw int in OpenSees): whether the second damage term is driven by the dissipated-energy ratio (DmgCyc == 0) or by an accumulated half-cycle count (DmgCyc == 1).
Pinching4State
Pinching4Material’s Cstate/Tstate — an int 0..4 in the OpenSees source, modelled here as a real enum.
PlaneMaterial
PlaneMaterialError
Why a PlaneMaterial’s constants are unusable.
Quad4Formulation
Which displacement field the element uses.
ShellSection
ShellSectionError
Why a ShellSection’s constants are unusable.
SpatialDof
Named spatial DOF indices, in the order used by every future spatial element/result/worker record.

Constants§

ELEMENT_DOF
2 * NDF — the size of a 2-node element’s local/global stiffness and force vectors. A named constant instead of a const expression because stable Rust’s const generics can’t yet compute 2 * NDF inline at each SMatrix/SVector use site.
MAX_ELEMENT_NODES
The most nodes any element in this crate connects: two-node frame elements, three- and four-node planar elements (2D membranes, 3D shell triangles and quadrilaterals). 3D solid elements are not planned.
NDF
Degrees of freedom per node: 2D translation (x, y) plus in-plane rotation (z). The third DOF carries ElasticBeamColumn’s bending. A node’s DOF becomes an equation only if something uses it (an element stiffens it, a constraint ties to it, it carries a mass, or it is fixed), so a node connected only to trusses has no rotation unknown and needs none fixed by hand (see Domain::is_active).
PLANAR_NDIM
Planar coordinate components [x, y].
SPATIAL_ELEMENT_DOF
Two-node spatial element DOFs: six at node i followed by six at node j.
SPATIAL_NDF
Spatial frame degrees of freedom [ux, uy, uz, rx, ry, rz].
SPATIAL_NDIM
Spatial coordinate components [x, y, z].

Traits§

ElementLoadComponents
Scalar view of an element load’s components (local axes), for recording the load an element actually carries at some pseudo-time.
ElementOps
What Domain’s generic assembly/state plumbing needs from an element catalog. A trait rather than a shared enum because Element (2D) and Element3 (3D) hold different variant sets, and a single enum would either duplicate every variant or need Box<dyn Trait> in the assembly loop. NDIM/NDOF are separate const generics (not computed from each other) because stable Rust cannot evaluate 2 * NDOF in a generic item.
TangentSink
Receives an element’s tangent stiffness k and internal resisting force r, indexed by the element’s DOFs dofs (row a of k and entry a of r belong to dofs[a]).
VectorSink
Receives a vector indexed by an element’s DOFs: an equivalent nodal load or a lumped mass.

Functions§

two_node_dofs
DOFs of a two-node element laid out as [all of node i's slots, all of node j's slots]; N must equal 2 * ndof.

Type Aliases§

DofRef
One element DOF: (node, slot), where slot indexes the node’s profile DOFs (ux, uy, rz in 2D; ux..rz in 3D).
Domain3
Domain’s spatial instantiation — six-DOF Node3/Element3. See Domain’s doc comment for why this is a type alias over one generic implementation rather than a hand-duplicated struct.
Node2
Explicit planar node specialization, useful where a profile must be named rather than inferred from Node’s default generic parameters.
Node3
Explicit spatial node specialization. It shares the node implementation with planar Node; only fixed array dimensions differ.
NodeList
The nodes an element connects, in the element’s own local order.
PlaneMatrix
The 3x3 plane constitutive tangent.
PlaneVector
A plane strain or stress vector [x, y, xy] (engineering shear for strain).
ShellMatrix
The 8x8 section tangent.
ShellVector
Generalized shell strain or resultant: membrane (3), bending (3), transverse shear (2).
SpatialElementMatrix
Fixed-size spatial two-node element tangent/resistance pair types.
SpatialElementVector