Skip to content

Fix compressible pressure-outlet reconstruction and characteristic classification - #2975

Open
rois1995 wants to merge 10 commits into
su2code:developfrom
rois1995:fix_characteristic_pressure_outlet
Open

rois1995 wants to merge 10 commits into
su2code:developfrom
rois1995:fix_characteristic_pressure_outlet

Conversation

@rois1995

@rois1995 rois1995 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

A large pressure drop at a Riemann outlet can produce a nonphysical reconstructed state. The ordinary outlet also classifies supersonic flow using total speed, so tangential velocity or grid motion can incorrectly switch off the prescribed pressure. TurboRiemann has the same pressure-reconstruction problem, a configuration lookup using the wrong marker type, and a duplicate moving-grid flux subtraction in its implicit path.

The ordinary, Riemann static-pressure and TurboRiemann static-pressure/radial-equilibrium outlets now share a reconstruction along the EOS isentrope. It uses the normal velocity relative to the grid, stops outward expansion at the sonic state, and extrapolates already-supersonic outflow. The ideal-gas path is analytic; the general EOS path integrates density and thermal energy directly. The Riemann and TurboRiemann implicit fluxes include the boundary-state derivative. Ordinary outlets keep the existing fixed-boundary approximation in the implicit matrix: adding the state derivative to approximate numerical-flux Jacobians destabilized the CFL 100 periodic regression. Radial-equilibrium pressure profiles are retained.

CI exposed an overly strict backflow check in the first version. Subsonic reverse flow now uses the existing pressure-outlet closure of extrapolated entropy and tangential velocity. Flow with all characteristics incoming still requires inlet data. New outlet fatal-error calls are serialized to avoid simultaneous OpenMP error reporting.

Unit tests cover the original startup state, pressure and flow classification, moving grids, boundary-state derivatives, frozen SST energy, and a learned EOS. Selected duct/nozzle comparisons, including configurations and plots, are linked below. Regression checks traced the CFL 100 abort to that implicit coupling and found a shared restart input in the supersonic flatplate test. Both are fixed. The periodic case again converges at iteration 1683, and all 71 affected output rows have been checked in their original MPI/OpenMP/AD modes against the final references. Tolerances and test lengths are unchanged. The full CI matrix for the latest commit passed, including the regression, unit, tape and sanitizer jobs.

Additional robustness investigation is still open: changing the rotational periodic stress case to a Riemann static-pressure outlet makes the current implementation abort at CFL 100, while develop converges. Both versions converge with first-order reconstruction. This configuration is outside the current CI matrix, so the green CI result does not resolve that regression. Alternative implicit linearizations are being tested separately; none is included in this PR yet.

This PR builds directly on develop and does not depend on #2943, #2944, #2945 or #2974. It covers single-phase finite-volume pressure outlets. Giles, mixing-plane reconstruction, ordinary real-gas outlet support, FEM, NEMO and continuous-adjoint boundaries remain outside its scope. Existing viscous and numerical-flux Jacobian approximations are retained; full adjoint flow validation is outstanding.

Initial duct/nozzle validation. TurboRiemann tests and earlier regression assessment.

The Peng–Robinson reservoir-inlet experiment tests a separate EOS stopping criterion. That prototype change is not included in this PR.

@rois1995

rois1995 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

I checked the outlet changes on a straight duct and a converging-diverging nozzle, for air and for MDM using Peng–Robinson. These are fixed-wall flow cases. The translating bump used in #2943 served a different purpose: checking Galilean invariance.

The table below records the initial version of this PR, before the later TurboRiemann and regression fixes. The latest results and CI status are in the update below.

Case develop Initial outlet fix
Air duct, Riemann outlet 1571 1403
MDM duct, Riemann outlet 1595 1467
Air duct, ordinary outlet 1482 1403
Air nozzle 1062 1062
MDM nozzle NaN at startup 3616

The numbers are iterations to a log10 RMS density residual of −10. The ducts recover the prescribed pressure. The nozzle exits become supersonic, so the outlet then extrapolates the interior state rather than imposing 1000 Pa. This is not a general claim of faster convergence.

The duct starts at Mach 0.3, with density and velocity specified at the inlet and an outlet pressure 5% below the initial pressure. The nozzle starts at Mach 0.9, with the same inlet type and an outlet target of 1000 Pa. Its throat/inlet area ratio is 0.8 and exit/throat ratio is 1.25. Both use first-order HLLC, implicit FGMRES/ILU, CFL 20, and two MPI ranks.

Duct convergence

The nozzle mesh check used 50×4, 100×8 and 200×16 cells. Between the medium and fine meshes, outlet-average pressure changed by 0.391% for air and 0.124% for MDM; mass flow changed by 0.00834% and 0.00250%. These checks cover those quantities on these cases, rather than establishing general mesh independence.

Configurations, meshes, histories and runner and the original duct/nozzle cases are available. For example: python3 run_cases.py --binary /absolute/path/to/SU2_CFD air_nozzle_100x8.

