Skip to content

New example cases and HyShot II validation harness (#87)#105

Open
jjhans wants to merge 3 commits into
rework-hyshotii-casesfrom
87-new-example-cases
Open

New example cases and HyShot II validation harness (#87)#105
jjhans wants to merge 3 commits into
rework-hyshotii-casesfrom
87-new-example-cases

Conversation

@jjhans

@jjhans jjhans commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Opens the pull request for 87-new-example-cases (issue #87), including the HyShot II updates. Per the plan, issue #87 stays open — the purpose of this PR is to pin down the remaining changes.

What's included

  • The new example cases tracked by New example cases #87 — numbered examples with READMEs and reference data (e.g. 04_jicf_heat_release_profile, 06_autoignition_vitiated_flow).
  • HyShot II validation harness (examples/hyshot_ii/): validation.py reproduces the wall pressure and heat-flux comparisons — fuel-on (reacting), fuel-off (inert), and an equivalence-ratio sweep — against experimental measurements and 3D RANS (CTR) results, computing L1 / L-infinity error metrics. Includes the reference-data CSVs (reference_data/) and a README following the numbered-example pattern.

Verified

  • validation.py reproduces the three reference figures (fuel-on, fuel-off, phi-sweep) from StanShock result CSVs, matching the prior MATLAB reference plots.
  • The Hyshot2Interface FPV case constructs and initializes correctly on the AsymmetricBox geometry (200 + 6 ghost cells, valid time step).

Known remaining work (to pin down)

The FPV + schedule case does not yet advance to completion on the AsymmetricBox geometry:

  • Non-finite Z_3D: divide-by-zero at the injector origin (x_cl = 0) in src/stanshock/models/jicf.py (~L291/307/308/383/385) poisons the 3D mixture-fraction array, so constructing the cubic RegularGridInterpolator fails with ValueError: RHS must contain only finite numbers. Tied to the JICF dead-code / cleanup work.
  • Mesh coupling (Remove mesh dependence of Z mean and variance profiles in JICF. #98): the mixture-fraction profile interpolator is built on the generation mesh (200 pts) but queried on the runtime mesh (206 pts), producing a shape mismatch in the source term.
  • Slow precompute (Vectorize and Annotate JICF Functions #104): JICF Z_3D generation takes ~10 min (69 axial slices at ~10 s each).
  • FRC variant (hyshot_ii_frc.py) is not yet functional (WIP).

Once #98 (and the injector-origin cleanup) land, hyshot_ii_jic.py can be wired to run the live simulation and feed validation.py end-to-end.

Relates to #95, #98, #104.

jjhans and others added 3 commits June 26, 2026 13:05
- 01_sod_shock_tube: validates numerical scheme options (WENO5/O1, HLLC/LF, double-flux) against the analytical Sod solution
- 02_isentropic_nozzle: validates geometry and area-change handling against quasi-1D isentropic nozzle theory
- 04_jicf_heat_release_profile: JICF heat release profile case (in progress — reveals areas for solver improvement)
- 06_autoignition_vitiated_flow: autoignition in vitiated flow (in progress — reveals areas for solver improvement)
Adds validation.py, which reproduces the HyShot II wall pressure and
heat-flux comparisons (fuel-on, fuel-off, and equivalence-ratio sweep)
against experimental measurements and 3D RANS (CTR) results, computing
L1/L-infinity error metrics. Includes the reference-data CSVs and an
example README following the numbered-example pattern.

The validation figures are reproduced from StanShock result CSVs. Live
end-to-end simulation of the FPV+schedule case is pending JICF fixes
(mesh dependence and injector-origin non-finite values).
@TimothyEDawson

Copy link
Copy Markdown
Collaborator

Hey @jjhans , sorry I didn't see these pull requests until just now! I don't get email notifications unless you tag me or assign me as a reviewer. I'll try to look through them and leave a few comments on each one.

One general comment: Don't forget to run pre-commit run --all-files and get it all passing locally before pushing, otherwise the CI will fail on the format step!

@@ -0,0 +1,79 @@
Experiment (Center Point),,Experiment (Upper Bound),,Experiment (Lower Bound),,Inert-HeafFlux-Body-MenterSST,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "HeafFlux"

Not a big fan of having a label for every other column, then a second label of X + Y for each. It was a little difficult to understand and takes extra effort to parse using standard tools like np.loadtxt. I would instead suggest the following changes:

  • Drop "experiment" and move experimental data into their own files, try to avoid empty data points.
  • "Center" should be "Mean."
  • Only keep one header row, don't worry about repeating (e.g. Mean X,Mean Y,Upper X,Upper Y,...).
  • Where possible, collect x-locations into a single column. E.g. experiment lower and upper have the same X coordinates, and they're almost the same as the mean X coordinates, so just have an "X Location [mm]" column followed by each Y data column.
  • Variable names should not unnecessarily repeat information that's already in the file name, i.e. "Inert" "Body", and (if only one model included) "MenterSST".
  • You can easily collect the following:
    • Experimental mean, lower, and upper pressures for the inert and reacting cases (1 X + 6 Y columns) for Body and Cowl (2 files)
    • Same, but for heat flux (2 files, 7 columns each)
    • RANS equivalents for the above, named columns for different cases and turbulence models where appropriate (e.g. "React (Spalart-Allm.)", "Inert (Menter-SST)", "React 1/8C No Walls (Menter-SST)"). Don't strictly need to include "Pressure" or "Heat Flux" as it's in the name of the file. I'm open to other suggestions on how to improve this one.
  • I'm not quite sure what the EQ file contains, so I'll have to come back to it later.


import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to avoid bringing Pandas in as a dependency just for example cases like this. It's a big library, and most of what you're doing with it here should be pretty easy to do using NumPy. If you use np.genfromtxt with names=True, it will create a structured array with column names taken from the header.

def load_stanshock_result(path: str | Path) -> StanShockResult:
"""Load a StanShock CSVWriter result file.

Expects the columns emitted by ``CSVWriter``: ``x [m]``, ``pressure [Pa]``,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My output data doesn't include the units, not sure if it was generated using a different version of CSVWriter than yours.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants