Repository navigation
linstabpy v1.0.0rc6
Pre-release
Pre-release
The supplement examples ship complete: Martini 0-5, Song 32 deg, and
Savarino, with their parity audits, slim reference fixtures, and the
paper-style figures. Two operator corrections came out of that audit.
On a deformed y-symmetric mesh the metric terms now come from the full
eta operators, so the family second derivatives converge at the axis.
The Floquet shift defaults to the continuum chain rule; the LinStab2D
discrete form stays behind matlab_parity.
Added
- Each Savarino map-walk row records its commit, its Slurm job, and its machine.
resolvent_analysisreturns the factor, SVD, and residual stage clocks.- The Savarino line campaign times a recycled sweep against a factor at each frequency.
- Song (2023) example complete (
examples/song/, θ = 32° only): self-contained
supplement pipeline from Song FV export through LinStabPy validation figures.prepare_baseflow.py— Plot3D → nodal.npy(601→599 trim, interpolation, nondim).plot_baseflow.py— mesh + mean-flow panels (examples.figure_styleLaTeX fonts).configs/run_fd4_n30.yaml— FD4, n = 30, β = 19.2, no operator dissipation (ε = 0).song.py— EVP driver; default config →configs/run_fd4_n30.yaml.report_matched20.py,plot_spectrum_matched20.py,plot_eigenmode_lead.py—
Hungarian matched-20 spectrum and lead eigenmode vs Song reference.song_plot_utils.py,reference_paths.py; shipped reference underreference/.- Shipped validation figures under
figures/(baseflow mesh/fields, matched-20
spectrum, lead eigenmode; FD4 n = 30, ε = 0). - Local-only outputs:
inputs/baseflow/,output/fd4_n30/(gitignored). - Validated (FD4 n = 30, ε = 0): 20/20 Song modes within |Δω| ≤ 0.01; lead |Δω| ≈ 0.002.
- Martini (2024) examples 0–5 — presentation + parity closure (
examples/martini/):
audit CLOSED 2026-08-18 (AUDIT_PLAN.md; steps A→E, user sign-off all six cases).- Per-case plotters:
example_{0..5}_plots.pyplus shared
plot_compare_utils.py,split_martini_fixtures.py,
run_all_martini_examples_and_plots.py— thesis-style mosaics (LinStab2D |
linstabpy | peak-normalized % error), spectra, and baseflow panels. - Slim MATLAB reference fixtures under
examples/martini/LinStab2DResults/
(compact u+v / u+v+w, complex128); bundledlinstab2D_scripts/and
regenerate_martini_fixtures.shfor MATLAB → NPZ regen. - Bundled baseflow
.matfiles underexamples/martini/baseflows/
(BL_BF.mat,Step_BF.mat,M09jet.mat,Paraboloid_BF.mat). - Shipped presentation PNGs next to each driver (baseflow, spectrum, mode
mosaics for Ex. 1–5; validation triptych for Ex. 0).
- Per-case plotters:
- Savarino (2026) example — reorganized supplement reproduction (
examples/savarino/,
θ = 30.8° SWBLI resolvent validation, Figs. S4–S6):- Layout:
configs/(YAMLs + grids),reference/(author baseflow + packed
response modes),output/(run records, figures, local intermediates). - Configs (
configs/):map_base.yaml,mack_f2_b45.yaml,
liftup_f1em4_b163.yaml,point.sbatch.template,savarino_map317_points.csv
(317-pt β–f grid for dense-map campaigns). - Shipped reference: Tecplot base flow under
reference/baseflow/; packed
reference/savarino_response_{mack,liftup}.npz(primitive ρ′, u′, v′, w′, T′). - Shipped results (
output/):savarino_map2_200pt.csv(200-pt gain-map run
record),savarino_map317pt.csv(317-pt minimal dense subset from PhD
map_minimal_keep_author200), validation figures underoutput/figures/
(mode comparisons + 200-/317-pt gain maps). collect_campaign.py --from-npz— aggregate NPZ +.metrics.jsontrees into
the run-record CSV layout (for PhD dense-map campaigns without Slurm logs).gen_campaign.py --grid {author200,dense317}— Slurm/local campaign generator
for 200- or 317-point grids.- Plotters aligned with PhD Savarino2026 style:
plot_gain_map.py— tensor/PCHIP interpolation, σ₁² colorbar with ×10⁴
on top, Mack / lift-up peak markers (plot_resolvent_map_savarino_style.py
parity); optional--show-points/--baseline-summaryfor diagnostics.compare_modes.py— Song eigenmode layout, peak-normalised ±1 colourbar,
ymax 0.06 (Mack) / 0.1 (lift-up) (plot_savarino_modes_linstabpy_template.py
parity).
- Layout:
Changed
- Recycled GMRES restarts. The restart is a Krylov length. It is never the system size.
certified_rsvdlogs every check when one check fails. One seed skips the multi-seed check.- Floquet shift default is now
continuum(LINSTABPY_FLOQUET_SHIFT,
numerics.floquet_shift):DZ += iα I,D2RZ += iα DR,D2Z += 2iα DZ − α² I,
the chain rule of(∂z + iα). The LinStab2D algebra (D2RZ += iα IandD2Z
built from the already-shiftedDZ, i.e.−3α² I) stays available as
matlab_parity; the Martini Ex. 3 YAMLs andexamples/sawtoothpin it.
Plane Poiseuille at Re = 10⁴, α = 1 (Orszag 1971):continuumconverges to
ω = 0.23752649 + 0.00373967i (|Δω| 3.8e-4 → 1.8e-6 for ny 128 → 512);
matlab_paritystalls at |Δω| ≈ 3.2e-4, a growth rate 8.5 % low, at every
resolution. Any unpinned Floquet run changes with this default. - Replaced the legacy Song figure/pack/matrix scripts with the pipeline above;
seeexamples/song/README.mdfor run order. song.pycreates the output NPZ parent directory before save and reads
numerics.operator_dissipationfrom YAML (disabled, ε = 0 for this test).song_plot_utils.load_song_leading_mode_npztransposes the shipped reference
eigenmode NPZ to LinStabPy(ny, nx)layout for plotting..gitignorere-ignores regenerated example outputs (examples/**/figures/,
examples/**/output/, Songinputs/baseflow/, logs) after the example PNG
whitelist; Songfigures/and reference NPZ are shipped; raw Plot3D exports
underinputs/raw/stay local.- Song plot scripts require LaTeX via
figure_style.check_plot_environment;
seeexamples/song/README.mdfor system packages (texlive-latex-extra, …). examples.figure_style:check_plot_environment(require_latex=…)with install
hint, optionaldpi/pad_inchesonsave(); tests intests/test_figure_style.py.- Grouped Song (2023) reference assets under
examples/song/reference/:
baseflow/song_32deg.npz,eigenmode/song_32deg_leading_mode.npz,
spectrum/eigenvalues.dat,spectrum/omega_i.csv. Addedreference_paths.py
and updated configs, figure scripts, and tests. - Martini fixture layout and git policy:
- Shipped NPZ:
examples/martini/LinStab2DResults/*.npzonly (slim MATLAB
reference). Root-levelexample_*.npzfrom linstabpy drivers are
gitignored (regenerated locally; several exceed the 60 MiB tracked-file
guard). - Raw MATLAB
.matexports stay outside Git inmartini_examples/(gitignored
scratch; recreated byregenerate_martini_fixtures.sh). - Run logs under
examples/martini/_run_logs/are gitignored. - Renamed
examples/martini/data/→baseflows/.
- Shipped NPZ:
- Martini plot/compare layer (repo mosaics ≤ 0.49% peak-norm vs campaign;
Ex. 4 cavity audit closed — residual tail is MATLABeigsconvergence, not
operator/BC):plot_compare_utils.py:used_ind0-based gridding,matlab_plot_grid_shape,
compact_resolvent_modes_uvw, peak-normalized mosaic triptychs.example_4_plots.py/split_martini_fixtures.py: slim MATLAB u+v+w compare
with joint complex scaling; Example 4 YAML pinsPr: 0.7and
zero_dmudT: truefor LinStab2D parity.compare_martini_examples.pyandtests/test_martini_parity_compare.py
updated forLinStab2DResults/fixture paths and compact mode layout.
- Moved library validation CLIs from
examples/martini/totests/tools/
(assembly_parity.py,assembly_metrics_diff.py,lnse_equivalence_harness.py,
matlab_source_parity.py,symbolic_compressible_nse.py,
coefficients_reference_base.py,NSE_DERIVATION.md). See
tests/tools/README.mdfor rationale and owner review checklist. - Removed unused maintainer-only scripts from
examples/martini/:
check_parity_matrices.py,compare_operator_construction.py,
perf_memory_operator_parity.py,operator_matrix.json,branch_matrix.json,
martini_c64_max_rel.txt,martini_examples.sbatch. - Savarino example layout and git policy:
- Moved point YAMLs, campaign template, and 317-pt grid into
configs/; run
records intooutput/(savarino_map2_200pt.csvwas at example root). reference_paths.py:GAIN_MAP_CSV,GAIN_MAP_317_CSV, figure paths under
output/figures/; compare outputs underoutput/compare/..gitignoreships only curated Savarino outputs: both map CSVs and
output/figures/*.png. Gitignored:output/baseflow/*.npy(from
savarino_to_npy.py),output/compare/**/*.npz(fromrun_compare_points.py),
reference/zenodo/. Whitelist repeated after rootoutput/rule.run_compare_points.py,gen_campaign.py,collect_campaign.py,mode_oracle.py
updated forconfigs/paths.- See
examples/savarino/README.mdfor minimal workflow and maintainer scripts
(verify_norm_convention.py,mode_oracle.py,fetch_zenodo.py,
pack_reference_modes.py).
- Moved point YAMLs, campaign template, and 317-pt grid into
Fixed
Mesh.deformon a y-symmetric mesh with a non-separable map: thedJ/Q
metric terms of the symm/asymm family operators are now differentiated with
the fullDy/D2y(the coordinate map has no η parity), as LinStab2D
DeformMesh.mdoes. Before, the family stencils were applied to the
coordinates themselves andD2y_asymm/D2y_symmdid not converge at the axis
rows (relative error growing like 1/h under refinement: 7.7 → 61 for
n = 16 → 128 on a polynomial map; 3.5 → 29 on the Z² map). After: 2.2e-4 → 3.9e-7
(order 3, asymm) and 2.1e-3 → 3.1e-5 (order 2, symm). Onlyy_symmetry=True
meshes on the full-2D deform path are affected (Martini Ex. 5 paraboloid;
the SWBLI cases are untouched). Regression:test_deform_full_2d_family_metric_terms_use_full_operators.- The walk probe uses the last response, not a ones vector.
- A walk GMRES has a four-iteration cap. A dead walk raises and factors this omega.
append_rowrefuses a row that does not match the header.
Removed
- Dropped
song_fig{1,2,3}_*.py,pack_run.py,run_song_2023_*.py,song.sh,
song_32deg_spectrum_quoted.csv, and the oldsong_32deg*.yaml/ sbatch configs
fromexamples/song/. - Dropped committed LinStabPy outputs from the old flat
examples/song/layout
(song_32deg_modes.npz,song_32deg_spectrum.csv,song_matlab_timing.json,
root-levelsong_fig*.png). Large EVP dumps and raw Plot3D inputs stay local;
curated reference NPZ and validation PNGs now live underreference/and
figures/respectively. - Dropped the 31.6 deg Song example from
examples/song/: baseflow
(song_316deg.npz,song_316deg_leading_mode.npz), reference spectrum
(song_316_eigenvalues.dat), configs (song_316deg.yaml,song_316deg.sbatch),
and comparison helpers (compare_evp_to_song316.py,parse_song316_eigenvalues.py).
The shipped example is 32 deg only; 31.6 deg validation stays in the PhD case tree. - Dropped committed linstabpy driver NPZ from
examples/martini/root
(example_*.npz, legacy*_values.npz/*_modes.npz/*_logs.npzsplits).
Regenerate locally via./run_all_examples.shor per-case drivers; parity
against MATLAB usesLinStab2DResults/only. - Dropped old debug/support PNGs from
examples/martini/(per-case
*_support_components*.png, legacy single-panelexample_*_{blasius,jet,...}.png
layouts superseded by mosaic figures). - Dropped
savarino_corner_probe_uv.yamlandsavarino_corner_probe_wonly.yaml
(side experiments; not part of the S4–S6 reproduction path). - Dropped example-root Savarino YAMLs and Slurm template (now under
configs/):
savarino_point_f2_b45.yaml,savarino_point.sbatch.template; renamed
compare_liftup_f1em4_b163.yaml→liftup_f1em4_b163.yaml. - Dropped committed PNGs from
examples/savarino/reference/(figures now under
output/figures/).