Files
MeanField/experiments/GEOMETRY_QUALITY_EXPERIMENT.md
Emily Boudreaux 75cc638739 perf(allocations): reduced overall allocations by 95%, increaseed jacobian applicatin by 2x
This commit uses global pre allocated work space to dramatically reduce memory usage and allocation time
2026-09-10 06:50:56 -04:00

302 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Geometry quality experiment
`geometry_quality_experiment` observes the production stellar-equilibrium context,
normalization, analytic Jacobian, preconditioner, volume extension, mapper, and
geometry-safe-step estimator. It does not implement a second Newton solver or
change the physical equations. This document describes methods and usage, not
conclusions from a particular run.
## Build and run
The executable is an opt-in CMake target (`EXCLUDE_FROM_ALL`). From the repository
root, using an existing configured release build:
```sh
cmake --build cmake-build-release-homebrew --target geometry_quality_experiment -j 2
./cmake-build-release-homebrew/geometry_quality_experiment --output geometry_quality_results_baseline
```
If the build directory predates the target, regenerate it using the same CMake
configuration first. Building this target does not build or run the full test
suite. The executable does not automatically launch tests.
Use exactly one MPI rank. The executable and geometry observer reject multi-rank
runs: the per-element diagnostic invokes a collective estimator separately for
each local element, which is not a valid distributed loop when rank-local element
counts differ.
The output directory must **not already exist**. Select a new directory for every
run so comparisons cannot accidentally overwrite earlier evidence. The default
mesh path is relative to the current working directory; run from the repository
root or supply `--mesh` explicitly.
Useful initial runs:
```sh
# Geometry and reference-mesh probes only; no diagnostic Newton correction.
./cmake-build-release-homebrew/geometry_quality_experiment --geometry-only --output geometry_quality_results_geometry
# One frozen-seed correction, without costly residual derivative/block-column checks.
./cmake-build-release-homebrew/geometry_quality_experiment --tolerances 0.03 --no-fd --no-block-actions --output geometry_quality_results_fast
# Compare linear accuracy at the identical seed, including default checks.
./cmake-build-release-homebrew/geometry_quality_experiment --tolerances 0.03,0.003 --output geometry_quality_results_tolerances
# Inspect a state reached by up to three production Newton iterations.
./cmake-build-release-homebrew/geometry_quality_experiment --advance 3 --tolerances 0.03 --no-fd --no-block-actions --output geometry_quality_results_advance3_cold
# Repeat that state with the production correction warm-start vector.
./cmake-build-release-homebrew/geometry_quality_experiment --advance 3 --warm --tolerances 0.03 --no-fd --no-block-actions --output geometry_quality_results_advance3_warm
# Replay a previously saved seed correction and inspect additional geometry controls.
./cmake-build-release-homebrew/geometry_quality_experiment --replay-vectors geometry_quality_results_saved/newton_0_vectors.csv --no-fd --no-block-actions --output geometry_quality_results_replay
# Focus a seed replay on diagonal and exact-vertex probes.
./cmake-build-release-homebrew/geometry_quality_experiment --replay-vectors geometry_quality_results_saved/newton_0_vectors.csv --diagonal-only --output geometry_quality_results_vertices
```
Even geometry-only mode constructs the complete production context. Context
construction includes physical preparation and preconditioner setup, so this is
not a lightweight mesh-only program.
## Options
| Option | Default | Meaning |
| --- | --- | --- |
| `--mesh FILE` | `sandbox.smesh` | STROID mesh used by production FEM setup. |
| `--output DIRECTORY` | `geometry_quality_results` | New artifact directory; an existing path is rejected. |
| `--tolerances LIST` | `0.03,0.003` | Comma-separated positive relative linear tolerances less than one. |
| `--max-linear-iterations N` | `200` | Iteration cap for diagnostic linear solves. |
| `--advance N` | `0` | Run production Newton for at most N iterations before freezing the state. |
| `--warm` | Off | Start every diagnostic solve from the correction left in the production context. |
| `--geometry-only` | Off | Run prescribed-direction/reference geometry diagnostics and return. |
| `--no-fd` | Off | Skip full normalized residual directional finite differences. |
| `--no-block-actions` | Off | Skip Jacobian actions with individual correction blocks. |
| `--save-vectors` | Off | Save complete physical/normalized state and correction coefficients. |
| `--replay-vectors FILE` | Off | Load a saved correction after checking its accepted state against this context; evaluate its true linear residual without another linear solve. |
| `--diagonal-only` | Off | Seed replay only: skip full per-element scans, projected-volume controls, and residual/block-column checks; retain diagonal and vertex probes. |
| `--help` | | Print the command-line summary. |
The advancement phase uses production Newton with relative nonlinear tolerance
`1e-8`, default backtracking, and linear tolerance `0.03` / cap `200`. Its linear
settings do not change with `--tolerances` or `--max-linear-iterations`. Check
`trajectory.csv` and the printed accepted-step count: advancement can terminate
before the requested number of iterations.
## Frozen-state protocol
The model matches the current sandbox: nonrotating n=1 polytrope, fixed mass and
angular momentum, fixed central density, and isobaric zero-pressure surface.
The context uses production physical Riesz normalization, the default physical
preconditioner, and FGMRES restart length 40.
All listed diagnostic linear tolerances are evaluated at the same accepted state.
Each starts cold unless `--warm` is present; warm mode reuses the same captured
production correction for each tolerance, not the result of the preceding
diagnostic solve. At the untouched seed that warm vector is zero.
Replay mode reads the exact `--save-vectors` CSV format and checks both saved
physical and normalized accepted-state coefficients against the reconstructed
context, using `1e-12 * (1 + abs(saved_value))` per coefficient. It loads the
normalized correction, denormalizes through the current context, and recomputes
`Jp+F`. It uses only the first requested tolerance, and that tolerance classifies
the verified residual; it does not trigger a new linear solve. Consequently,
`iterations=0` and the replay wall time are **not** fresh linear-solve performance
measurements. A saved direction that does not meet the requested tolerance gets
status `maximum_iterations` as the current diagnostic classification, even though
no Krylov iteration limit was exercised. Replay verifies a saved state, not a
complete source/build/mesh identity.
`--diagonal-only` requires replay, `--advance 0`, and no `--geometry-only` flag.
It disables finite-difference and block-column checks. It still constructs the
full production context, independently checks the replayed correction, and calls
the ordinary global production preflight once, so `solves.csv` retains the
production quadrature boundary as a reference. It avoids repeated full
per-element scans; it is not a no-preflight or mesh-only mode.
No diagnostic correction is accepted. Finite-difference candidates use production
trial preparation, then restore accepted-state preparation before a subsequent
linear solve. The internal diagnostic access scope requires no live solver and
restores accepted-state preparation on exit.
The first diagnostic correction is additionally split into an unweighted mean
radial surface component and the remainder. These are geometry-only directional
comparisons, not independent solutions of the Newton equation. Uniform contraction
is another deliberately prescribed surface direction: each surface parameter is
minus its reference radius, and its volume displacement is generated by the
production extension.
Two additional prescribed-direction controls bypass the surface extension: the
physical-coordinate fields `u(X) = -X` and `u(X) = -(|X|/R) X` are projected into
the existing displacement FE space. Their geometry checks use only core elements
(attribute 1). These are diagnostic volume directions, not alternative
production surface prescriptions and not Newton corrections. At the default
orders, P3 displacement interpolation does not exactly represent the P4 physical
mesh coordinate field; even the nominally affine control therefore tests an
interpolant rather than an exact continuum affine map. Exterior geometry is not
certified by these core-only controls.
When inspecting an unadvanced seed (`--advance 0`) **with replay**, two additional
controls compile the existing production radial-interior prescription at powers
3 and 4 instead of 2. They apply the identical saved surface correction, retaining
the production surface and exterior prescriptions, then inspect all production
geometry rules. These are geometry-only interventions: the correction has not
been recomputed for the changed parameterization, so an improved geometry boundary
does not establish nonlinear convergence or equilibrium accuracy. These controls
do not run in ordinary non-replay or advanced-state inspection.
## Artifacts and interpretation
| File | Contents |
| --- | --- |
| `metadata.txt` | Mesh path/size, compile/compiler identifiers, polynomial increment, model/scaling description, MPI count, requested options, state size, and accepted residual. |
| `blocks.csv` | Accepted state/residual, corrections, and true linear residual `Jp+F`, separated by manifest block. |
| `solves.csv` | Linear tolerance/status/iterations, verified true residual, elapsed whole-solve time, geometry boundary, and differences from the first correction. |
| `surface.csv` | Surface reference coordinates and accepted/correction displacement divided by reference radius. |
| `surface_summary.csv` | Unweighted mean/RMS surface correction fraction, RMS nonmean component, and extrema. |
| `block_actions.csv` | Each individual correction block's contribution to each equation block, including its dot product with the accepted residual. First correction only. |
| `finite_differences.csv` | Blockwise directional derivative errors for the first correction. Header-only when disabled. |
| `extension_checks.csv` | Volume-direction consistency against finite differences of the freshly prepared generated volume displacement, plus trial residual norms. Uses the same first-correction perturbations as the residual derivative checks; header-only with `--no-fd`. |
| `trajectory.csv` | Accepted production iterations before inspection; present with `--advance`. |
| `CASE_vectors.csv` | Optional raw coefficient snapshots from `--save-vectors`. |
| `CASE_geometry_elements.csv` | Sorted per-element geometry boundaries, limiting samples, positions, directional gradients, determinant polynomials, and singular values. |
| `CASE_geometry_mapping_checks.csv` | Directly rebuilt mapped geometry versus the affine prediction at selected limiting samples. |
| `CASE_geometry_limiting_matrices.csv` | Base/directional mapping and reference/physical element matrices for the most limiting elements. |
| `CASE_vertices_geometry_*.csv` | Same geometry diagnostics and unchanged estimator, but with vertex-only sampling on eight selected core elements. Present for seed replay. |
| `CASE_core_diagonal.csv` | Fresh production FE direction along the negative core-corner diagonal, compared with the continuous logical-radius-squared profile. Written for `uniform_contraction` and `newton_0` on recognized sandbox geometry. |
| `uniform_contraction_reference_corner_probes.csv` | Reference transformation probes at and just inside core-element vertices, without inverse-Jacobian evaluation. |
Case names `newton_0`, `newton_1`, etc. follow the requested tolerance order.
`newton_0_mean` and `newton_0_nonmean` refer to the surface split. Geometry probes
also run for `uniform_contraction`.
Core-only controls use `core_projected_affine_contraction` and
`core_projected_physical_radial_contraction`.
Replay power controls use `newton_0_radial_power_3` and
`newton_0_radial_power_4`. The `action_difference_over_F` column in `solves.csv`
is the norm of the change in `Jp` from the first correction, divided by the accepted
residual norm. Compare it with the correction difference when investigating weakly
determined directions.
`solves.csv` writes the production `LinearSolveStatus` enumeration numerically:
`0` means converged, `1` maximum iterations, `2` breakdown, `3` non-finite, and
`4` backend failure.
A diagnostic run can still inspect and save an unconverged correction; check
status and the verified true residual before interpreting it as a Newton solve.
### Norms
`physical_l2` and `physical_linf` are Euclidean/max norms of physical FE
**coefficients**, not spatial integrals or physical field extrema. Different
blocks have different units, so summing or directly comparing their unscaled
physical coefficient norms is generally not meaningful.
Normalized norms use the production frozen scaling; their Euclidean combination
is the single-rank norm used by this experiment's Newton/linear diagnostics.
`linear_residual_over_block_F` divides by that equation block's initial normalized
residual. Retain the absolute numerator when interpreting it: a nearly zero
denominator can make a harmless small absolute residual look relatively large.
Surface summary statistics are unweighted over surface parameters, not area-
weighted spherical averages or a spherical-harmonic decomposition.
### Geometry boundaries and ties
The per-element boundary uses the same union of production quadrature rules as
Newton preflight. It is the first sampled determinant boundary in **[0, 1]** along
the supplied direction, not a search over arbitrary positive step sizes.
`limited=0,boundary_step=1` means no boundary was found in that interval; it does
not locate a boundary at one. The safety step is 90% of a limiting boundary.
Each CSV row represents one distinct element. Counts within one part per million
and within one percent of the global smallest boundary measure near-ties between
elements, not the potentially much larger number of near-tied quadrature points.
Element numbers and rule indices are local; this executable uses rank zero only.
For a limited element the row's sample is its actual limiting quadrature point.
For an unlimited element it is the element center, and rule/point indices are -1.
Thus directional-gradient entries are point samples, **not maxima over an entire
element**. The reported minimum accepted/full-step determinants, by contrast,
come from all sampled rules in that element.
Reference-element singular values describe the map from the element integration
coordinates to the undeformed reference mesh. Mapped singular values describe
the DomainMapper map relative to that reference mesh. Total physical element
values combine both Jacobians. Distinguishing these avoids attributing a poor
reference element to the Newton displacement map alone.
The worst 12 distinct elements receive detailed fresh-mapping checks at fractions
`0, 0.25, 0.5, 0.9, 0.99, 0.999` of their own boundary. Mapping-matrix error is
relative to the predicted matrix norm; determinant error is normalized by the
accepted determinant, not by the small near-boundary determinant. Geometry
validity between quadrature samples is not certified by these checks.
For unadvanced seed replay, additional `CASE_vertices` diagnostics pass all eight
vertices of each selected core element (0, 9, 18, 27, 36, 45, 54, 63) to the
**unchanged production estimator**. These use a different sample set, not different
geometry physics or altered tests. Compare vertex and ordinary quadrature
boundaries explicitly: one does not subsume the other. Vertex-only minimum
determinants are minima over those vertices, not over the element interiors or
the full mesh. The cases include uniform contraction, the replayed correction,
its mean/nonmean split, and radial-power controls. Selected elements are filtered
for core attribute 1 and hexahedral geometry; their numbering remains specific
to the sandbox mesh.
Corner probes cover elements 0, 9, 18, 27, 36, 45, 54, and 63, all their vertices,
and inward fractions `0, 1e-5, 1e-4, 0.001, 0.01, 0.05, 0.1` toward each element
center. These element IDs are specifically useful for the sandbox mesh, not a
universal classification for arbitrary `--mesh` inputs. Exact-vertex probes
evaluate only the reference transformation and its Jacobian; they deliberately
avoid inverses at potentially singular vertices.
The diagonal probe samples element 0 at equal integration coordinates `s`, using
`s = 0, 0.005, 0.010885670926971493, 0.02, 0.05, 0.1, 0.2,
0.276393202250021, 0.5, 0.723606797749979, 0.9, 1`. This includes the production
limiting sample and the P3 GaussLobatto interpolation nodes along that diagonal.
It reads the generated direction's true DOFs into a fresh grid function and
directly evaluates FE values and derivatives. The continuous comparison is
`u_radial = corner_surface_amplitude * r_logical^2`; its derivative uses the
logical transformation and the physical reference-radius derivative. Actual and
desired radial derivatives are both divided by `dr_physical/ds` to obtain radial
gradients, exposing separately the nodal interpolant and coordinate amplification.
No Jacobian inverse is used. The comparison is skipped unless element 0 matches
the sandbox's negative diagonal from logical coordinate -1/4 to -1/8, and assumes
logical stellar-surface radius one. It is not a general core-mode decomposition.
For power-control cases the continuous comparison uses the corresponding radial
power instead of two. Appended determinant coefficients represent
`det(J_reference + alpha * dU/dxi) / det(J_reference)`, evaluated directly by
column multilinearity, including at exact vertices. They apply to the
undeformed seed; the caller restricts these probes to that state. These
coefficients allow independent checks outside the production quadrature sample
set and require no matrix inverse.
### Derivative checks
Residual checks use forward differences
`(F(x + epsilon*p) - F(x))/epsilon`, with epsilon equal to the production safe
step times `1e-2`, `1e-3`, and `1e-4`. They compare against the complete normalized
`Jp`, using frozen normalization and fresh production trial preparation.
These are one-sided first-order checks, not central differences. Expect truncation
error to decrease with epsilon until cancellation or preparation/solve error
dominates. A single small error or three nonmonotone errors do not by themselves
establish or refute a Jacobian defect. Forward steps stay in the predicted
positive-direction interval; negative perturbations are not preflighted.
The accompanying extension check compares
`(generated_volume(x + epsilon*p) - generated_volume(x))/epsilon`
against `BuildVolumeDisplacementDirection(physical_p)`. Its relative error is a
Euclidean true-DOF vector norm divided by the expected direction norm. This checks
normalization, surface perturbation, and production volume generation together;
it is distinct from checking the mapper's element-local analytic variation.
## Reproducibility limits
Preserve the console log with the artifact directory. Metadata records useful
configuration identifiers but does not contain a mesh checksum, a complete
compiler flag dump, or a source/worktree snapshot. For controlled comparisons,
also retain the exact mesh, configured build options, and source revision plus
local diff. Do not equate runs with different initial residuals merely because
their executable or mesh filename matches.
An investigator may additionally save `provenance.txt` beside these artifacts;
that file is not currently produced automatically by the executable.