pub struct ForceBeamColumn {
pub node_i: NodeId,
pub node_j: NodeId,
pub density: f64,
/* private fields */
}Expand description
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.
Basic system. 3 dof, rigid-body-mode-free: v = [v1, v2, v3] where
v1 is axial elongation and v2/v3 are the end rotations relative to
the chord (θ_i - ψ, θ_j - ψ, ψ = (v2_local - v1_local)/L the
chord’s rigid-rotation) — the same objective quantity GeomTransf
implicitly builds into ElasticBeamColumn’s closed-form stiffness, made
explicit here because the flexibility method needs an isolated,
statically-determinate reduced system to define force-interpolation
functions on. Basic forces q = [q1, q2, q3] are q1 = axial force, and
q2/q3 are not simply the local nodal moments — the force
interpolation b(x) below (and the a_matrix/a_matrix_transpose map
between basic and local systems) were derived to be consistent with
DispBeamColumn’s already-verified curvature-displacement convention
(FiberSection’s M = -sum(stress*area*y), ElasticBeamColumn’s
closed-form 4EI/L/2EI/L pattern) and checked against
ElasticBeamColumn’s exact elastic stiffness in
core/tests/elements/force_beam.rs — that test is the actual source of
truth for these signs, not a textbook convention taken on faith.
State determination algorithm — ported directly from
xara/SRC/element/Frame/Other/Force/ForceBeamColumn2d.cpp’s
update() (the Neuenhofer-Filippou/Spacone-Ciampi-Filippou algorithm
that file’s header cites), not re-derived by hand; see
state_determination and
try_state_determination‘s
own doc comments for the mechanics (a two-stage per-section correction
each outer iteration, an energy-based convergence check, and a
bisection fallback when a single jump from v_commit to the target
v doesn’t converge directly) — done fresh on every call from
q_commit/e_commit/v_commit (see those fields’ doc comments for
why there’s no mutable trial cache). At convergence, the basic tangent
stiffness is F^-1 (F the element flexibility integral(b^T * f_s * b) dx) — the standard result for force-based elements, from
differentiating the equilibrium r(q, v) = 0 implicit relation.
Small-displacement by default, with an opt-in GeomTransf::Corotational
transformation that supplies objective chord-relative basic
deformations and the consistent geometric tangent.
BeamIntegration::Lobatto is the usual choice (endpoints included —
plastic hinges concentrate at member ends).
Element loads. A uniform local-axis load enters the section forces
exactly, which is the point of a force-based element: s(x) = b(x)·q + s_p(x), where s_p is the load’s own section force on the statically
determinate basic system (axial restrained at node i, simply supported in
bending: N_p = wx·(L−x), M_p = wy·x(x−L)/2). The load therefore
reaches state_determination, and the element’s nodal resistance is
Aᵀq — the load’s statically equivalent nodal forces (wx·L axial at
node i, w·L/2 shear at each end; form_load_vector) are the applied
side. This mirrors OpenSees’s ForceBeamColumn2d (sp and p0).
Fields§
§node_i: NodeId§node_j: NodeId§density: f64Mass per unit volume, applied uniformly over the section’s total
fiber area, same convention as DispBeamColumn. Zero (the default)
means massless.
Implementations§
Source§impl ForceBeamColumn
impl ForceBeamColumn
pub fn new( node_i: NodeId, node_j: NodeId, fibers: Vec<Fiber>, integration: BeamIntegration, ) -> Self
pub fn with_density(self, density: f64) -> Self
Sourcepub fn with_corotational(self) -> Self
pub fn with_corotational(self) -> Self
Use finite-rotation, chord-following kinematics for this member.
Sourcepub fn fiber_responses(&self) -> Vec<Vec<(f64, f64)>>
pub fn fiber_responses(&self) -> Vec<Vec<(f64, f64)>>
Every integration point’s per-fiber (strain, stress), read
directly from e_commit — unlike DispBeamColumn::fiber_responses,
no recomputation from nodal displacement is needed: e_commit
already is each section’s last-committed (eps0, kappa) (this
element’s own state-determination target, refreshed by commit —
see e_commit’s field doc comment), the same reason local_force
above is a plain cached read rather than a recomputation. Outer
Vec is one entry per integration point, inner Vec one entry per
fiber (the order originally passed to new).
Trait Implementations§
Source§impl Clone for ForceBeamColumn
impl Clone for ForceBeamColumn
Source§fn clone(&self) -> ForceBeamColumn
fn clone(&self) -> ForceBeamColumn
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for ForceBeamColumn
impl RefUnwindSafe for ForceBeamColumn
impl Send for ForceBeamColumn
impl Sync for ForceBeamColumn
impl Unpin for ForceBeamColumn
impl UnsafeUnpin for ForceBeamColumn
impl UnwindSafe for ForceBeamColumn
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T, U> Imply<T> for U
§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.