Add fixed-work mass-consistent gravity Schur refinement

This commit is contained in:
2026-09-17 16:19:22 -04:00
parent 018fc1c992
commit b18f41f88f
3 changed files with 531 additions and 7 deletions

View File

@@ -0,0 +1,119 @@
# Fixed-work mass-consistent gravity Schur refinement
This optional preconditioner policy leaves the exact full Newton Jacobian,
normalization, nonlinear merit, and defaults unchanged. It is selected through the
existing typed prescription:
```cpp
preconditioning::GravityFieldBlock(
backend::MatrixFreeChebyshev{.order = 5, .powerIterations = 20},
backend::HypreBoomerAMG<backend::FixedCycles>{backend::FixedCycles{.cycles = 3}},
preconditioning::GravityConsistentSchurLDU{
.correctionSweeps = 1,
.relaxation = 0.5
}
)
```
The numbers above specify a benchmark candidate, not a recommended production
setting. `GravityApproximateLDU` remains the default. The new policy composes with
all existing stellar-structure policies and specification-border handling.
## Algebra and sign
Write the mixed gravity block in its existing reduced field coordinates as
\[
D=\begin{bmatrix}M&B^T\\ B&0\end{bmatrix},\qquad
D\begin{bmatrix}q\\\phi\end{bmatrix}
=\begin{bmatrix}f\\g\end{bmatrix}.
\]
Let \(R\) denote the prepared mass inverse action used by flux recovery, and let
\(Q\) denote the existing reduced potential inverse action. The latter uses AMG
on the assembled diagonal-mass Schur surrogate. In particular, increasing the
accuracy of \(R\) does not automatically change the operator targeted by \(Q\).
The positive mass-consistent Schur action and its signed right-hand side are
\[
S_R=B R B^T,\qquad r=B R f-g.
\]
The new policy starts with the existing potential answer \(\phi_0=Q r\), performs
exactly the requested number of corrections
\[
\phi_{j+1}=\phi_j+\omega Q(r-S_R\phi_j),
\]
and uses the existing flux recovery \(q=R f-R B^T\phi_k\). For stationary linear
\(R\), this gives
\[
Bq-g=r-S_R\phi_k.
\]
Thus the corrected residual targets the Poisson row of the same approximate
mixed factorization used for recovery. The gradient-row residual still depends
on the quality of \(R\); this is not an exact inverse of \(D\). Even a converged
Schur refinement would invert the mass-approximated block only, unless \(R=M^{-1}\).
For fixed linear child inverses the potential error propagates with
\(I-\omega Q S_R\). A positive finite \(\omega\) does not prove contraction.
Neither the toy test nor the implementation establishes spectral bounds for the
stellar models. Benchmarking must measure full-J true defects and cost.
## Work, lifetime, and sparse actions
Each additional sweep costs one application each of \(R\), \(Q\), \(B\), and
\(B^T\). No Krylov iteration, convergence test, nonlinear preparation, or full-J
application occurs inside the refinement. Two potential-sized work vectors are
allocated once for positive sweep counts. The existing statistics count every
child application, and `schurRefinementSweeps` records completed corrections.
With positive sweeps, the prepared policy reuses the cached assembled divergence
already required by the Schur surrogate. The same sparse matrix and reduced DOF
maps supply both its forward and transpose actions throughout the factorization.
The cache precedes the borrowed operator in owner lifetime and is rebound after
discretization invalidation. Geometry-only refresh retains the computational-mesh
divergence while rebuilding the geometry-dependent mass inverse and Schur
surrogate.
With zero sweeps, the policy keeps the old matrix-free divergence binding and the
old LDU arithmetic, including operation order. This separate path permits exact
baseline comparison. Positive-sweep comparisons include both the refinement and
the equivalent sparse implementation of the coupling; sparse/matrix-free
equivalence is tested independently.
The policy preserves the existing compile-time application contract: it is
stationary linear exactly when both child backends declare that contract. A
tolerance-driven child remains flexible. Fixed work must not be mistaken for
linearity of an arbitrary child solver. Keeping the default fixed-cycle children
allows the specification border to retain its cached structural responses.
Sweep counts must be nonnegative; relaxation must be finite and positive. The
distributed prepared block validates these conditions collectively and requires
identical choices on every rank before constructing collective child solvers.
No upper bound on relaxation is claimed to ensure stability.
## Validation and comparison scope
The added unit tests check rational answers for a noncommuting dense mass/Schur
example, preservation of an exact Schur fixed point, zero-sweep bitwise baseline
equivalence, linearity, repeated-application independence, fixed work statistics,
and invalid options. Contraction is asserted only for the selected dense fixture.
The added FEM integration test compares sparse and matrix-free reduced divergence
and transpose actions on three dense vectors, compares the full refined action
against the matrix-free coupling implementation, and checks zero-sweep exact
equivalence using identical child inverses. It repeats these checks after geometry
and discretization revisions and tests stale rejection, cache rebuilding, and
collective option mismatch rejection when run on multiple ranks.
Tests are provided for the coordinated build/test campaign; no benchmark result
or production improvement is claimed by this implementation note. Compare the
new policy against the default using the same mass backend, AMG cycles, material
inverse, full-J operator, saved right-hand sides, and scalar-border sources.
Evaluate independent and two-way stellar-structure policies separately so a
coupling change is not mistaken for a gravity-inverse improvement.