solver: a job cancelled before it starts stops before any setup work

The cancel check came only at the factorization, so on a busy CI runner a
pre-cancelled frequency solve still spent 17 s on setup (cancel_tests).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-15 12:44:16 -04:00
1 parent 3e997dab43
commit f220c7108b
4 files changed
+11

No files matched your search

+5
View File
@@ -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<StaticResult> {
// 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<FrequencyResult> {
// 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
+2
View File
@@ -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<FrequencyResult> {
// 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()));
+2
View File
@@ -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<HeatResult> {
// 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<String> = resolved.warnings.iter().map(ToString::to_string).collect();
+2
View File
@@ -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<StaticResult> {
// 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()));