I also repeated the ordinary air duct and MDM nozzle after merging develop; they still took 1403 and 3616 iterations. The relevant outlet, HLLC and EOS source files had not changed between the two develop versions. Commit and binary details are in the result records.

These are selected local checks. Full CI is not yet green. The change assumes single-phase states; it does not add ordinary-outlet support for real gases or change Giles, FEM, NEMO or continuous-adjoint boundaries. Full adjoint flow validation is still outstanding. The separate Peng–Robinson inlet experiment below is not part of this PR.

@rois1995

rois1995 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

While testing the reservoir-fed MDM nozzle, I found a separate issue at the inlet. The Peng–Robinson conversion from enthalpy and entropy to a thermodynamic state stops on an absolute entropy tolerance. The resulting small density noise can prevent the residual from falling further: in this case it stayed near −8.8 through 20,000 iterations.

A prototype stopping criterion based on the relative change in volume reaches −10 in 628 iterations, with the same outlet fix. The density and pressure fields change by only about 1e−10 relative to their maximum values. The focused EOS test fails seven assertions before the prototype change and passes all 56 afterward.

That EOS change is not included in this PR. The plot compares the original and prototype inlet inversion, both using the repaired outlet. The patch and reservoir testcase are available for a separate review.

Reservoir nozzle convergence

This experiment covers single-phase Peng–Robinson states only. I have not checked the corresponding inlet sensitivities or other real-gas models.

Comment thread SU2_CFD/include/solvers/characteristic_pressure_outlet.hpp Fixed
@rois1995

rois1995 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

For a later change, would it be useful to support real gases with MARKER_OUTLET, or should those cases continue to use MARKER_RIEMANN / Giles?

At present the ordinary outlet is restricted to ideal gases. It uses a numerical flux between the interior and reconstructed boundary states, while the Riemann outlet evaluates the physical flux at the reconstructed state. Allowing real gases therefore needs more than removing the configuration restriction: the ordinary outlet must also provide the EOS derivatives used by the numerical flux, and needs its own tests.

The shared reconstruction in this PR could be reused for that work. I have kept ordinary real-gas outlet support out of this PR.

@rois1995

rois1995 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

I extended the fix to TurboRiemann static-pressure and radial-equilibrium outlets after reproducing the same pressure-reconstruction problem there. Both now use the existing shared helper; the radial-equilibrium pressure profile itself is unchanged. I also corrected a Riemann marker being looked up as a Giles marker, and removed a second subtraction of the moving-grid flux in the implicit path.

For the fixed-wall nozzle checks:

  • MDM: correcting the marker lookup alone still gives NaN at startup. With the pressure fix, TurboRiemann and regular Riemann both reach density residual −7 in 429 iterations. I used −7 here to avoid mixing this check with the separate reservoir-inlet precision issue described above.
  • Air: both old and repaired versions reach density residual −10 in 352 iterations, but the old version leaves an artificial jump at the outlet row. The repaired exit is Mach 1.594 and 40.47 kPa, compared with 0.786 and 89.59 kPa before. The interior flow is already choked in both runs. The repaired TurboRiemann and regular Riemann fields agree to roundoff.

Air nozzle outlet comparison

I also investigated the failing CI jobs. Many individual cases pass; the failures include both solver aborts and changed reference values. Two fixes are included:

  • Allow subsonic reverse flow using the existing pressure-outlet assumption of extrapolated interior entropy and tangential velocity. The original check rejected any reverse flow, breaking several existing cases. Fully incoming flow still needs inlet data.
  • Integrate density and thermal energy directly for a general EOS. This avoids the iterative pressure/density conversion that failed in the learned-gas case. The flatplate and learned-gas reproductions now complete their CI test iterations (100 and 50).

ThreadSanitizer also reported several threads entering the fatal-error handler at once. The new outlet error calls are now serialized.

The remaining reference differences still need assessment. For the wedge case, the residual after 20 iterations changes, but develop and the fix both converge at iteration 48 and their final fields agree within 2.7e−12 relative to the field maxima. I have not replaced the regression reference values or assumed that all other differences have the same explanation.

All three local unit suites pass in normal and four-thread builds. The outlet tests also pass with two MPI ranks and with two ranks × two threads. Forward and reverse reconstructed-state derivative checks each pass 2160 assertions, and differentiated solver compilation passes. The reverse derivative check uses AddressSanitizer. The complete CI matrix, including CoolProp and sanitizer regressions, is now running on the pushed commit.

Nozzle cases, histories, fields and plot. Regression assessment and focused reproductions.

Giles and mixing-plane reconstruction are unchanged. The radial profile is held fixed in the local implicit matrix. The tests cover frozen SST energy in the convective map, not a complete viscous turbomachinery flow. This remains a single-phase outlet change; full adjoint flow validation is outstanding. I added code comments explaining these assumptions and the reconstruction/Jacobian steps.

Code changes. CI rerun.

CI note: the first completed reverse-mode ASAN build failed before compilation because fetching the Eigen submodule returned HTTP 500. Setup then stopped with Ninja missing. The other jobs are still running; GitHub did not accept a retry of that job. This is separate from the regression reference differences discussed above.

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants