diff --git a/crates/solver/src/analysis.rs b/crates/solver/src/analysis.rs index 3fee7e7..46cb90f 100644 --- a/crates/solver/src/analysis.rs +++ b/crates/solver/src/analysis.rs @@ -367,6 +367,8 @@ pub(crate) fn budget(limits: &Limits, mesh: &Mesh, graph: &NodeGraph, matrices: /// quasi-static thermoelasticity without thermoelastic dissipation, so solving the two in turn /// is the monolithic solution exactly. pub fn solve_static(model: &Model, step: Option<&str>, limits: &Limits) -> Result { + // A job cancelled before it starts stops here, before any setup work. + fieldcraft_model::progress::check()?; let resolved = model.resolve()?; let step = model.select_step( step, @@ -571,6 +573,8 @@ pub(crate) const TOLERANCE: f64 = 1e-9; /// Solve a frequency step (the step named `step`, or the model's only frequency step): the /// lowest natural modes within the step's frequency range. pub fn solve_frequency(model: &Model, step: Option<&str>, options: &FrequencyOptions, limits: &Limits) -> Result { + // A job cancelled before it starts stops here, before any setup work. + fieldcraft_model::progress::check()?; let resolved: Resolved = model.resolve()?; let step = model.select_step(step, |p| matches!(p, Procedure::Frequency { .. }), "frequency")?; let Procedure::Frequency { modes, min_hz, max_hz } = step.procedure else { @@ -590,6 +594,7 @@ pub fn solve_frequency(model: &Model, step: Option<&str>, options: &FrequencyOpt let setup = Setup { model, resolved: &resolved, mesh: &mesh, step }; let red = reduction(&setup, false, &order, budget(limits, &mesh, &graph, 2), &mut warnings)?; let Assembled { k, m } = assemble(&mesh, &graph, Some(options.mass))?; + fieldcraft_model::progress::check()?; let m = m.ok_or_else(|| Error::Internal("mass matrix".into()))?; // Every element's mass entries between translations sum to its mass, once per direction // (the mean over the directions for a point mass given per direction; rotary inertia, and diff --git a/crates/solver/src/buckle.rs b/crates/solver/src/buckle.rs index 52a921c..7d7b40e 100644 --- a/crates/solver/src/buckle.rs +++ b/crates/solver/src/buckle.rs @@ -107,6 +107,8 @@ impl Operator for Shifted<'_> { /// Solve a buckling step (the step named `step`, or the model's only buckling step). pub fn solve_buckle(model: &Model, step: Option<&str>, limits: &Limits) -> Result { + // A job cancelled before it starts stops here, before any setup work. + fieldcraft_model::progress::check()?; let step = model.select_step(step, |p| matches!(p, Procedure::Buckle { .. }), "buckling")?; let Procedure::Buckle { modes, shift } = step.procedure else { return Err(Error::Internal("buckling step".into())); diff --git a/crates/solver/src/heat.rs b/crates/solver/src/heat.rs index 15ead21..07fdb28 100644 --- a/crates/solver/src/heat.rs +++ b/crates/solver/src/heat.rs @@ -479,6 +479,8 @@ pub(crate) fn temperatures_at(model: &Model, resolved: &Resolved, step: &Step, l /// Solve a heat transfer step: the step named `step`, or the model's only one. pub fn solve_heat(model: &Model, step: Option<&str>, limits: &Limits) -> Result { + // A job cancelled before it starts stops here, before any setup work. + fieldcraft_model::progress::check()?; let resolved = model.resolve()?; let step = model.select_step(step, |p| matches!(p, Procedure::HeatTransfer { .. }), "heat transfer")?; let mut warnings: Vec = resolved.warnings.iter().map(ToString::to_string).collect(); diff --git a/crates/solver/src/nonlinear.rs b/crates/solver/src/nonlinear.rs index dd70adc..79d3482 100644 --- a/crates/solver/src/nonlinear.rs +++ b/crates/solver/src/nonlinear.rs @@ -1069,6 +1069,8 @@ fn followers(model: &Model, resolved: &fieldcraft_model::Resolved, mesh: &Mesh, /// Solve a nonlinear static step: the step named `step`, or the model's only nonlinear static /// step. pub fn solve_nonlinear(model: &Model, step: Option<&str>, limits: &Limits) -> Result { + // A job cancelled before it starts stops here, before any setup work. + fieldcraft_model::progress::check()?; let chosen = model.select_step(step, |p| matches!(p, Procedure::NonlinearStatic(_)), "nonlinear static")?; let Procedure::NonlinearStatic(settings) = &chosen.procedure else { return Err(Error::Internal("nonlinear static step".into()));