Files
MeanField/experiments/README.md

189 lines
8.6 KiB
Markdown

# Accuracy experiments
This directory is deliberately separate from `tests/`. It uses Catch2 only as
an MPI-aware runner, selector, configuration host, and failure reporter. A run
fails only when the calculation is invalid (for example, non-finite output or a
failed linear solve); measured accuracy is written as data, not as a regression
tolerance.
`experiment_main.cpp` registers the `experiment` Catch2 reporter. It collects
rows recorded with `record_experiment_result` and writes one wide CSV table on
MPI rank zero. Each row carries sweep parameters and numerical metrics, so
results can be plotted or compared across commits.
The initial budget has three sweeps at fixed mesh and polynomial orders:
1. linear-solver tolerance: `1e-8`, `1e-10`, `1e-12`, `1e-14`;
2. production quadrature boost: `0`, `4`, `8`;
3. reference-space decomposition: numerical field/potential error, analytic
projection error, and numerical-to-projection gap.
Run only the budget and choose its output path with:
```text
./mean_field_experiments --experiment-output gravity_budget.csv --catch2 "[accuracy]"
```
## Reduced stellar-surface conditioning experiments
`stellar_null_space_experiments` is a dedicated diagnostic executable rather
than an ordinary verification or validation test. It constructs the analytic
`n = 3` Lane-Emden seed and probes only directions representable by the reduced
surface coordinates: uniform radial homology, three translation-like radial
dipoles, an axisymmetric oblate quadrupole, and a degree-12 zonal spherical
harmonic. Tangential, rotational, stellar-interior-only, and vacuum-only mesh
motions are deliberately absent because they are generated coordinates rather
than root unknowns.
The experiment prints rank-zero progress messages while it builds the seed,
solves its gravity field, and completes each surface-mode case. The reachability
probe records the surface-to-volume lift amplification, complete root Jacobian
response by block, and centered-difference agreement at zero and half the
Keplerian angular speed. Run it with:
```text
mpirun -np 1 ./cmake-build-debug-homebrew/stellar_null_space_experiments \
--experiment-output reduced_surface_reachability.csv \
--catch2 "[null_space][surface_modes][reachability]"
```
The gravity-completed probe solves the linearized mixed gravity subsystem for
the gravity-gradient and gravity-potential variations accompanying each
reduced surface mode. It then measures the complete reduced root response:
```text
mpirun -np 1 ./cmake-build-debug-homebrew/stellar_null_space_experiments \
--experiment-output gravity_completed_surface_modes.csv \
--catch2 "[null_space][surface_modes][gravity_completed]"
```
The gravity solver prints its convergence summary, while the experiment prints
the current mode and completed-case count. This probe prepares each rotation
state only once and does not repeat the expensive nonlinear finite-difference
calculations from the reachability diagnostic.
The surface-frequency probe injects normalized zonal spherical harmonics over
a range of angular degrees. For each degree it lifts the unit surface pattern
once, samples the coefficients of
`det(I + a grad(d))` at the production geometry-inspection points, and locates
the positive and negative critical fractional amplitudes without repeatedly
rebuilding trial geometries. It also records the minimum determinant at
fractional amplitudes `1e-4`, `1e-3`, and `1e-2`:
```text
mpirun -np 1 ./cmake-build-debug-homebrew/stellar_null_space_experiments \
--experiment-output surface_frequency_limits.csv \
--catch2 "[surface_modes][frequency_limit]"
```
The coupled conditioning probe evaluates an extension-aware `n = 3` homology
direction together with the nonuniform reduced surface modes. Its density and
enthalpy tangents include the coordinate-composition terms generated by the
non-affine interior extension, and its gravity variation is completed through
the discrete mixed subsystem so the fixed-infinity exterior response is
consistent. The probe prepares the equilibrium once, reuses one restricted
gravity operator and preconditioner, and uses analytic Jacobian actions:
```text
mpirun -np 1 ./cmake-build-release-homebrew/stellar_null_space_experiments \
--experiment-output coupled_surface_conditioning.csv \
--catch2 "[null_space][surface_modes][conditioning]"
```
The CSV reports prescribed and gravity-completed responses by residual block,
the response normalized by the completed direction, lift conditioning where
applicable, and the convergence of each restricted gravity solve.
The homology mass-cancellation experiment evaluates the signed decomposition
```text
delta M = delta M_density + delta M_geometry
```
without solving gravity or preparing the complete coupled operator. The two
default-build cases provide the registered-order baseline and one uniform
spatial refinement:
```text
mpirun -np 1 ./cmake-build-release-homebrew/stellar_null_space_experiments \
--experiment-output homology_mass_h0_p0.csv \
--catch2 "[null_space][homology][mass_normalization][p_refinement]"
mpirun -np 1 ./cmake-build-release-homebrew/stellar_null_space_experiments \
--experiment-output homology_mass_h1_p0.csv \
--catch2 "[null_space][homology][mass_normalization][h_refinement]"
```
A reproducible one-level uniform polynomial refinement uses a separate build so
all registered field families and their quadrature policies see the same
compile-time order increment:
```text
cmake -S . -B cmake-build-release-homebrew-p1 -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_MAKE_PROGRAM=/opt/homebrew/bin/ninja \
-DCMAKE_C_COMPILER=/opt/homebrew/opt/llvm/bin/clang \
-DCMAKE_CXX_COMPILER=/opt/homebrew/opt/llvm/bin/clang++ \
-DUMFPACK_DIR=/opt/homebrew/lib/cmake/UMFPACK \
-DXAD_DIR=/usr/local/lib/cmake/XAD \
-Dhypre_DIR=/usr/local/lib/cmake/HYPRE \
-Dmfem_DIR=/usr/local/lib/cmake/mfem \
-DBoost_DIR=/opt/homebrew/anaconda3/lib/cmake/Boost-1.82.0 \
-DMEAN_FIELD_UNIFORM_POLYNOMIAL_ORDER_INCREMENT=1
cmake --build cmake-build-release-homebrew-p1 \
--target stellar_null_space_experiments -j 8
mpirun -np 1 \
./cmake-build-release-homebrew-p1/stellar_null_space_experiments \
--experiment-output homology_mass_h0_p1.csv \
--catch2 "[null_space][homology][mass_normalization][p_refinement]"
```
A whole-Jacobian dense singular-value experiment is intentionally deferred.
The checked-in `sandbox.smesh` is too large for a useful dense SVD, and the
current matrix-free root operator does not provide a transpose action needed by
a scalable smallest-singular-value method.
The executable needs the same dependencies, generated module mapping, and
configuration registration as the existing Catch2 test executable. Add
`experiment_main.cpp` and `gravity_accuracy_budget.cpp` as a second executable
next to that target; do not add them to the ordinary test executable.
## P0 preconditioning baseline
The P0 diagnostic establishes the unpreconditioned reference for the complete,
central-density-closed `n = 3` stellar equilibrium Jacobian. It uses an identity
inverse preconditioner with FGMRES, recomputes the true residual independently,
records every residual block, and counts and times Jacobian and preconditioner
applications. A separate fixed-operator Arnoldi measurement acts explicitly on
the right-preconditioned product `J M^-1`. Its singular-value ratio is a
projected Krylov-space condition proxy, not the condition number of the full
Jacobian. The same output records Ritz values, clustering about one,
nonnormality, and the real extent of the projected field of values.
The extended baseline preserves the fixed 40-iteration FGMRES budget used by
the original P0 run and increases the Arnoldi dimension from 12 to 48. It writes
the complete reported FGMRES residual history, block-relative and
manifest-scaled final residuals, the fraction of the squared residual in each
physics block, timings for construction/projection/preparation/direct-residual
measurement, and separate Arnoldi operator and orthogonalization timings. Live
progress messages delimit every expensive phase and report every fourth
Arnoldi application. The CSV records whether it came from a Debug or Release
build.
Run the focused synthetic verification tests with:
```text
./cmake-build-debug-homebrew/tests "[preconditioning][diagnostics][unit]"
```
Run the performance and spectral measurement separately with:
```text
mpirun -np 1 ./cmake-build-release-homebrew/experiments \
--experiment-output preconditioning_p0_identity_extended.csv \
--catch2 "[preconditioning][diagnostics][baseline]"
```
Set `MEANFIELD_SINGLE_JACOBIAN_BENCHMARK=1` to stop after the initial prepared
Jacobian timing instead of running FGMRES and Arnoldi.