From 0bf260f04d2594f3a9063761f85579c2127f0607 Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Thu, 17 Sep 2026 10:22:25 -0400 Subject: [PATCH] Record gravity arithmetic diagnostics and bounded model campaign --- .../NUMERICAL_STRATEGIES_2026-09-17.md | 17 ++- .../numerical_strategy_cases_2026-09-17.json | 110 ++++++++++++++++++ experiments/plateau_diagnostic.cpp | 5 + .../solver/stellar_newton_strategy.cppm | 1 + 4 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 experiments/numerical_strategy_cases_2026-09-17.json diff --git a/experiments/NUMERICAL_STRATEGIES_2026-09-17.md b/experiments/NUMERICAL_STRATEGIES_2026-09-17.md index a2d1e29..386fbaf 100644 --- a/experiments/NUMERICAL_STRATEGIES_2026-09-17.md +++ b/experiments/NUMERICAL_STRATEGIES_2026-09-17.md @@ -63,7 +63,7 @@ Right-hand-side condensation includes any remaining gravity defect, and lifting Tolerance-stopped inner Krylov solves approximate a linear Schur action. Flexible outer preconditioning does not make this action exact. Tight inner tolerances, directional derivative checks, and the full lifted residual gate control this limitation. Inner failure propagates explicitly. Operator actions never prepare or mutate the physical state. -The generic reference implementation restricts the full operator and supplied inverse. That preserves normalization, boundary conditions, model borders, and custom preconditioner recipes, but can do unnecessary work in non-gravity blocks. A specialized restricted inverse is a possible later performance improvement once equivalence is tested. +The reference implementation restricts the full operator and supplied inverse. The default automatic application policy can instead reuse the existing physical gravity action and gravity inverse, with the same diagonal normalization. Compile-time capabilities recognize the physical runtime, specification couplings, block identities, and preconditioner factorization. A collective runtime comparison requires the canonical partition on every rank. Unknown runtimes or incompatible partitions use the reference path. The explicit `RootRestrictedGravityApplications` policy remains available for comparisons. This changes block applications, not the nonlinear equations. ## Interpreting reports @@ -78,8 +78,21 @@ Branches: - `research/polynomial-positive-newton-20260917` - `research/gravity-curvature-correction-20260917` - `research/gravity-reduced-newton-20260917` +- `research/gravity-compact-application-20260917` (equivalent block applications) +- `research/gravity-prepared-roundoff-20260917` (prepared-equation consistency) - `research/numerical-strategies-20260917` (combined production integration) The campaign runner builds a committed clean source revision, copies an immutable executable, and records source, mesh, executable, input-state, and output hashes. Serial execution keeps timing comparisons interpretable. Each new run uses a fresh output directory. Frozen probes preserve accepted buffers and verify restoration; they never certify a final physical model. -Validation results and measured limits are recorded below after execution. +### First frozen and production observations (`4ae2f3f`) + +The first immutable build is retained in the workspace under `diagnostics/numerical_strategies_2026-09-17/frozen_v1`, with its source and executable hashes. Its production observations are in `models_v1`, referencing the same frozen executable. + +- **n=1, J=0, polynomial policy:** six accepted full Newton steps; final normalized residual `1.65157289693e-13`. No direction repair. All eight virials pass; maximum `3.73091953522e-7`. This reproduces the earlier converged control. It is a solver/virial milestone, not a pointwise continuum-accuracy certificate. +- **n=1, J=0.1, captured iteration 2:** the base certifies nonnegative; the original full trial is proved negative. Whole-mesh certification takes about 3–4 ms. The sufficient repair fraction is `0.9152726503`; repaired trial polynomials certify and prepare, but tested step lengths `1, 0.5, 0.125` all increase the full residual. The linear model predicts its best step near `0.00825`, with only about 0.46% residual reduction. This is evidence of an overly conservative coupled direction, not evidence that all feasible descent is impossible. +- **Late rotating capture:** the accepted polynomial is already proved negative. The policy returns `invalid_base` and preserves accepted buffers exactly. The first artifact's unvisited repair-report fields incorrectly defaulted to a certificate; the separate certificate file is correct, and commit `5f3eb0b` fixes the report defaults to `unresolved`. +- **n=1.5, J=0, frozen shape-curvature capture:** base residual `1.78804469158e-4`; raw full trial `2.18913190375e-3`; curvature-corrected full trial `1.40702031008e-4`. Gravity remainder drops from `2.18656200516e-3` to `1.37482284578e-12`. Retained coordinates and accepted buffers are unchanged. Correction order measured over the smallest resolved steps is `1.999898`. +- **Reduced frozen action:** Schur action and retained lifted full action differ by `6.71e-19`; minimum central-difference relative error is `1.39e-6`. The original difference grid has only one point sufficiently above the checker's arithmetic floor, so its trend result is honestly **incomplete**. The next build uses larger differences without relaxing thresholds. +- **Production curvature run:** intentionally stopped after six trial rejections at iteration zero, despite converged inner solves. Review identified that the fresh-equation consistency allowance omitted large cancelling gravity contributions. This incomplete run is preserved, including the explicit interruption record; it is not a convergence result. + +Final tests and updated production results follow after execution. diff --git a/experiments/numerical_strategy_cases_2026-09-17.json b/experiments/numerical_strategy_cases_2026-09-17.json new file mode 100644 index 0000000..b9fb194 --- /dev/null +++ b/experiments/numerical_strategy_cases_2026-09-17.json @@ -0,0 +1,110 @@ +[ + { + "id": "n1_J0_curvature", + "arguments": [ + "--index", + "1", + "--angular-momentum", + "0", + "--strategy", + "curvature", + "--max-newton", + "10", + "--no-central", + "--restart", + "160", + "--max-linear", + "200" + ] + }, + { + "id": "n1_J0_reduced", + "arguments": [ + "--index", + "1", + "--angular-momentum", + "0", + "--strategy", + "reduced", + "--max-newton", + "10", + "--no-central", + "--restart", + "160", + "--max-linear", + "200" + ] + }, + { + "id": "n1p5_J0_curvature", + "arguments": [ + "--index", + "1.5", + "--angular-momentum", + "0", + "--strategy", + "curvature", + "--max-newton", + "12", + "--no-central", + "--restart", + "160", + "--max-linear", + "200" + ] + }, + { + "id": "n1p5_J0_reduced", + "arguments": [ + "--index", + "1.5", + "--angular-momentum", + "0", + "--strategy", + "reduced", + "--max-newton", + "10", + "--no-central", + "--restart", + "160", + "--max-linear", + "200" + ] + }, + { + "id": "n1_J0p10_positivity", + "arguments": [ + "--index", + "1", + "--angular-momentum", + "0.1", + "--strategy", + "positivity", + "--max-newton", + "8", + "--no-central", + "--restart", + "160", + "--max-linear", + "200" + ] + }, + { + "id": "n1_J0p10_positivity_curvature", + "arguments": [ + "--index", + "1", + "--angular-momentum", + "0.1", + "--strategy", + "positivity-curvature", + "--max-newton", + "8", + "--no-central", + "--restart", + "160", + "--max-linear", + "200" + ] + } +] diff --git a/experiments/plateau_diagnostic.cpp b/experiments/plateau_diagnostic.cpp index 6b395b2..fb27fa8 100644 --- a/experiments/plateau_diagnostic.cpp +++ b/experiments/plateau_diagnostic.cpp @@ -626,11 +626,16 @@ template int RunContext(Context &context, const Options &o, cons metric("gravity_iterations", strategyDiagnostics.gravityIterations); metric("gravity_failures", strategyDiagnostics.gravityFailures); metric("gravity_prepared_failures", strategyDiagnostics.gravityPreparedFailures); + metric("compact_gravity_operator", strategyDiagnostics.compactGravityOperator); + metric("compact_gravity_inverse", strategyDiagnostics.compactGravityInverse); metric("linear_report_space", static_cast(strategyDiagnostics.lastLinearReportSpace)); metric("gravity_solve_seconds", strategyDiagnostics.gravitySolveSeconds); metric("last_gravity_true_residual", strategyDiagnostics.lastGravityTrueResidual); metric("last_gravity_correction_norm", strategyDiagnostics.lastGravityCorrectionNorm); metric("last_gravity_prepared_defect", strategyDiagnostics.lastGravityPreparedDefect); + metric("last_gravity_affine_disagreement", strategyDiagnostics.lastGravityAffineDisagreement); + metric("last_gravity_arithmetic_allowance", strategyDiagnostics.lastGravityArithmeticAllowance); + metric("last_gravity_prepared_target_threshold", strategyDiagnostics.lastGravityPreparedTargetThreshold); metric("initial_gravity_residual", strategyDiagnostics.initialGravityResidual); metric("completed_initial_gravity_residual", strategyDiagnostics.completedInitialGravityResidual); metric("last_lifted_relative_true_residual", strategyDiagnostics.lastLiftedRelativeTrueResidual); diff --git a/libmeanfield/interface/solver/stellar_newton_strategy.cppm b/libmeanfield/interface/solver/stellar_newton_strategy.cppm index b77c8bc..fd8fc55 100644 --- a/libmeanfield/interface/solver/stellar_newton_strategy.cppm +++ b/libmeanfield/interface/solver/stellar_newton_strategy.cppm @@ -4,6 +4,7 @@ module; #include #include #include +#include #include #include #include