185 lines
10 KiB
Markdown
185 lines
10 KiB
Markdown
# Physical slices of the deformed FEM model
|
||
|
||
This optional experiment displays the independent density, enthalpy and actual
|
||
material boundary of a prepared state. It changes no solver equations, fields,
|
||
orders, positivity handling or public library API.
|
||
|
||
## Use
|
||
|
||
Add `--model-slices` to a normal `plateau_diagnostic` invocation. It writes
|
||
`initial_slices` and `final_slices`, each with `xz` and `xy` subdirectories.
|
||
|
||
Optional settings:
|
||
|
||
- `--slice-plane both|xz|xy|yz` (default `both`, meaning xz and xy).
|
||
- `--slice-offset VALUE` (default zero). This is the physical coordinate normal
|
||
to the plane: y for xz, z for xy, x for yz. `both` applies the same offset to
|
||
both planes.
|
||
- `--slice-subdivisions N` (default 6, allowed 2–32). Begin with 4–8 and compare
|
||
two resolutions for a plot whose small features matter. Work grows with the
|
||
number of reference subcells; 32 is an explicit upper bound, not a suggested
|
||
default.
|
||
|
||
Existing harmonic snapshots can be observed through the checked density replay
|
||
path, using the matching binary, mesh and physical specifications:
|
||
|
||
```sh
|
||
plateau_diagnostic --index 3 --angular-momentum 0 \
|
||
--surface-prescription harmonics --surface-degree 4 \
|
||
--mesh /absolute/path/to/saved/input.smesh \
|
||
--density-snapshot /absolute/path/to/saved \
|
||
--model-slices-only --max-newton 0 --slice-subdivisions 6 \
|
||
--output /absolute/path/to/new_observation
|
||
```
|
||
|
||
`--model-slices-only` writes `frozen_slices` and the replay's normal physical
|
||
metrics/provenance, skipping the expensive density-region observations. It does
|
||
not perform Newton iterations. `--model-slices` can also accompany an existing
|
||
frozen density diagnostic. Replay checks still apply; a size match alone does
|
||
not establish compatibility of a saved state.
|
||
|
||
Render one plane with Python, NumPy and Matplotlib:
|
||
|
||
```sh
|
||
python experiments/plot_model_slices.py /absolute/path/to/new_observation/frozen_slices/xz \
|
||
--reference-outline --title 'n=3 rotating trial; unconverged' \
|
||
--output /absolute/path/to/new_figures/n3_trial_xz
|
||
```
|
||
|
||
The helper writes PNG and PDF and refuses to overwrite either. Both axes use
|
||
the same physical length scale. The solid curve is the deformed material
|
||
boundary; the optional dashed curve is the undeformed boundary intersected
|
||
with the same plane. No deformation magnification is applied. A two-sided
|
||
color scale centered at zero retains the sign when a field has both signs;
|
||
the displayed ticks are the actual values, and each color half may have a
|
||
different range. All-positive or all-negative data use a linear color scale.
|
||
No density or enthalpy values are clipped, replaced by an EOS evaluation, or
|
||
logged. Extrema in panel titles are sampled extrema.
|
||
|
||
Field values are linearly interpolated within each supplied triangle at the
|
||
centers of a 512-by-512 scalar grid, then mapped to colors. This avoids Gouraud
|
||
shading's interpolation of RGBA colors, which can change an unchanged affine
|
||
field's appearance under triangle refinement. `--pixels N` changes this display
|
||
resolution (32–2048). Uncovered pixels remain masked; a pixel covered by more
|
||
than one approximate triangle takes the first supplied triangle, with no
|
||
cross-element averaging. No global triangulation or global point-location
|
||
topology is inferred. Pixels can miss subpixel features and straddle a boundary;
|
||
the separately drawn physical outline remains the geometric reference.
|
||
|
||
Final-state plots use the surrounding run's convergence flag when available;
|
||
replayed or initial states are labeled as not assessed by the image. Give a
|
||
descriptive title, including the physical parameters and any known failure,
|
||
when plotting a stalled or otherwise unconverged state. A plausible picture
|
||
does not establish virial balance or an unbordered equilibrium.
|
||
|
||
## Geometry and field contract
|
||
|
||
Only stellar hexahedra are visited. Each is split into a configurable reference
|
||
lattice and consistent tetrahedra within that element. Intersections solve
|
||
`mapped_position[normal] = offset` on the actual curved map along each crossed
|
||
edge, using a safeguarded bracketed root calculation. This is a physical-plane
|
||
cut, not a deformed image of a reference-plane selection. The mapped Jacobian
|
||
must remain valid at every evaluation. Exterior compactification is not used.
|
||
|
||
Density and enthalpy are evaluated directly from their existing FEM fields at
|
||
the resolved reference coordinates. Output triangles keep their owning element
|
||
and separate vertex records. The plotter uses this supplied connectivity and
|
||
never triangulates a global point cloud; consequently it does not connect
|
||
disconnected material across vacuum or average the two DG traces on an
|
||
interface. A plane exactly coincident with an internal element face uses the
|
||
trace from its positive-normal side.
|
||
|
||
The material boundary is found from stellar/nonstellar faces and evaluated from
|
||
the stellar side. Its curve is computed separately from the volume coloring.
|
||
The undeformed outline is independently intersected with the physical plane;
|
||
projecting reference positions of the deformed cut would be a different curve.
|
||
An exactly coplanar surface patch is reported as unsupported instead of being
|
||
silently drawn as a unique intersection curve.
|
||
|
||
The tetrahedral subdivisions are conforming inside each parent hexahedron,
|
||
but their face diagonals are not made globally consistent across differently
|
||
oriented neighboring elements. Boundary faces are triangulated independently
|
||
as well. On a curved shared face, these choices can produce slightly different
|
||
chord approximations: small gaps or overlaps between neighboring element fills,
|
||
or a mismatch between the colored edge and the independently drawn outline.
|
||
Deterministic ownership of a coincident planar face does not remove this curved
|
||
interface approximation. These image artifacts must not be interpreted as
|
||
physical gaps, jumps in geometry or an additional density feature.
|
||
|
||
Curved cuts are displayed using straight triangles and boundary chords. Field
|
||
colors are piecewise linear on those triangles, not exact values throughout
|
||
their interiors. Root tolerances, maximum physical-plane residuals, sampled
|
||
centroid/midpoint chord errors, counts, bounds and time are recorded in each
|
||
plane's `metadata.csv`. The chord errors and bounds are sampled diagnostics,
|
||
not rigorous global enclosures. Tangencies or multiple crossings contained
|
||
between subdivision vertices can be missed; compare subdivisions for image
|
||
stability. This visualization does not certify pointwise positivity or exclude
|
||
small unsampled features.
|
||
|
||
Before interpreting an actual FEM image, export the same saved state and plane
|
||
at two subdivision counts, for example 6 and 12 (or 4 and 8 for a first bounded
|
||
check). Compare the outlines, element-interface seams, sampled chord errors and
|
||
the visible density/enthalpy structure at the same axes and color ranges. The
|
||
pure geometry and plotting controls below do not test differently oriented
|
||
neighboring curved hexahedra and do not replace this export refinement check.
|
||
Globally consistent face triangulation would remove the diagonal mismatch;
|
||
it is not implemented in this bounded diagnostic.
|
||
|
||
The comparison helper enforces a common plane/orientation/offset, increasing
|
||
subdivision counts, shared physical axes and shared per-field color scales:
|
||
|
||
```sh
|
||
python experiments/compare_model_slices.py \
|
||
/absolute/path/to/coarse/final_slices/xz \
|
||
/absolute/path/to/fine/final_slices/xz \
|
||
--source-state /absolute/path/to/original/accepted_state.txt \
|
||
--reference-outline --title 'Same rotating trial; unconverged' \
|
||
--output /absolute/path/outside/source/slice_refinement
|
||
```
|
||
|
||
It writes a side-by-side PNG/PDF and JSON containing triangle-area sums, signed
|
||
piecewise-linear 2D density/enthalpy integrals, surface bounds, segment-length
|
||
sums, exported geometric diagnostics and their absolute/relative changes. Area
|
||
and field integrals include any overlapping triangles; segment-length sums
|
||
include any duplicate segments. These are measures of the displayed slice,
|
||
not exact curved-FEM integrals, 3D mass or virial diagnostics. Near-zero signed
|
||
integrals make relative changes sensitive, so also inspect absolute changes.
|
||
The two panels use the same scalar raster grid and bounds; its pixel resolution
|
||
and overlap ownership are recorded. Quantitative integrals are computed from
|
||
the supplied triangles, independently of the display raster.
|
||
|
||
`--source-state` is the caller's declaration of the common saved state and its
|
||
SHA256 is recorded. The caller must verify that both exports used that state,
|
||
mesh, field orders and physical specifications. The current export CSVs do not
|
||
bind themselves to a snapshot, and this helper does not establish provenance
|
||
from matching plane metadata. Output artifacts must be outside the source
|
||
checkout and existing files are not overwritten.
|
||
|
||
## Checks
|
||
|
||
Every export runs pure geometric controls: unit-cube section area, integration
|
||
of a signed affine field, a curved shear for which the reference-plane cut is
|
||
wrong, surface segment intersection, and deterministic one-sided treatment of
|
||
a coincident internal face. The same controls can run without FEM:
|
||
|
||
```sh
|
||
c++ -std=c++20 -O0 experiments/model_slice_geometry_tests.cpp -o /tmp/model_slice_checks
|
||
/tmp/model_slice_checks
|
||
python -m unittest discover -s experiments -p test_plot_model_slices.py -v
|
||
python -m unittest discover -s experiments -p test_compare_model_slices.py -v
|
||
```
|
||
|
||
The Python controls cover signed independent fields, supplied connectivity for
|
||
disconnected material, equal axes, PNG/PDF rendering, and rejection of a
|
||
cross-element triangle, an off-plane field/outline, and shape exaggeration.
|
||
They are geometry and plotting controls, not a substitute for a coupled-model
|
||
validation run. The exporter checks that its density, enthalpy and displacement
|
||
source buffers remain bitwise unchanged.
|
||
|
||
The comparison controls use an affine signed density and independent enthalpy
|
||
on a unit square at two subdivisions. They check exact area/integrals/perimeter,
|
||
explicit counting of duplicated triangles, shared axes/color normalizations,
|
||
and rejection of a mismatched offset or reversed refinement. They do not run a
|
||
FEM model. An additional affine control verifies that coarse and fine scalar
|
||
rasters agree, and the disconnected-material control verifies masked vacuum.
|