forked from 1b-agent/fieldcraft-upstream
engine: a prescribed displacement or temperature satisfies the loads stage (#356)
The setup checklist asked for a load on rubber-seal, driven only by a prescribed displacement, while model.check called it ready. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
febcffefd6
commit
8819ff787c
2 files changed
+24
-1
No files matched your search
@@ -128,6 +128,8 @@ impl Session {
|
||||
// Models without elements (point masses, fluid domains) need no material or section.
|
||||
let elementless = analysable && m.elements().is_empty();
|
||||
let modal_only = !m.steps().is_empty() && m.steps().iter().all(|st| matches!(st.procedure, Procedure::Frequency { .. }));
|
||||
// A model driven by a prescribed displacement or temperature needs no load either.
|
||||
let driven = m.boundary_conditions().values().any(|bc| bc.drives());
|
||||
let mut next_given = false;
|
||||
Stage::ALL
|
||||
.into_iter()
|
||||
@@ -137,7 +139,7 @@ impl Session {
|
||||
let optional = match stage {
|
||||
Stage::Prepare => true,
|
||||
Stage::Material | Stage::Section => elementless,
|
||||
Stage::Loads => modal_only,
|
||||
Stage::Loads => modal_only || driven,
|
||||
_ => false,
|
||||
};
|
||||
let command = r.provider();
|
||||
@@ -234,6 +236,17 @@ mod tests {
|
||||
assert_eq!((status(&s, Stage::Results), to_json(&s.progress())["next"]["command"].clone()), (Next, json!("results.contour")));
|
||||
}
|
||||
|
||||
/// A model driven by a prescribed displacement (rubber-seal) needs no load: the checklist
|
||||
/// agrees with the model check and offers the solve next.
|
||||
#[test]
|
||||
fn a_displacement_driven_model_needs_no_load() {
|
||||
let mut s = Session::default();
|
||||
s.run_script(&crate::sample::rubber_seal()).unwrap();
|
||||
assert!(s.model.loads().is_empty());
|
||||
assert_eq!(status(&s, Stage::Loads), Optional);
|
||||
assert_eq!(status(&s, Stage::Solve), Next, "{:?}", s.progress());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_check_returns_the_checklist() {
|
||||
let mut s = Session::default();
|
||||
|
||||
@@ -172,6 +172,16 @@ impl BoundaryCondition {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether it drives the model on its own, as a load does: a non-zero prescribed
|
||||
/// displacement or a non-zero prescribed temperature (a support only holds).
|
||||
pub fn drives(&self) -> bool {
|
||||
match self {
|
||||
BoundaryCondition::Displacement { values, .. } => values.iter().flatten().any(|v| *v != 0.0),
|
||||
BoundaryCondition::Temperature { value, .. } => *value != 0.0,
|
||||
BoundaryCondition::Fixed { .. } | BoundaryCondition::Symmetry { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether it prescribes temperatures (rather than motion).
|
||||
pub fn is_thermal(&self) -> bool {
|
||||
matches!(self, BoundaryCondition::Temperature { .. })
|
||||
|
||||
Reference in new issue
Block a user