Skip to main content

Material

Enum Material 

Source
pub enum Material {
Show 13 variants Elastic { e: f64, }, ElasticPP { e: f64, eyp: f64, ep: f64, }, Gap { e: f64, gap: f64, }, Ent { e: f64, }, Steel01 {
Show 15 fields fy: f64, e0: f64, b: f64, a1: f64, a2: f64, a3: f64, a4: f64, min_strain: f64, max_strain: f64, shift_p: f64, shift_n: f64, loading: Steel01Loading, strain: f64, stress: f64, tangent: f64,
}, Concrete01 { fpc: f64, epsc0: f64, fpcu: f64, epscu: f64, min_strain: f64, end_strain: f64, unload_slope: f64, strain: f64, stress: f64, tangent: f64, }, Steel02 {
Show 20 fields fy: f64, e0: f64, b: f64, r0: f64, cr1: f64, cr2: f64, a1: f64, a2: f64, a3: f64, a4: f64, min_strain: f64, max_strain: f64, pl_strain: f64, asymptote_strain: f64, asymptote_stress: f64, reversal_strain: f64, reversal_stress: f64, kon: Steel02Kon, strain: f64, stress: f64,
}, Concrete02 { fc: f64, epsc0: f64, fcu: f64, epscu: f64, rat: f64, ft: f64, ets: f64, min_strain: f64, tension_strain: f64, strain: f64, stress: f64, tangent: f64, }, Hysteretic(Box<HystereticFields>), Pinching4(Box<Pinching4Fields>), Parallel(Vec<(Material, f64)>), Series { children: Vec<Material>, child_strains: Vec<f64>, stress: f64, max_iter: usize, tol: f64, }, MinMax { inner: Box<Material>, min_strain: f64, max_strain: f64, failed: bool, },
}

Variants§

§

Elastic

Fields

§

ElasticPP

Elastic-perfectly-plastic, with real permanent-set tracking via the committed plastic strain ep — standard 1D return-mapping plasticity. Construct via Material::elastic_pp, not the struct literal: ep is internal history, not a material parameter, and must start at zero.

Fields

§eyp: f64
§ep: f64
§

Gap

One-sided gap: zero stiffness until the strain closes the gap (strain + gap < 0, i.e. compressive strain past the opening), then linear elastic. Stateless — a genuine function of current strain only (no permanent set to track), unlike ElasticPP.

Fields

§gap: f64
§

Ent

“No tension”: zero stiffness in tension (strain >= 0), linear elastic in compression. Equivalent to Gap { e, gap: 0.0 }, kept as its own variant since OpenSees exposes it separately and it’s the simplest possible nonlinear material (useful as the base case for element wiring tests). Stateless, same reasoning as Gap.

Fields

§

Steel01

Bilinear kinematic hardening with isotropic hardening on load reversal (Filippou 1983), ported from OpenSees’ Steel01. Construct via Material::steel01.

min_strain/max_strain track the largest excursion ever committed in each direction (used only to update shift_p/shift_n on a reversal, so they lag one reversal behind, exactly like OpenSees’ CminStrain/CmaxStrain); shift_p/shift_n are the isotropic hardening shifts applied to the bounding lines; strain/stress are the last committed point (needed because the bounding formula c = Cstress + E0*dStrain references it directly, not just the “obvious” history fields).

Fields

§fy: f64
§e0: f64
§a1: f64
§a2: f64
§a3: f64
§a4: f64
§min_strain: f64
§max_strain: f64
§shift_p: f64
§shift_n: f64
§loading: Steel01Loading
§strain: f64
§stress: f64
§tangent: f64

Committed tangent (OpenSees’ Ctangent). A trial at the committed strain returns it unchanged, so a displacement-control predictor sees the hardening tangent of a yielded fiber, not e0.

§

Concrete01

Kent-Scott-Park compression envelope with Karsan-Jirsa degrading unload/reload and zero tensile strength, ported from OpenSees’ Concrete01. Construct via Material::concrete01 — fpc, epsc0, fpcu, epscu are normalized negative (compression) at construction, matching the OpenSees convention.

min_strain is the most negative strain ever committed (drives the envelope); end_strain is where the current unload/reload line would cross zero stress (needed by reload’s branch to tell whether a trial strain is still on that line or must re-enter the envelope); unload_slope is that line’s slope; strain/stress are the last committed point (same reason as Steel01 above).

Fields

§fpc: f64
§epsc0: f64
§fpcu: f64
§epscu: f64
§min_strain: f64
§end_strain: f64
§unload_slope: f64
§strain: f64
§stress: f64
§tangent: f64

Committed tangent (OpenSees’ Ctangent), returned unchanged for a trial at the committed strain.

§

Steel02

Menegotto-Pinto transition curve with Filippou isotropic hardening, ported from OpenSees’ Steel02. Unlike Steel01‘s piecewise-linear bilinear rule, the loading/unloading branches are smooth curved asymptotes to the elastic and strain-hardening lines (parameters r0/cr1/cr2 control the transition sharpness). Construct via Material::steel02 — sigini (OpenSees’ optional initial-stress offset) is not supported, matching Material::steel01’s scope.

