From b8e51b5dd9d564ebe897c9ca33baecb003fd9278 Mon Sep 17 00:00:00 2001 From: jyviko <2501648+jyviko@users.noreply.github.com> Date: Sun, 18 Oct 2026 13:32:43 -0400 Subject: [PATCH] solver: order by planes or graph dissection, whichever fills less (#212) Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo --- crates/solver/src/analysis.rs | 6 +++--- crates/solver/src/heat.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/solver/src/analysis.rs b/crates/solver/src/analysis.rs index 4b121f5..0db7b8b 100644 --- a/crates/solver/src/analysis.rs +++ b/crates/solver/src/analysis.rs @@ -15,7 +15,7 @@ use crate::cholesky::{Factor, FactorError, UpperColumns}; use crate::constraints::{Budget, Reduction, coupling_rows, symmetry_rows}; use crate::eigen::{Operator, Wanted, lanczos}; use crate::ldlt::{Kind, Symmetric}; -use crate::ordering::nested_dissection; +use crate::ordering::fill_reducing_order; use crate::sparse::{Csr, NodeGraph, add_block, add_diagonal, add_scalar}; use crate::system::{ Mesh, Structural, StructuralKernel, add_thermal_loads, inelastic_warnings, loads, prescribed, structural_body_forces, temperature_loads, @@ -311,10 +311,10 @@ pub(crate) fn pattern(mesh: &Mesh) -> (NodeGraph, Vec) { // The order covers the mesh nodes; reference point equations follow them. let n = mesh.labels.len(); let order = if graph.adjacency.len() == n { - nested_dissection(&mesh.xyz, &graph.adjacency) + fill_reducing_order(&mesh.xyz, &graph.adjacency) } else { let mesh_part: Vec> = graph.adjacency.iter().take(n).map(|row| row.iter().copied().filter(|b| *b < n).collect()).collect(); - nested_dissection(&mesh.xyz, &mesh_part) + fill_reducing_order(&mesh.xyz, &mesh_part) }; (graph, order) } diff --git a/crates/solver/src/heat.rs b/crates/solver/src/heat.rs index 97f125c..6fafd87 100644 --- a/crates/solver/src/heat.rs +++ b/crates/solver/src/heat.rs @@ -28,7 +28,7 @@ use fieldcraft_model::{ElementKind, Load, Model, Procedure, Resolved, SectionKin use crate::cholesky::{Factor, FactorError, UpperColumns}; use crate::constraints::{Budget, Reduction, Row}; use crate::contact::thickness; -use crate::ordering::nested_dissection; +use crate::ordering::fill_reducing_order; use crate::sparse::{Csr, NodeGraph, add_block}; use crate::system::hold; use crate::tie::{TieFace, TieNodes, rows_of}; @@ -398,7 +398,7 @@ fn run(model: &Model, resolved: &Resolved, step: &Step, limits: &Limits) -> Resu let mut warnings = Vec::new(); let rows = tie_rows(model, resolved, &mesh, &mut warnings)?; let fixed = prescribed(model, resolved, &mesh, step)?; - let order = nested_dissection(&mesh.xyz, &graph.adjacency); + let order = fill_reducing_order(&mesh.xyz, &graph.adjacency); let budget = Budget { max_bytes: limits.max_factor_entries.saturating_mul(8), pattern_entries: graph.entries(&mesh.layout), matrices: 1 }; let eqs = Reduction::new(&mesh.layout, std::iter::empty(), &order, &rows, |_| Ok(fixed), budget)?; if eqs.neq() == 0 {