Skip to content

Scalable linear solvers: plan, decisions and traceability #21

Open

Description

@jmartfrut

Tracking issue for the scalable linear-solver block (part of the master plan, #22; driver companion #23). Full design, measurements and per-stage records in the project documents design/solvers.md and design/solvers-*-status.md (kept outside git). This issue records the decisions, the stages and their PRs so that every PR of the block can reference it.

Last update: 2026-11-13 — S0 to S5 done (S5: HyperFEM #283, HyperFEMKernels #52 merged). Pending administrative items: HyperFEM release with S4-B/S5, README recipe of the hybrid Newton for electro-mechanics. MPI: R5 proposal (tracked in #23).

Goal and acceptance

Replace LU as the linear solver inside Newton so that the full solve! scales:

  • Time: solve! ≥ ×5 vs Gridap+LU from ~200k DOFs (measured on EM, D4).
  • Algorithmic scalability: Krylov iterations nearly mesh-independent (±30 % from 50k to 1M DOFs).
  • Newton unchanged: same Newton iterations and solution as LU.
  • GPU/MPI-compatible design; every feature with tests.

Decisions

  • D1 Libraries (2026-10-23): PETSc via GridapPETSc in production (GAMG with rigid-body modes, BoomerAMG, fieldsplit, MUMPS, PCMG); AlgebraicMultigrid.jl for prototyping and CI; Krylov and matrix-free multigrid in Julia. The installed binary (GridapPETSc 0.5.8 → PETSc_jll 3.22.1) has everything the plan needs (checked in S0). No first-class pure-Julia solver backend.
  • D2 Code location (2026-10-23): the contract is Gridap's LinearSolver interface; each piece lives where the knowledge it needs lives. HyperFEM (extension on GridapPETSc, short branches off main): S0′, S1, S2, S4-B. HyperFEMKernels: S3, S4-A, S5, exposed as Gridap LinearSolvers with the coarse solver injected (no PETSc dependency). Discarded: everything in HyperFEMKernels; PETSc SNES end to end.
  • D3 Hardware (2026-10-23): criteria measured on the M5 Max laptop (128 GB, 18 threads) at 50k/200k/1M DOFs; LU only up to where it fits; cluster (Julia 1.13) only for MPI scaling and GPU.
  • D4 Reference problems (2026-10-29, refined 2026-10-30): EM and hMRE; the ×5 criterion is measured on EM (plate P1, box Q2); hMRE enters through its 3D / vacuum cases and the u–φ blocks; hmre_cell (3D periodic cell) is the illustrative case of the gains. Visco secondary; aorta CFD out of the block.
  • D5 Convergence criteria (2026-10-29): follow the third-medium note — relative with the consistent tangent, absolute (atol_projected, on the scale of the reactions) in projected mode, curvature criterion relative and only when the linear solve converged.
  • D6 h-multigrid (2026-10-31): S4 split into S4-A (matrix-free p-multigrid) and S4-B (PETSc PCMG on a hierarchy obtained by uniform refinement of a coarse Gmsh mesh, for Q1/P1 models). S4-B starts with a test of Gridap's refine on Gmsh tetrahedra and hexahedra (gate). External review in design/solvers-s4b-review.md; its open questions are raised when S4-B starts.
  • S2 (DS2-1…DS2-6, 2026-10-31): positive-real form (φ rows negated) + GMRES; one V-cycle per block; default split additive by measurement; block AMGSolver for CI.
  • Gate 0 (2026-10-31): the GAMG default is the best tuning found; the iteration growth on the 3D cell comes from the ×100 stiffness contrast, not from AMG on P1 elasticity. GAMG unchanged.
  • R4a (DR4-1…DR4-8, 2026-10-31/11-05): Eisenstat–Walker forcing term (choice 2 only, ηmax = η0 = 1e-2, never tighter than the solver's tolerance at the start of the Newton), default off; no automatic fallback to a direct solver; one-pass residual_and_jacobian! deferred; README recommends PETScSolver(U; reuse=3) + forcing=EisenstatWalker() for multi-field production runs; projected-mode tolerance is an open question for S5 (settled by DS5-4).
  • S4-A (DS4A-1…DS4A-11, 2026-11-07/08): the caller passes the spaces of every level, HyperFEM provides level_spaces; mechanics (single field) only — per-block p-multigrid for (u, φ) deferred; acceptance on an isotropic unit cube (mech_cube), the slender box reported; coarse solver one GAMG V-cycle with rigid-body modes (LU/MUMPS optional, injected, no PETSc in the engine); GMRES by default, CG valid (symmetric cycle); Chebyshev degree 2, range 20 (by the smoother sweep); the Dirichlet projection reuses the last usable levels; Q3 → Q1 directly; LOR Q1 deferred. Released as 0.2.2 (0.2.1 had gone out with Second derivatives (∇∇) of the unknown, test and trial functions; fallback by triangulation; cheap update #47).
  • S4-B (DS4B-1…DS4B-9, 2026-11-08): Gridap's refine(model, 2) for every element type (step 0 gate passed on Gmsh tetrahedra and hexahedra, affine and distorted); Dirichlet tags must be closed sets on the coarse mesh; plain models in the hierarchy, glues kept apart; prolongation free → free by insertion from the refinement rule; Galerkin coarse operators; pure-Julia V-cycle (option J) in HyperFEM, the PETSc PCMG route (P) optional (only needed for MPI); Chebyshev on inverted nodal blocks with a Lanczos estimate in the block inner product; with reuse only the coarse levels lag, the fine smoother follows the current tangent; multi-field through FieldSplitSolver with one V-cycle per block (reported, not acceptance).
  • S5 (DS5-1…DS5-5, 2026-11-09/10): forcing term recommended in the README for h-multigrid / field split, defaults unchanged; linear_indefinite(ns) hook reported by the multigrid solvers, FieldSplitSolver, PETSc (KSP_DIVERGED_INDEFINITE_*) and CG in MatrixFreeSolver (Krylov.jl linesearch = true); with HybridTangent an indefinite report switches to the projected tangent at the same state, ConsistentTangent unchanged; projected-mode solves at ηmax floored by atol_projected (adopted: projected Newton iterations did not grow); HybridTangent(; stay_projected = 2) stays projected after the second indefinite report of a solve (2026-11-10); electro-mechanics: HessianRegularization(model::ElectroMechano) projects the total ∂²Ψ/∂F∂F (Maxwell term included), formulation in E, never in D; acceptance on the EM pull-in, the hMRE beam is not an instability case as it stands (iterative solvers fail first by conditioning).
  • S3 (DS3-1…DS3-5, 2026-11-05): Krylov.jl; LaggedAssembled(solver; every = 3) (confirmed by measurement); LOR Q1 moved to S4-A; Krylov in Julia, PETSc only inside LaggedAssembled (MatShell in phase 3); Newton ↔ solver hooks stay in HyperFEM, HyperFEMKernelsExt adds the MatrixFreeSolver methods.

Stages

Execution order: S0 → S0′ → R1 → R2 → S1 → R3 → transient models → S2 → R4a → S3 → S4-A → S4-B → S5 (R stages tracked in #23).

Stage Where Content Status PRs
S0 (+R0) HyperFEMKernels PETSc check, refinable cases EM plate P1 / EM box Q2 / hMRE at 50k–1M, per-iteration costs ✅ 2026-10-29 HFK #34
S0′ (+R4) HyperFEM NewtonRaphson, own tolerances/log (GridapSolvers dropped), InjectivityLS (exact 2D/3D step, jmin, Armijo), HybridTangent, LogBarrier, Dirichlet-reset fix, verbose output ✅ 2026-10-30 HyperFEM (S0′ PR)
S1 HyperFEM PETScSolver GMRES/CG + GAMG/BoomerAMG/MUMPS, near_nullspace(U), lagged reuse, real linear_converged; AMGSolver for CI ✅ 2026-10-31 HyperFEM #269; HFK #37, #38
S2 HyperFEM PETScSolver(U::MultiFieldFESpace) with fieldsplit (additive default), block AMGSolver ✅ 2026-10-31 HyperFEM #270, #271; HyperFEM 0.1.0 (#272)
R4a HyperFEM set_tolerance!/tolerance hooks, Eisenstat–Walker forcing term, flat-memory test, deprecations removed ✅ 2026-11-05 HyperFEM #275; HyperFEM 0.2.0 (#276); HFK #40
S3 HyperFEMKernels + HyperFEM KernelOperator(jacobian=:matrixfree), lazy sparsity pattern, MatrixFreeSolver (Krylov.jl), LaggedAssembled, BlockJacobi, eigenvalue_bounds, KernelFunctional (energy / injectivity step as kernels); HyperFEM CompiledBackend(jacobian=:matrixfree) ✅ 2026-11-06 HFK #44, release 0.2.0 #45; HyperFEM #278
S4-A HyperFEMKernels + HyperFEM Matrix-free p-multigrid (Q2 → Q1, Q3 → Q1, Q3 → Q2 → Q1): transfers between nested spaces (Prolongation, restrict!, inject!), levels rediscretised from the Newton's forms at the injected state, Chebyshev smoother on nodal blocks from the stored tangents, PMultigrid slot of MatrixFreeSolver, coarse level assembled with one GAMG V-cycle, preconditioner_ok (non-finite or indefinite tangent → failed solve); HyperFEM level_spaces ✅ 2026-11-08 HFK #49, release 0.2.2; HyperFEM #281
S4-B HyperFEM + HyperFEMKernels h-multigrid for Q1/P1 on a refined mesh hierarchy: MeshHierarchy (Gridap's refine, step 0 gate), prolongation(s) from the refinement glue, HMultigridSolver (CG/GMRES + one V-cycle: Galerkin operators refilled in a fixed pattern, Chebyshev on nodal blocks, Lanczos estimate in the block inner product, injected coarse solver, lagged coarse levels), FieldSplitSolver (block preconditioner with injected block solvers: one V-cycle per (u, φ) block); one BLAS thread during Krylov and setups; benchmark cases hcube_tet, hcube_hex, hem_plate_c ✅ 2026-11-09 HyperFEM #282 (step 0 on main c777494); HFK #51
S5 HyperFEM + HyperFEMKernels Performance levers (forcing term recommended for h-multigrid / field split: tet 893k solve! 142.8 → 86.1 s, EM plate 555k 66.6 → 28.0 s; cheaper lagged refresh of the fine smoother); linear_indefinite hook on every solver (negative curvature in CG, non-positive Ritz values on a multigrid level, PETSc's indefinite flags); HybridTangent switches to the projected tangent on it, projected-mode tolerance (DS5-4), stay_projected = 2; HessianRegularization of coupled electro-mechanical models (in E) and of anisotropic models; benchmark cases hem_plate_c … φtop, hem_plate_ch, hmre … Bfactor, hmre_h ✅ 2026-11-10 HyperFEM #283; HFK #52

Results so far

Laptop M5 Max, 6 Julia threads, PETSc serial, backend :compiled; per Newton iteration or solve! as stated. Full tables in design/solvers.md and the status documents; raw rows in benchmark/results/.

case DOFs reference best configuration gain
mechanics, plate P1 809k LU 220 s/it (87 GB) CG + GAMG 10.4 s/it (8.9 GB) ×15–21
EM plate, constrained electrodes 236k S2 fieldsplit solve! 50.4 s (×4.5 vs LU) + reuse=3 + forcing (R4a): solve! 22.5 s ×2.2 over S2, ≈ ×10 vs LU
EM plate, constrained electrodes 1.08M LU ≈ 295 s/it fieldsplit additive 18.5 s/it ≈ ×16
hMRE periodic cell 3D 104k LU 29.5 s/it (94 GB) fieldsplit additive 1.95 s/it (3.8 GB) ×15
hMRE periodic cell 3D 480k LU does not fit fieldsplit additive 12.1 s/it (8.5 GB) only solver that runs
EM box Q2 (thin cantilever) 218k MUMPS solve! 537 s matrix-free GMRES + LaggedAssembled(MUMPS; every=3) 107 s ×5.0 (S3)
mechanics, unit cube Q2 197k CG + GAMG assembled 6.35 s/it matrix-free GMRES + p-multigrid (S4-A) 1.33 s/it ×4.8
mechanics, unit cube Q2 957k CG + GAMG assembled 36.2 s/it (16.8 GB) matrix-free GMRES + p-multigrid 4.34 s/it (4.3 GB) ×8.3 (×3.9 memory)
mechanics, unit cube Q3 227k CG + GAMG assembled 29.4 s/it (7.8 GB) p-multigrid Q3 → Q1 1.55 s/it (Q3 → Q2 → Q1: 2.1 GB) ×19
mechanics, slender box Q2 158k CG + GAMG assembled 10.2 s/it p-multigrid 3.2 s/it ×3.2 (anisotropy limits point smoothers)
mechanics, unit cube Q1 hexahedra, 5 levels 799k CG + GAMG 8.83 s/it (29.8 its) CG + h-multigrid (S4-B) 1.75 s/it (16.8 its) ×5.0
mechanics, unit cube P1 tetrahedra, 4 levels 893k CG + GAMG 15.97 s/it (84.7 its); solve! 815 s CG + h-multigrid 2.80 s/it (31.9 its); solve! 143 s ×5.7
EM plate (u, φ) on a hierarchy, 4 levels 555k PETSc fieldsplit, GAMG blocks 10.14 s/it (97.5 its); solve! 203 s FieldSplitSolver Schur, h-multigrid blocks 3.33 s/it (49.9 its); solve! 67 s ×3.0
EM plate past the pull-in (φtop = 1.6), hybrid Newton 71k LU solve! 331–683 s; multigrid with consistent tangent stops at Λ = 0.79 FieldSplitSolver hMG + HybridTangent + projected HessianRegularization (S5): Λ = 1 in 22 s, same equilibrium as LU (4.5e-7) ×15–30
EM plate past the pull-in (φtop = 1.6), hybrid Newton 555k LU does not fit idem, stay_projected = 2: Λ = 1 in 10 steps, 0 bisections, 182 s only solver that runs
  • Since the start of the plan (3D hMRE cell, 104k): HyperFEM v0.0.7 (Gridap + LU) ≈ 1125 s / ~76 GB → :compiled + fieldsplit 78 s / 3.8 GB (×14 time, ×20 peak memory).
  • Iterations: P1 mechanics +39 % over 53k → 809k; em_plate_c +37 % over 71k → 1.08M; 3D cell +42 % over 29k → 480k, driven by the ×100 stiffness contrast (flat at contrast 1).
  • Same Newton trajectory and solution as LU/MUMPS in every converged run.
  • Matrix-free product vs SpMV on Q2 hexahedra: ×5 (57k–974k), ×6 on Q3; on P1 tetrahedra ×10 slower (P1 stays assembled; S4-B is its route).
  • p-multigrid Krylov iterations on the cube Q2: 25.5 → 26.6 → 27.8 from 25k to 957k (+9 %); GAMG on the assembled Q2: 60 → 64 → 66.
  • h-multigrid CG iterations on P1 tetrahedra: 32 at 414k and at 893k (GAMG 53 → 85); Q1 hexahedra 16.7–16.8 from 101k to 799k (GAMG 28 → 30). Memory does not discriminate on the assembled tangent (both dominated by the matrix).
  • The GAMG references are PETSc in serial (no MPI in this build).

Open items carried forward

  • Thin-structure elasticity AMG (K_uu cond ≈ 4e7 on em_plate/em_box): MUMPS (or lagged MUMPS matrix-free) until a dedicated task (semi-coarsening, line smoothers, BDDC).
  • Monolithic GAMG returns a wrong update with a converged flag on the 3D cell.
  • Interface-aware coarsening for high stiffness contrast (or S4-B with the interface on the coarse mesh, or BDDC).
  • Multi-field (u, φ) p-multigrid: per-block p-multigrid inside a field split — now possible through FieldSplitSolver (S4-B), which accepts any LinearSolver per block.
  • Block field splits are not h-independent on the EM plate (h-multigrid blocks 41 → 56 GMRES iterations from 71k to 555k, GAMG blocks 55 → 98): the coupling the block splits ignore.
  • h-multigrid fine products are ~60 % of a CG iteration: symmetric (upper-triangle) storage or the matrix-free fine operator are the next levers; the PETSc PCMG route for MPI.
  • p-multigrid cycle is coarse-limited (one GAMG V-cycle on Q1) and its setup is ≈ 23 % of a Newton iteration at 957k: a second coarse cycle and lagging the λmax estimate are the next levers.
  • Rebinding a MatrixFreeSolver to an operator of another concrete type (review B8, pre-existing).
  • Matrix-free on simplices needs the matrix-product formulation of the assembly kernels.
  • Preconditioner application through PETScSolver.solve! converts vectors per call (MatShell/PETSc vectors in phase 3).

Traceability

Every PR of the block (in this repository or in HyperFEM) references this issue and names its stage (S1, S4-A, …). Measurements go in benchmark/ with their origin (machine, threads, Julia version). Decisions are recorded here when taken.


Generated by Claude Code

Activity

  1. jmartfrut commented on Oct 24, 2026

    @jmartfrut
    MemberAuthor

    Driver-side companion: #23 (driver refactor in HyperFEM, stages R0–R5). Coordination with this block:

    • S0 also measures the driver baseline (R0): time and bytes per Newton iteration, per load step and per solve!, and driver allocations outside assembly and the linear solve.
    • S0′ also takes the allocation fixes of the HyperFEM efficiency review: line searches without x + α*dx (trial vector in the cache) and x .+= α .* dx; IterativeSolver without eval(Meta.parse(...)) per solve!, typed kwargs, in-place solution; views instead of b[r]' * dx[r] in Injectivity_Preserving_LS.
    • R4 (single Newton) goes after S1 and before S3: its cache accepts the matrix-free Jacobian of S3 and refreshes the preconditioner with x (lagged AMG of S1). HyperFEM.NewtonSolver is the evolution of Newton_RaphsonSolver after S0′ and follows D5.
  2. jmartfrut commented on Oct 29, 2026

    @jmartfrut
    MemberAuthor

    Update 2026-10-29:

    • D4 decided: reference problems EM and hMRE; visco secondary; aorta CFD out of this block.
    • D5 decided: convergence criteria follow the third-medium note — relative with the consistent tangent, absolute (atol_projected, user-given on the scale of the reactions) in projected mode, curvature criterion relative and only when the linear solve converged.
    • S0 is a separate small PR in HyperFEMKernels (benchmark/solvers/, includes R0 of Driver refactor in HyperFEM (tracking, companion of #21) #23).
    • S0′ widened: Newton refactor (absorbs R4 of Driver refactor in HyperFEM (tracking, companion of #21) #23) plus the third-medium solver improvements (exact injectivity step 2D/3D with J_min, Armijo on the energy, hybrid Newton with eigenvalue clamping, per-mode tolerances, LogBarrier), ≈ 3 sessions, one HyperFEM PR with one commit per step. ΔΛ growth goes to R2.
    • Backends renamed :gridap → :lazy, :kernel → :compiled (HyperFEM #263, HyperFEMKernels Use HyperFEM's new backend names (:lazy, :compiled) #33).
    • Unified S + R structure and order in design/solvers.md; total ≈ 16 sessions.
  3. jmartfrut commented on Nov 6, 2026

    @jmartfrut
    MemberAuthor

    S0 - S3 Completed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions