forked from 1b-agent/fieldcraft-upstream
solver, model: imperfections from buckling modes in nonlinear steps
NonlinearStatic.imperfection {step, mode, scale}: the buckling step's mode, scaled to a largest
component of `scale`, is added to the node coordinates before the step is solved, with a warning
naming it; Abaqus and LS-DYNA decks refuse it by name. A clamped–free column with its first mode
as imperfection under half its buckling load amplifies it by 1/(1 − α) within 2.8 %.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
788edbbddd
commit
0bb1c2462f
7 files changed
+119
-6
No files matched your search
@@ -67,7 +67,7 @@ pub use mesh::{
|
||||
pub use sections::{BeamProfile, Extent, Formulation, Integration, Section, SectionKind};
|
||||
pub use sets::Set;
|
||||
pub use steps::{
|
||||
BulkViscosity, ExplicitDynamic, Hourglass, HourglassKind, InitialVelocity, MAX_LOAD_PATH_POINTS, MAX_NONLINEAR_INCREMENTS,
|
||||
BulkViscosity, ExplicitDynamic, Hourglass, HourglassKind, Imperfection, InitialVelocity, MAX_LOAD_PATH_POINTS, MAX_NONLINEAR_INCREMENTS,
|
||||
MAX_NONLINEAR_ITERATIONS, NonlinearStatic, OutputVariable, Procedure, RigidWall, Step, StressRate, Tolerances, Transient,
|
||||
};
|
||||
pub use units::UnitSystem;
|
||||
|
||||
@@ -145,6 +145,20 @@ pub struct NonlinearStatic {
|
||||
/// them (cyclic loading). Increments end at every point of the path.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub load_path: Option<Vec<[f64; 2]>>,
|
||||
/// A geometric imperfection: the mode shape of a buckling step, scaled, added to the node
|
||||
/// coordinates before this step is solved (the step and its results are on that geometry).
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub imperfection: Option<Imperfection>,
|
||||
}
|
||||
|
||||
/// Mode `mode` (from 1) of buckling step `step`, scaled so its largest component is `scale`
|
||||
/// (a length), as an initial imperfection.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Imperfection {
|
||||
pub step: String,
|
||||
pub mode: u32,
|
||||
pub scale: f64,
|
||||
}
|
||||
|
||||
/// Most points of a nonlinear step's load path.
|
||||
@@ -181,6 +195,7 @@ impl Default for NonlinearStatic {
|
||||
tolerances: Tolerances::default(),
|
||||
line_search: false,
|
||||
load_path: None,
|
||||
imperfection: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,6 +205,12 @@ impl NonlinearStatic {
|
||||
let fraction = |what: &str, v: f64| {
|
||||
if v > 0.0 && v <= 1.0 { Ok(v) } else { Err(Error::Invalid(format!("the {what} is a fraction of the step in (0, 1], got {v}"))) }
|
||||
};
|
||||
if let Some(imp) = &self.imperfection {
|
||||
if !(1..=MAX_MODES).contains(&imp.mode) {
|
||||
return Err(Error::Invalid(format!("an imperfection takes mode 1 to {MAX_MODES}, got {}", imp.mode)));
|
||||
}
|
||||
finite("imperfection scale", imp.scale)?;
|
||||
}
|
||||
let initial = fraction("initial increment", self.initial_increment)?;
|
||||
let min = fraction("minimum increment", self.min_increment)?;
|
||||
let max = fraction("maximum increment", self.max_increment)?;
|
||||
|
||||
Reference in new issue
Block a user