Files
MeanField/experiments/GRAVITY_SUBSYSTEM_IMPLEMENTATION_2026-09-17.md

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.