Skip to content

Commit 0b47b13

Browse files
authored
Fix downstream shock Mach numbers (#122)
* fixed CO derivatives by updated element convergence check * corrected shock mach values which were incorrectly based on mw ratios
1 parent f21a58e commit 0b47b13

11 files changed

Lines changed: 405 additions & 44 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ All notable user-visible changes to this project are documented here.
77
### Changed
88

99
### Fixed
10+
- Corrected downstream shock Mach numbers to use finalized gas speeds and
11+
reported sound speeds, including frozen and retained last-valid states.
12+
Documented shock reference frames and the legacy reflected-frozen sound-speed
13+
basis; `M21`/`M52` remain molecular-weight ratios, with no thermochemical or
14+
legacy output changes.
1015
- Fixed premature convergence of minor elements such as carbon in database Air
1116
by checking element-relative balances and gas updates. This can add Newton
1217
iterations and slightly change equilibrium results.

docs/source/examples/shock/example7.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ is still not a converged shock point.
154154
v_sonic2[i] = solution.sonic_velocity[1]
155155
P2_P1[i] = solution.P21
156156
T2_T1[i] = solution.T21
157-
M2_M1[i] = solution.M21
157+
M2_M1[i] = solution.M21 # Legacy molecular-weight ratio, not a Mach ratio
158158
rho2_rho1[i] = 1.0/solution.rho12
159159
v2[i] = solution.v2
160160
@@ -172,7 +172,7 @@ is still not a converged shock point.
172172
v_sonic5[i] = solution.sonic_velocity[2]
173173
P5_P2[i] = solution.P52
174174
T5_T2[i] = solution.T52
175-
M5_M2[i] = solution.M52
175+
M5_M2[i] = solution.M52 # Legacy molecular-weight ratio, not a Mach ratio
176176
rho5_rho2[i] = solution.rho52
177177
u5_p_v2[i] = solution.u5_p_v2
178178

docs/source/examples/shock_examples.rst

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,45 @@ Shock Examples
33

44
Here we describe the example shock problems.
55

6+
Velocity and Mach conventions
7+
-----------------------------
8+
9+
The Fortran, C, Python, MATLAB, and Excel shock interfaces report stations
10+
``[initial, incident, reflected]``, numbered ``[1, 2, 5]`` in legacy CEA.
11+
Speeds are positive magnitudes. The unshocked gas and reflecting wall are
12+
stationary in the laboratory frame.
13+
14+
* ``velocity[0] = u1`` is the upstream gas speed in the incident-shock frame,
15+
also the incident wave speed in the laboratory frame.
16+
* ``velocity[1] = u2`` is the downstream gas speed in the incident-shock frame.
17+
The laboratory-frame gas speed is ``v2 = u1 - u2``.
18+
* ``velocity[2] = u5`` is the downstream gas speed in the reflected-shock frame.
19+
That gas is stationary at the wall, so ``u5`` also equals the reflected
20+
wave-speed magnitude in the laboratory frame (the wave travels back toward
21+
the unshocked gas). The upstream reflected-frame gas speed is
22+
``u5_p_v2 = u5 + v2``. It is not ``u2``.
23+
24+
Thus the reflected mass balance is ``rho2*(v2 + u5) = rho5*u5`` and
25+
``u5 = v2/(rho5/rho2 - 1)``. ``Mach`` is ``velocity/sonic_velocity`` in these
26+
respective shock frames, not a vector of laboratory-frame Mach numbers.
27+
The upstream reflected-shock Mach number would use ``(v2 + u5)/a2`` with
28+
the appropriate upstream sound speed, not the reported downstream entry.
29+
30+
Sound speed is reported as ``sqrt(R*T*gamma_s/M)``. Initial and incident-frozen
31+
states use frozen heat capacities; equilibrium states use the equilibrium
32+
isentropic exponent. Reflected-frozen output retains the legacy incident-state
33+
frozen heat-capacity basis and molecular weight, evaluated with the reflected
34+
temperature in the sound-speed expression. For temperature-dependent heat
35+
capacities this can differ from a locally evaluated frozen sound speed;
36+
``Mach`` uses the reported convention. Retained last-valid states use the same
37+
definition but remain unconverged and need not satisfy shock conservation.
38+
39+
``M21`` and ``M52`` are **molecular-weight ratios**, not Mach-number ratios.
40+
The legacy ``M2/M1`` and ``M5/M2`` output labels and example variables retain
41+
this meaning. Mach ratios, if needed, must be formed from ``Mach`` explicitly,
42+
with due regard to the different reference frames.
43+
644
.. toctree::
745
:maxdepth: 1
846

9-
shock/example7
47+
shock/example7

source/bind/c/cea_enum.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,15 @@
111111
CEA_ROCKET_FROZEN_PRANDTL = 25, \
112112
CEA_ROCKET_EQUILIBRIUM_PRANDTL = 26
113113

114+
/* Shock arrays are ordered [initial, incident, reflected] (stations 1, 2, 5).
115+
* VELOCITY gives gas speeds in the incident frame (1, 2) and reflected frame (5).
116+
* Station 5 is at rest at the wall; its speed also equals the reflected wave-speed
117+
* magnitude in the wall frame. V2 = u1-u2 is wall-frame gas speed at station 2;
118+
* U5_P_V2 is upstream gas speed relative to the reflected wave, not the wall.
119+
* MACH = VELOCITY/SONIC_VELOCITY. Reflected-frozen sound speed retains the legacy
120+
* incident frozen-Cp basis at reflected T. M21/M52 are molecular-weight ratios,
121+
* not Mach ratios. See docs/source/examples/shock_examples.rst for conventions.
122+
*/
114123
#define CEA_SHOCK_PROPERTY_TYPE_ENUM \
115124
CEA_SHOCK_TEMPERATURE = 0, \
116125
CEA_SHOCK_PRESSURE = 1, \

source/bind/python/CEA.pyx

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3391,7 +3391,8 @@ cdef class ShockSolver:
33913391
p0 : float
33923392
Unshocked pressure in bar
33933393
u1 : float, optional
3394-
Shock velocity in m/s (mutually exclusive with Mach1)
3394+
Incident wave speed relative to the stationary unshocked gas in m/s
3395+
(mutually exclusive with Mach1)
33953396
Mach1 : float, optional
33963397
Shock Mach number (mutually exclusive with u1)
33973398
reflected : bool, default True
@@ -3453,7 +3454,12 @@ cdef class ShockSolution:
34533454
Solution object containing shock wave calculation results.
34543455
34553456
Stores shock properties at initial, incident, and optionally
3456-
reflected shock states.
3457+
reflected shock states (legacy stations 1, 2, and 5).
3458+
3459+
Gas speeds and Mach numbers use the incident-shock frame at stations 1
3460+
and 2 and the reflected-shock frame at station 5; they do not share a
3461+
single laboratory frame. The unshocked gas and reflecting wall are at
3462+
rest in the laboratory frame.
34573463
34583464
Parameters
34593465
----------
@@ -3509,7 +3515,13 @@ cdef class ShockSolution:
35093515

35103516
property velocity:
35113517
"""
3512-
Velocity at each shock state in m/s.
3518+
Gas speed in m/s, in each station's shock frame.
3519+
3520+
Entries 0 and 1 are upstream/downstream speeds relative to the incident
3521+
shock. Entry 2 is downstream speed relative to the reflected shock.
3522+
Reflected downstream gas is stationary at the wall, so entry 2 also
3523+
equals the magnitude of the reflected wave speed in the wall frame.
3524+
The upstream reflected-frame gas speed is ``u5_p_v2``, not entry 1.
35133525
35143526
Returns
35153527
-------
@@ -3521,7 +3533,12 @@ cdef class ShockSolution:
35213533

35223534
property Mach:
35233535
"""
3524-
Mach number at each shock state.
3536+
Gas Mach number: ``velocity / sonic_velocity`` at each shock state.
3537+
3538+
Uses the incident-shock frame for entries 0 and 1 and the reflected-shock
3539+
frame for entry 2. Entry 2 is neither a wall-frame gas Mach number (zero)
3540+
nor the upstream reflected-shock Mach number. See ``sonic_velocity``
3541+
for the retained reflected-frozen sound-speed convention.
35253542
35263543
Returns
35273544
-------
@@ -3533,7 +3550,14 @@ cdef class ShockSolution:
35333550

35343551
property sonic_velocity:
35353552
"""
3536-
Sonic velocity at each shock state in m/s.
3553+
Reported sound speed in m/s: ``sqrt(R * T * gamma_s / M)``.
3554+
3555+
Initial and incident-frozen states use frozen heat capacities;
3556+
equilibrium states use the equilibrium isentropic exponent.
3557+
For compatibility, reflected-frozen output uses the incident state's
3558+
frozen heat-capacity basis and molecular weight at the reflected
3559+
temperature. This legacy convention can differ from the local frozen
3560+
sound speed for a gas with temperature-dependent heat capacities.
35373561
35383562
Returns
35393563
-------
@@ -3545,7 +3569,7 @@ cdef class ShockSolution:
35453569

35463570
property rho12:
35473571
"""
3548-
Density ratio across the incident shock (ρ2/ρ1).
3572+
Density ratio across the incident shock (ρ1/ρ2).
35493573
35503574
Returns
35513575
-------
@@ -3617,43 +3641,48 @@ cdef class ShockSolution:
36173641

36183642
property M21:
36193643
"""
3620-
Mach number ratio across the incident shock (M2/M1).
3644+
Molecular-weight ratio across the incident shock (M2/M1), not a Mach ratio.
36213645
36223646
Returns
36233647
-------
36243648
float
3625-
Mach number ratio across the incident shock
3649+
Legacy CEA2 molecular-weight ratio across the incident shock
36263650
"""
36273651
def __get__(self):
36283652
return self._get_scalar_property(SHOCK_M21)
36293653

36303654
property M52:
36313655
"""
3632-
Mach number ratio across the reflected shock (M5/M2).
3656+
Molecular-weight ratio across the reflected shock (M5/M2), not a Mach ratio.
36333657
36343658
Returns
36353659
-------
36363660
float
3637-
Mach number ratio across the reflected shock
3661+
Legacy CEA2 molecular-weight ratio across the reflected shock
36383662
"""
36393663
def __get__(self):
36403664
return self._get_scalar_property(SHOCK_M52)
36413665

36423666
property v2:
36433667
"""
3644-
Velocity at the incident shock state in m/s.
3668+
Station-2 gas speed in the wall/unshocked-gas frame in m/s.
3669+
3670+
Equals ``velocity[0] - velocity[1]``; this is not a shock wave speed.
36453671
36463672
Returns
36473673
-------
36483674
float
3649-
Velocity at the incident shock state
3675+
Gas speed behind the incident shock relative to the wall
36503676
"""
36513677
def __get__(self):
36523678
return self._get_scalar_property(SHOCK_V2)
36533679

36543680
property u5_p_v2:
36553681
"""
3656-
Velocity of the reflected shock wave in m/s.
3682+
Upstream gas speed relative to the reflected shock in m/s.
3683+
3684+
Equals ``velocity[2] + v2``. This is also the reflected wave speed
3685+
relative to station-2 gas, not the wave speed relative to the wall.
36573686
36583687
Returns
36593688
-------

source/bind/python/cea/lib/libcea.pyi

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -689,18 +689,25 @@ class ShockSolver:
689689

690690

691691
class ShockSolution:
692+
"""Stations [1, 2, 5]; speeds/Mach use incident, incident, reflected shock frames."""
692693
last_error: int
693694
def __init__(self, solver: ShockSolver, reflected: bool = True) -> None: ...
694695
@property
695696
def T(self) -> ScalarOrArray: ...
696697
@property
697698
def P(self) -> ScalarOrArray: ...
698699
@property
699-
def velocity(self) -> ScalarOrArray: ...
700+
def velocity(self) -> ScalarOrArray:
701+
"""Gas speeds [u1, u2, u5] in the shock frames; u5 is also the wall-frame wave speed magnitude."""
702+
...
700703
@property
701-
def Mach(self) -> ScalarOrArray: ...
704+
def Mach(self) -> ScalarOrArray:
705+
"""velocity / sonic_velocity, including the legacy reflected-frozen sound-speed basis."""
706+
...
702707
@property
703-
def sonic_velocity(self) -> ScalarOrArray: ...
708+
def sonic_velocity(self) -> ScalarOrArray:
709+
"""sqrt(R*T*gamma_s/M); reflected-frozen uses incident frozen Cp at reflected T."""
710+
...
704711
@property
705712
def rho12(self) -> ScalarOrArray: ...
706713
@property
@@ -714,13 +721,21 @@ class ShockSolution:
714721
@property
715722
def T52(self) -> ScalarOrArray: ...
716723
@property
717-
def M21(self) -> ScalarOrArray: ...
724+
def M21(self) -> ScalarOrArray:
725+
"""Incident molecular-weight ratio M2/M1, not a Mach ratio."""
726+
...
718727
@property
719-
def M52(self) -> ScalarOrArray: ...
728+
def M52(self) -> ScalarOrArray:
729+
"""Reflected molecular-weight ratio M5/M2, not a Mach ratio."""
730+
...
720731
@property
721-
def v2(self) -> ScalarOrArray: ...
732+
def v2(self) -> ScalarOrArray:
733+
"""Station-2 gas speed in the wall frame, u1-u2 [m/s]."""
734+
...
722735
@property
723-
def u5_p_v2(self) -> ScalarOrArray: ...
736+
def u5_p_v2(self) -> ScalarOrArray:
737+
"""Upstream gas speed in the reflected-shock frame [m/s]."""
738+
...
724739
@property
725740
def volume(self) -> ScalarOrArray: ...
726741
@property

source/bind/python/cea/samples/rp1311/example7.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
v_sonic2[i] = solution.sonic_velocity[1]
117117
P2_P1[i] = solution.P21
118118
T2_T1[i] = solution.T21
119-
M2_M1[i] = solution.M21
119+
M2_M1[i] = solution.M21 # Legacy molecular-weight ratio, not a Mach ratio
120120
rho2_rho1[i] = 1.0/solution.rho12
121121
v2[i] = solution.v2
122122

@@ -134,7 +134,7 @@
134134
v_sonic5[i] = solution.sonic_velocity[2]
135135
P5_P2[i] = solution.P52
136136
T5_T2[i] = solution.T52
137-
M5_M2[i] = solution.M52
137+
M5_M2[i] = solution.M52 # Legacy molecular-weight ratio, not a Mach ratio
138138
rho5_rho2[i] = solution.rho52
139139
u5_p_v2[i] = solution.u5_p_v2
140140

0 commit comments

Comments
 (0)