Skip to content

Choosing a linear solver

Conjugate gradients with Jacobi, incomplete Cholesky or multigrid, or a direct factorisation — what each does, how to watch it, and when the choice matters.

Analysis types 9 min read

Every analysis ends in a linear system , and there is more than one way to solve it. Elementarium lets you choose, per analysis setup, between an iterative conjugate gradient method with a preconditioner and a direct factorisation. Most models are indifferent to the choice; some are not. The solve monitor shows either one converging while it runs.

The solvers

SolverKindWhat it does
Conjugate gradient — the defaultIterativeImproves an initial guess step by step until the relative residual falls below a tolerance you set. Stores the matrix and a few vectors, nothing more
Cholesky ()DirectFactorises into a lower-triangular matrix and its transpose. Needs symmetric positive definite
Cholesky ()DirectThe same with a diagonal pulled out, so it also handles symmetric matrices that are indefinite — which is what the second-order iteration watches for

The direct solvers are sparse: they exploit the fact that a stiffness matrix is mostly zeros, so the cost grows far more slowly than the square of the number of degrees of freedom would suggest. The matrix does not store the zeros inside each node's 6 × 6 block either.

All three run threaded where the browser grants cross-origin isolation — see Solver threads below.

Preconditioners for CG

Conjugate gradients converge at a rate set by the conditioning of the system. A stiffness matrix, with stiffnesses spanning orders of magnitude between a stiff column and a soft spring, is usually badly conditioned. A preconditioner transforms the problem into one that converges faster:

PreconditionerCost per iterationEffect
Jacobi (diagonal) — the defaultNegligibleRemoves the scaling differences between degrees of freedom. Cheap, fully threaded, and enough for frames
Incomplete CholeskyModerateAn approximate factorisation (IC0); usually cuts iterations by an order of magnitude, at the price of a sequential setup
Algebraic multigrid (AMG)Higher setupAttacks the long-wavelength error that Jacobi-CG resolves slowly. The strongest on large surface meshes
None—Plain CG, for comparison only

Multigrid

Multigrid got three changes in 0.5.0 that make it the preconditioner to reach for on a model with plates — the analysis manager suggests Switch to AMG when it sees one:

  • It is told about rigid-body modes. With Rigid-body modes on Auto, the coarse levels are built knowing how a shell or a frame moves when it is not strained, so a typical solve converges in tens of iterations rather than hundreds or thousands.
  • Its default smoother is threaded. The smoother is now SPAI(0), which runs on every core. ILU(0), the old default, ran on one core and slowed down when threaded; it is still offered, marked as such. Chebyshev, Damped Jacobi and the sequential Gauss-Seidel are the other choices.
  • It solves load cases together. Up to eight load cases share one pass through the multigrid hierarchy, using the processor's vector (SIMD) instructions — 1.2–1.7× faster on models with several load cases.

The cycle (V or W), the number of sweeps, the strength threshold and the size of the coarsest level are all exposed under the AMG settings. Leave them alone unless the Last solve readout gives you a reason not to.

Where the choice is made

Two places, the second overriding the first:

  • Project settings → Analysis → Solver — the project default every analysis starts from.
  • Analysis manager → Linear solver — per analysis setup. Use project defaults follows the project; Make default promotes this setup's choice to the project. The Last solve line reports what the settings did the last time this analysis ran: the most iterations any load case took, the worst relative residual recomputed from the answer, and the solve time.

Modal analysis has no linear-solver section; its eigenvalue settings are on Modal analysis.

The solve monitor

A solve that takes more than a moment opens the solve monitor beside the model. It shows the run as it happens: which load case is being solved, the current iteration out of the ceiling, the error, and a convergence chart with one curve per load case.

The solve monitor panel: Linear static, Converged, 1.2 s; Case 8/8, Iteration 119 max, Energy error 8.26×10⁻⁷, Tolerance 1×10⁻⁶; the Convergence tab with eight energy-error curves falling from 10⁰ to below 10⁻⁶ between 110 and 120 iterations, and chips G1, G2, Q1, Q2, Q3, Q4, T1, W1 all ticked
The solve monitor after F5 in the road overpass example: Linear static, converged in 1.2 s; all 8 load cases solved by CG with the multigrid preconditioner, the slowest in 119 iterations, to an energy error of 8.26×10⁻⁷ against a 1×10⁻⁶ tolerance. One curve per load case, G1 to W1.
PartWhat it tells you
HeaderThe analysis, its state — Preparing, Assembling, Factorizing, Iterating, then Converged, Not converged, Stopped or Failed — and the elapsed time
ReadoutsCase (this one of how many), Iteration, Energy error or Residual, and the Tolerance it is working to
Convergence tabThe error per iteration on a log scale, one curve per load case, the tolerance as a dashed line. A chip per load case: Converged, Solving, To solve, Did not converge
Stats tabThe run in numbers — see below
FooterOpen while solving, and Stop while it runs (Run / Run all when it has finished)

The chart can plot two measures. The energy error is what CG minimises, so its curve never rises; it is the true picture of how close the answer is. The residual is what the tolerance tests, so it is what decides when a case is done; it can sit high, or climb for a while, as the answer improves. A direct solver reports neither: it has no iterations, and the monitor shows the factorisation instead.

Stop cancels the run cleanly between iterations. Results already solved stay; the rest are reported as not solved.

The Stats tab