min_strain/max_strain are the peak strain reached on each side so far (Steel02’s epsmaxP/epsminP — note the reversed initial values vs. Steel01: Steel02 seeds them to ±fy/e0, not 0.0, so the very first reversal has a nonzero isotropic-hardening baseline); pl_strain/asymptote_strain/asymptote_stress are the strain at the last reversal’s plastic-excursion bound and the strain/stress where the current curve’s two asymptotes (elastic and strain-hardening) intersect (Steel02’s epsplP/epss0P/sigs0P); reversal_strain/reversal_stress are the point of the last load reversal (epssrP/sigsrP) — the curve’s other anchor. kon mirrors Steel02’s konP, minus its sigini-only pinned state.

Fields

§fy: f64
§e0: f64
§r0: f64
§cr1: f64
§cr2: f64
§a1: f64
§a2: f64
§a3: f64
§a4: f64
§min_strain: f64
§max_strain: f64
§pl_strain: f64
§asymptote_strain: f64
§asymptote_stress: f64
§reversal_strain: f64
§reversal_stress: f64
§kon: Steel02Kon
§strain: f64
§stress: f64
§

Concrete02

Concrete01‘s Kent-Scott-Park compression envelope plus linear tension softening and a stiffer reloading rule, ported from OpenSees’ Concrete02. Construct via Material::concrete02 — fc/epsc0/fcu/epscu are normalized negative, same as Concrete01.

min_strain is the most negative strain ever committed (Concrete02’s ecminP, same role as Concrete01’s min_strain); tension_strain is the peak tensile-excursion strain beyond the unload line’s zero-stress crossing (Concrete02’s deptP — the tension-side analogue of min_strain, with no Concrete01 equivalent since Concrete01 carries no tension branch at all).

Fields

§fc: f64
§epsc0: f64
§fcu: f64
§epscu: f64
§rat: f64
§ft: f64
§ets: f64
§min_strain: f64
§tension_strain: f64
§strain: f64
§stress: f64
§tangent: f64

Committed tangent (OpenSees’ eP), returned unchanged for a trial at the committed strain.

§

Hysteretic(Box<HystereticFields>)

Multi-linear (up to 3 points per side) backbone with pinching, deformation/energy-based damage, and ductility-degraded unloading stiffness, ported from OpenSees’ HystereticMaterial. Construct via Material::hysteretic.

Boxed (HystereticFields bundles ~30 fields — see its own doc comment) rather than inlined into the enum like every other leaf variant: Material’s size is its largest variant’s size, and without boxing this one, every Material — including the huge majority that are a plain Elastic { e: f64 } — would pay for the most field-heavy variant’s stack space, everywhere a Material is stored (Fiber, ZeroLength’s per-DOF array, every composite’s Vec<Material>). Pinching4 (stage 4’s other material) boxes the same way, for the same reason.

§

Pinching4(Box<Pinching4Fields>)

Four-point-per-side backbone with a pinched trilinear unload/reload path and three independent cyclic-damage rules (stiffness, strength, and deformation-demand degradation), ported from OpenSees’ Pinching4Material. Construct via Material::pinching4.

The most involved material in this catalog: a genuine 5-state machine (see Pinching4State) rather than the positive/negative/interior split every other path-dependent variant here uses, driven by an explicit strain bracket per state rather than re-derived thresholds.

Boxed for the same reason Hysteretic is (see above) — this one is larger still (~60 fields, including four 6-element envelope arrays).

§

Parallel(Vec<(Material, f64)>)

Composite: every child sees the same strain, stress/tangent are the factor-weighted sum. Ported from OpenSees’ ParallelMaterial — the factor defaults to 1.0 (see Material::parallel) but is kept explicit per OpenSees’ API.

§

Series

Composite: every child sees the same stress, total strain is the sum of the children’s individual strains. Not directly invertible (unlike Parallel), so evaluate runs its own small internal flexibility-based Newton loop, entirely self-contained within one call — see the type’s doc for why this doesn’t violate the trial/commit purity rule. child_strains is the last converged per-child strain split, kept explicitly (mirroring OpenSees’ own SeriesMaterial::strain[] array) since not every leaf material tracks its own committed strain. Construct via Material::series.

Fields

§children: Vec<Material>
§child_strains: Vec<f64>
§stress: f64
§max_iter: usize
§tol: f64
§

MinMax

Wraps one material with strain bounds: once a committed strain exits [min_strain, max_strain], failed becomes (and permanently stays) true — stress reads as 0.0, tangent as 1e-8 * inner.initial_tangent() (not exactly zero, to avoid handing back a structurally singular row/column — see OpenSees’ MinMaxMaterial::getTangent). Once failed, the inner material’s state is frozen (no further trial/commit reaches it), matching OpenSees’ Cfailed short-circuit. Construct via Material::min_max.

Fields

§inner: Box<Material>
§min_strain: f64
§max_strain: f64
§failed: bool

Implementations§

Source§

impl Material

Source

pub fn parallel(materials: Vec<Material>) -> Self

