5.2 KiB
Prepared gravity subsystem and curvature correction
This branch introduces solver components; the complete equilibrium equations, normalization, and model specification remain the source of truth.
Block and lifetime contracts
MakeGravityBlockPartition<Form>(layout) selects the gravity-gradient and
gravity-potential blocks by their compiled value and residual types. Its
constraints reject forms lacking those blocks. The complement is retained in
root order, including any generated angular-momentum or central-density border.
There are no string identifiers or fixed root offsets in this selection.
GravityBlockPartition also has a checked explicit-index constructor for
algebraic tests and other compiled adapters. Local partitions may be empty;
gravity and retained local systems must be square. A globally empty gravity
system is rejected by the prepared linear backend. Gather/injection require
preallocated, nonoverlapping storage.
PreparedGravitySubsystem owns gravity operator/preconditioner workspaces and the
existing prepared linear backend. It borrows the full normalized operator,
inverse, and communicator at stable addresses. It is neither movable nor
copyable. Preparation records the root preparation generation. After candidate
preparation the caller must refresh its physical inverse and explicitly refresh
the subsystem; stale applications and solves fail. The subsystem does not
prepare a candidate, change an accepted state, or commit a step.
The exact gravity action is the principal restriction of the root Jacobian.
The default automatic policy uses the existing compact physical gravity action
when a declared compile-time capability and collectively checked canonical
partition permit it. Otherwise it injects, applies, and restricts the full root
operator. The selected preconditioner similarly uses a supported compact
physical gravity block or the supplied root inverse's restriction. Neither
choice asserts an exact gravity inverse. Both paths retain the same diagonal
normalization and boundary maps, persistent scratch storage, and the backend's
independently checked true-defect gate. RootRestrictedGravityApplications
remains an explicit reference policy. Equality tests and measured application
costs are recorded in
GRAVITY_COMPACT_APPLICATIONS_2026-09-17.md.
Attempted solves, completed inner iterations, failed calls, completed solve time, and the last completed solve report are available without history allocation. Contract exceptions count as failed calls but do not trigger new collectives to measure elapsed time during unwinding.
The existing FGMRES backend now admits ranks with zero local equations while
requiring a nonempty global system. GetConfiguration() returns its immutable
prescription so another prepared operator can reuse the same backend options.
Curvature correction
PreparedGravityCurvatureCorrection captures G(x) and J_G(x) p before any
candidate preparation. For a prepared candidate x + alpha p it solves
G_z(x + alpha p) delta_z = G(x) + alpha J_G(x) p - G(x + alpha p).
Only the compact gravity correction is returned. The caller may inject it only after a converged inner report, then must prepare and evaluate the complete candidate again before applying its usual acceptance rules. In particular, improving gravity does not certify the hydrostatic, material, or shape residual.
For smooth equations with uniformly bounded inverse gravity block, the right
side and correction are second order in alpha. This preserves the base and
Newton tangent even when the base does not lie on the gravity solution manifold.
It differs from projecting the candidate to G=0, which can introduce a finite
correction at zero step when the base gravity residual is nonzero. Inexact inner
tolerances control cancellation of the remainder; they cannot replace the outer
equilibrium and virial checks.
The owner captures a new base for each new Newton direction and invalidates the cache when that direction is discarded. The stored base generation is exposed for diagnostics; preparing trials intentionally does not invalidate the captured base arrays. Reusing those arrays after replacing the base or direction violates the caller's explicit lifecycle contract.
Test coverage
tests/solver/gravity_subsystem.cpp covers typed forms with/without a central
border, noncontiguous and differently ordered row/value maps, invalid maps and
overlapping storage, exact restricted solves, true-defect failure, nonfinite
inputs, stale operator/inverse preparation, locally empty MPI partitions,
globally empty rejection, preserved backend options, zero affine curvature at
an off-manifold base, and the second-order correction at curved trial geometry.
The integration campaign compiled these components and passed their serial and
supported two-rank tests, including locally empty partitions. Real stellar
serial fixtures also passed compact/reference comparisons with and without the
central-density border. Full stellar MPI operation remains unvalidated because
the existing logical radial surface interpolation is restricted to one rank.
Algebraic tests alone do not establish a virial-qualified stellar equilibrium;
the separate model campaign applies the unchanged physical acceptance checks.