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

5.9 KiB

Compact gravity applications

Branch: research/gravity-compact-application-20260917.

This change removes work from applications inside a gravity-only Krylov solve. It does not change equations, coordinates, tolerances, gravity completion, line search, or the verified true-defect gate. Full root preparation and inverse refresh remain mandatory.

Selection and coordinates

PreparedGravitySubsystem accepts a final compile-time application policy. Its default, AutomaticGravityApplications, uses a compact action only when a registered capability is present and the supplied local partition exactly equals the typed canonical partition. A collective minimum selects the same path on every rank. RootRestrictedGravityApplications keeps the original full-root injection/application/restriction as a test reference and fallback. Existing construction and user-facing stellar specifications are unchanged.

The built-in operator capability requires the known physical stellar core and checks the compiled specification contributions: none may modify gravity rows. It reuses GravityFieldOperator::ApplyGravityUnknowns, the existing affine action on gradient and potential at fixed material state and geometry. This applies [M B^T; B 0], including existing reduced/full boundary maps, without invoking zero density or displacement variations. Its compact packing is always gradient followed by potential; the typed root layout chooses the row and value locations independently.

Normalization is unchanged: the action is D_r A_G D_x^-1, and the inverse action is D_x P_G D_r^-1. Factors are gathered from the frozen normalization on refresh, after the new root preparation is ready. Root generations and child inverse currentness invalidate stale applications. No pointers into normalization buffers survive a refresh.

The direct inverse capability recognizes the standard normalized physical preconditioner and independent material/gravity factorization with the exact gravity block identities. It invokes the already-prepared physical gravity block. Unknown custom inverse recipes and other structure factorizations retain the full-root restriction. The capability's application contract is included in the wrapper's compile-time contract; a potentially flexible branch cannot be advertised as stationary. Selecting a compact inverse is a preconditioning choice, not an assertion that it is the exact gravity inverse. Full-root restriction equivalence must be measured for actual fixtures; the same exact gravity true-defect gate is always used.

GravityCompactOperatorAccess and GravityCompactInverseAccess are explicit extension contracts. Custom code opts in by specializing them; similarly named getters alone never enable a shortcut. A registered operator promises the exact gravity principal block, canonical partition, and full diagonal factors. A registered inverse promises a current compact physical action with a declared application contract. These are lower-level numerical extension points, not required model inputs.

Verification

tests/solver/gravity_compact_applications.cpp compares compact and explicit root-reference actions for nontrivial directions, nonuniform row/state factors, and both standard and optional-central-border typed forms. It checks factor refresh, stale root and child inverse rejection, unknown inverse fallback, and collective fallback when only rank zero supplies a noncanonical map. Existing generic tests retain empty-local-rank and true-defect failure coverage.

plateau_gravity_application_diagnostics.hpp supplies plateau_diagnostics::ProbeGravityApplications(subsystem, outputDirectory). Call after preparing the full normalized operator, refreshing its inverse, and preparing/refreshing the subsystem. It writes gravity_applications.csv with three deterministic nontrivial global directions, selected paths, relative/absolute compact-versus-full errors, and separate application times. It neither prepares a candidate nor changes accepted state. The reference policy also allows direct solve comparisons outside the probe. check_numerical_strategies.py automatically checks this CSV when present; --require applications explicitly requires it. Its default-fixture operator/inverse comparison uses error <= 2e-12 * max(1, reference_norm) and rejects nonfinite measurements. Fallback paths are reported without failing selection.

The integration campaign compiled and passed the compact mock tests in serial and on two ranks, and the real-FEM serial comparisons both with and without the central-density border. The frozen n=1.5 helper measured exactly zero operator and inverse output differences for all three dense directions. On that fixture compact operator applications took about 0.018 seconds versus 0.244 seconds for the root reference; inverse applications took about 0.160 versus 0.205 seconds. The first matched gravity solve took 7.25 seconds versus 18.36 seconds before the compact change, with the same 40 iterations and numerical result at the same true-defect tolerances. These are fixture measurements, not universal speedup guarantees.

gravity_applications.csv records selected paths and separate operator/inverse application times. The backend's LinearSolveReport also has application timing fields, but the current numerical_strategy_inner.csv records only aggregate inner solve time. Neither per-application speedup nor aggregate inner timing alone measures a complete Newton step; reduced outer work also includes full-system actions.

Full stellar MPI comparisons remain unvalidated: the larger two-rank integration selection encountered the existing logical radial surface interpolation restriction to one rank. Low-level distributed application and collective-fallback tests passed. The measured default inverse equivalence does not establish equivalence for arbitrary custom compact preconditioners. End-to-end models continue to require the existing strict convergence and virial checks.