The solve monitor Stats tab listing Solver Conjugate gradient, Load cases All 8 solved, Iterations 119, Worst residual 9.38×10⁻⁷, Mechanism check Reused, Condition estimate 211, Time 1.11 s and Solve 983 ms
The same run on the Stats tab: Conjugate gradient, all 8 load cases solved, 119 iterations, a worst residual of 9.38×10⁻⁷ recomputed from the answer, the mechanism check reused, a condition estimate of 211, and 1.11 s in all, 983 ms of it the solve.
RowMeaning
Result, Solver, Load casesWhat ran, with which method and preconditioner, and how many cases were solved
IterationsThe most any load case needed to reach the tolerance
Worst residual recomputed from the answer, the largest over the load cases. It says whether the answer satisfies equilibrium, whatever the solver reported
Mechanism checkWhether the pre-solve check passed, or was reused from the last run
Condition estimateHow ill-conditioned is. Above about the answer loses digits — look for a near-mechanism or a very soft spring
Free rotations lockedNode rotations no member stiffens, such as truss joints, held so the system can be solved. They carry no result
TimeThe run split into model build, solve, member forces, plate results, error estimate, displacements and reactions

Last run and By analysis switch between the most recent solve and a summary per analysis setup. The header picker does the same for the convergence chart: Current solve follows whatever is running, All analyses lists them.

Solver threads

The threaded build splits assembly, the matrix product and — since 0.4.0 — every other step of each CG iteration across processor threads. How many is a setting:

  • Settings → Solver engine → Threads — Automatic (the hint says how many are available) or a fixed count.
The Settings dialog with Appearance (theme and language) and Solver engine sections: Engine Parallel or Serial, Threads Automatic, Re-solve automatically and Report paused analyses toggles, and a readout of 8 of 8 threads
Settings, top half: Appearance, then Solver engine — 8 of 8 threads on this machine, the Parallel engine, Threads on Automatic, and the Re-solve automatically and Report paused analyses switches.
  • Automatic takes half the logical processors, at most eight. Logical processors are usually two hyperthreads per physical core; an iterative solve is limited by memory bandwidth, so the second hyperthread adds a participant to every synchronisation and no bandwidth. Past eight threads, coordinating that many browser workers costs more than it saves.
  • Solver engine itself is Parallel or Serial. Where the page is not cross-origin isolated, the engine runs single-threaded and the setting says so — see System requirements.

Fewer threads leave room for the rest of the machine — a video call, a second browser window solving something else. A fixed count can only lower the number: Automatic is also the ceiling.

Which to use

Start with the default. Conjugate gradients with Jacobi is cheap, threaded end to end, and converges quickly on frames and trusses.

Switch to multigrid when the model has plates and the solve monitor shows hundreds or thousands of iterations per case. Plate meshes are where Jacobi-CG is weakest and AMG is strongest. The overpass above is that case: 18,654 degrees of freedom, mostly deck shells. Jacobi-CG needs 3,147 iterations for its slowest load case; AMG needs 119. The worked examples ship with AMG.

Leave incomplete Cholesky for the odd ill-conditioned frame. Its setup and its triangular solves run on one thread, so on a large model it is the slowest of the three: the overpass takes around ten seconds under IC0 against one to two under Jacobi or AMG.

Use a direct solver when:

  • you are solving the same matrix against many load cases and memory is not the constraint — the factorisation happens once and every case after it is a cheap pair of triangular solves;
  • the model is badly conditioned and the iterative solver stalls (Did not converge);
  • you want an independent check on an iterative result. Two different algorithms agreeing to five figures is evidence of a kind that re-running the same one is not.

Tolerance

CG stops when its estimate of the relative residual falls below the tolerance:

The default is 1e-6 with a ceiling of 10,000 iterations; the tolerance can be set anywhere from 1e-12 to 1e-3.

ToleranceUse
1e-6The default. The displacement error is bounded by the condition estimate times the residual: with a condition estimate in the hundreds, about four figures — still beyond any engineering need
1e-5 and looserVisible in the results: displacements and reactions carry the residual with them. A quick look, not a report

The number to distrust is a loose tolerance on a badly conditioned model, where the residual can be small while the displacement error is not. The Worst residual and Condition estimate rows on the Stats tab are there to catch exactly that.

If two setups, one direct and one CG at 1e-6, disagree beyond the fourth figure, the conditioning is poor and the reason is in the model: a very stiff spring, a section in the wrong units, a near-mechanism. Solver errors lists the usual causes.

Two answers, side by side

Each analysis in Elementarium is a named setup that stores its solver choice and keeps its own results. For a result you are not sure of:

  1. Create a second setup with a different solver — direct against CG, or a different preconditioner.
  2. Solve both, and compare their Last solve lines in the analysis manager.
  3. Pin one to each viewer panel and read the governing quantity in both.

The difference answers "does the solver matter here". It is almost always no, and now you can say so with a number instead of an assumption.

What the choice does not affect

The solver decides how is solved, not what is. Element formulation, mesh density, supports, releases and loads are the same for every solver, and every error in them is reproduced faithfully by all of them. A converged CG result and a direct result of the same wrong model agree perfectly.

Modal and stability analyses solve an eigenvalue problem rather than a linear system. Their settings (number of modes, mass target, the Sturm-sequence completeness check) are described on Modal analysis and Linear buckling.

The direct stiffness method explains where comes from; Element formulations what each element contributes to it; the release notes record what each solver change did to solve times.

Something wrong or unclear on this page? Tell us, and it gets corrected.