Skip to main content

ForceBeamColumn

Struct ForceBeamColumn 

Source
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: f64

Mass 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

Source

pub fn new( node_i: NodeId, node_j: NodeId, fibers: Vec<Fiber>, integration: BeamIntegration, ) -> Self

Source

pub fn with_density(self, density: f64) -> Self

Source

pub fn with_corotational(self) -> Self

Use finite-rotation, chord-following kinematics for this member.

Source

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

Source§

fn clone(&self) -> ForceBeamColumn

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ForceBeamColumn

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> ByRef<T> for T

§

fn by_ref(&self) -> &T

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.