Equal-factor (1.0 each) parallel composite. For custom factors, build the Material::Parallel(Vec<(Material, f64)>) variant directly.

Source

pub fn series(children: Vec<Material>) -> Self

Series composite with OpenSees’ default tolerance (1e-10) and a generous internal iteration cap (30) — since, unlike OpenSees’ SeriesMaterial, evaluate can’t lean on many external Newton calls to slowly converge a warm-started trial state (see the type’s doc), the internal loop needs to reach convergence by itself.

Source

pub fn min_max(inner: Material, min_strain: f64, max_strain: f64) -> Self

Source§

impl Material

Source

pub fn concrete01(fpc: f64, epsc0: f64, fpcu: f64, epscu: f64) -> Self

fpc/epsc0/fpcu/epscu are normalized to be negative (compression), matching OpenSees’ Concrete01 constructor.

Source§

impl Material

Source

pub fn concrete02( fc: f64, epsc0: f64, fcu: f64, epscu: f64, rat: f64, ft: f64, ets: f64, ) -> Self

fc/epsc0/fcu/epscu are normalized to be negative (compression), matching OpenSees’ Concrete02 constructor. rat is the ratio between the unloading slope at epscu and the initial slope; ft/ets are the tensile strength and tension-softening modulus.

Source§

impl Material

Source

pub fn elastic_pp(e: f64, eyp: f64) -> Self

Source§

impl Material

Source

pub fn hysteretic( mom1p: f64, rot1p: f64, mom2p: f64, rot2p: f64, mom3p: f64, rot3p: f64, mom1n: f64, rot1n: f64, mom2n: f64, rot2n: f64, mom3n: f64, rot3n: f64, pinch_x: f64, pinch_y: f64, damfc1: f64, damfc2: f64, beta: f64, ) -> Self

The 3-point-per-side backbone constructor (OpenSees also offers a 2-point constructor that derives the midpoint as the average of the two given points — not ported, since a caller can just pass that average as mom2p/rot2p/mom2n/rot2n directly).

Debug builds assert the backbone is monotonic and one-to-one (0 < rot1p < rot2p < rot3p, rot1n < rot2n < rot3n < 0) — OpenSees hard-exits the process on this same precondition failure, which isn’t a library-appropriate response here.

Source§

impl Material

Source

pub fn pinching4( stress1p: f64, strain1p: f64, stress2p: f64, strain2p: f64, stress3p: f64, strain3p: f64, stress4p: f64, strain4p: f64, stress1n: f64, strain1n: f64, stress2n: f64, strain2n: f64, stress3n: f64, strain3n: f64, stress4n: f64, strain4n: f64, r_disp_p: f64, r_force_p: f64, u_force_p: f64, r_disp_n: f64, r_force_n: f64, u_force_n: f64, gamma_k_params: [f64; 4], gamma_k_limit: f64, gamma_d_params: [f64; 4], gamma_d_limit: f64, gamma_f_params: [f64; 4], gamma_f_limit: f64, gamma_e: f64, dmg_cyc: Pinching4DmgCyc, ) -> Self

Ported from Pinching4Material‘s full (asymmetric-backbone) constructor. OpenSees’ second overload — the one that mirrors the positive backbone onto the negative side and copies rDispP/rForceP/uForceP across — is not ported, for the same reason Material::hysteretic skipped its 2-point overload: a caller can pass the negated values directly.

The four-term damage parameter groups are taken as [f64; 4] arrays (gammaK1..gammaK4 etc.) rather than 12 separate scalars — a purely mechanical regrouping of OpenSees’ flat signature that keeps this under 30 arguments instead of 39.

Debug builds assert the backbone is one-to-one (all positive strains > 0, all negative strains < 0); OpenSees only prints a warning and carries on with a nonsensical envelope.

Source§

impl Material

Source

pub fn steel01( fy: f64, e0: f64, b: f64, a1: f64, a2: f64, a3: f64, a4: f64, ) -> Self

Source§

impl Material

Source

pub fn steel02( fy: f64, e0: f64, b: f64, r0: f64, cr1: f64, cr2: f64, a1: f64, a2: f64, a3: f64, a4: f64, ) -> Self

sigini (OpenSees’ optional initial-stress offset) is not supported — see the variant’s doc comment. Ten parameters is Steel02’s actual OpenSees signature (minus sigini/density), not something to trim for its own sake.

Source§

impl Material

Source

pub fn trial_stress_tangent(&self, strain: f64) -> (f64, f64)

(stress, tangent) for a trial evaluation at strain — read-only, safe to call any number of times from any Newton iteration. See the type-level doc comment for why this must never mutate self.

Source

pub fn commit(&self, strain: f64) -> Material

The new committed Material if strain were accepted as the converged state. Called once per converged step, by Domain::commit — see the type-level doc comment.

Source

pub fn initial_tangent(&self) -> f64

The tangent modulus at zero history — OpenSees’ getInitialTangent. Only needed by MinMax (for its post-failure tangent) and the composites (to propagate it to a wrapping MinMax).

Trait Implementations§

Source§

impl Clone for Material

Source§

fn clone(&self) -> Material

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 Material

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.