Oblique Shock Relation¶
An oblique shock results from a sudden change of direction of supersonic flow. The relations of density (\(\rho\)), pressure (\(p\)), and temprature (\(T\)) across the shock can be obtained analytically [Anderson03]. In addition, two angles are defined:
- The angle of the oblique shock wave deflected from the upstream is \(\beta\); the shock angle.
- The angle of the flow behind the shock wave deflected from the upstream is \(\theta\); the flow angle.
See Figure 1 for the illustration of the two angles.
Methods of calculating the shock relations are organized in the class
ObliqueShockRelation
. To obtain the relations of density
(\(\rho\)), pressure (\(p\)), and temprature (\(T\)), the control
volume across the shock is emplyed, as shown in Figure
2. In the figure and in
ObliqueShockRelation
, subscript 1 denotes upstream properties and
subscript 2 denotes downstream properties. Derivation of the relation uses a
rotated coordinate system \((n, t)\) defined by the oblique shock, where
\(\hat{n}\) is the unit vector normal to the shock, and \(\hat{t}\) is
the unit vector tangential to the shock. But in this document we won’t go into
the detail.
-
class
solvcon.parcel.gas.oblique_shock.
ObliqueShockRelation
(gamma)¶ Calculators of oblique shock relations.
The constructor must take the ratio of specific heat:
>>> ObliqueShockRelation() Traceback (most recent call last): ... TypeError: __init__() ... >>> ob = ObliqueShockRelation(gamma=1.4)
The ratio of specific heat can be accessed through the
gamma
attribute:>>> ob.gamma 1.4
The object can be used to calculate shock relations. For example,
calc_density_ratio()
returns the \(\rho_2/\rho_1\):>>> np.around(ob.calc_density_ratio(mach1=3, beta=37.8/180*np.pi), ... 10).tolist() 2.4204302545
The solution changes as
gamma
changes:>>> ob.gamma = 1.2 >>> np.around(ob.calc_density_ratio(mach1=3, beta=37.8/180*np.pi), ... 10).tolist() 2.7793244902
-
gamma
¶ Ratio of specific heat \(\gamma\), dimensionless.
-
ObliqueShockRelation
provides three methods to calculate the ratio
of flow properties across the shock. \(M_1\) and \(\beta\) are
required arguments:
- \(\rho\)
calc_density_ratio()
- \(p\)
calc_pressure_ratio()
- \(T\)
calc_temperature_ratio()
With \(M_1\) available, the shock angle \(\beta\) can be calculated from the flow angle \(\theta\), or vice versa, by using the following two methods:
- \(\beta\)
ObliqueShockRelation.calc_shock_angle()
- \(\theta\)
ObliqueShockRelation.calc_flow_angle()
The following method calculates the downstream Mach number, with the upstream Mach number \(M_1\) and either of \(\beta\) or \(\theta\) supplied:
- \(M_2\)
calc_dmach()
Listing of all methods:
calc_density_ratio()
calc_pressure_ratio()
calc_temperature_ratio()
calc_dmach()
calc_normal_dmach()
calc_flow_angle()
calc_flow_tangent()
calc_shock_angle()
calc_shock_tangent()
calc_shock_tangent_aux()
-
ObliqueShockRelation.
calc_density_ratio
(mach1, beta)¶ Calculate the ratio of density \(\rho\) across an oblique shock wave of which the angle deflected from the upstream flow is \(\beta\) and the upstream Mach number is \(M_1\):
\[\frac{\rho_2}{\rho_1} = \frac{(\gamma + 1) M_{n1}^2} {(\gamma - 1) M_{n1}^2 + 2}\]where \(M_{n1} = M_1\sin\beta\).
This method accepts scalar:
>>> ob = ObliqueShockRelation(gamma=1.4) >>> np.around(ob.calc_density_ratio(mach1=3, beta=37.8/180*np.pi), ... 10).tolist() 2.4204302545
as well as
numpy.ndarray
:>>> angle = 37.8/180*np.pi; angle = np.array([angle, angle]) >>> np.around(ob.calc_density_ratio(mach1=3, beta=angle), 10).tolist() [2.4204302545, 2.4204302545]
Parameters: - mach1 – Upstream Mach number \(M_1\), dimensionless.
- beta – Oblique shock angle \(\beta\) deflected from the upstream flow, in radian.
-
ObliqueShockRelation.
calc_pressure_ratio
(mach1, beta)¶ Calculate the ratio of pressure \(p\) across an oblique shock wave of which the angle deflected from the upstream flow is \(\beta\) and the upstream Mach number is \(M_1\):
\[\frac{p_2}{p_1} = 1 + \frac{2\gamma}{\gamma+1}(M_{n1}^2 - 1)\]where \(M_{n1} = M_1\sin\beta\).
This method accepts scalar:
>>> ob = ObliqueShockRelation(gamma=1.4) >>> np.around(ob.calc_pressure_ratio(mach1=3, beta=37.8/180*np.pi), 10).tolist() 3.7777114257
as well as
numpy.ndarray
:>>> angle = 37.8/180*np.pi; angle = np.array([angle, angle]) >>> np.around(ob.calc_pressure_ratio(mach1=3, beta=angle), 10).tolist() [3.7777114257, 3.7777114257]
Parameters: - mach1 – Upstream Mach number \(M_1\), dimensionless.
- beta – Oblique shock angle \(\beta\) deflected from the upstream flow, in radian.
-
ObliqueShockRelation.
calc_temperature_ratio
(mach1, beta)¶ Calculate the ratio of temperature \(T\) across an oblique shock wave of which the angle deflected from the upstream flow is \(\beta\) and the upstream Mach number is \(M_1\):
\[\frac{T_2}{T_1} = \frac{p_2}{p_1} \frac{\rho_1}{\rho_2}\]where both \(p_2/p_1\) and \(\rho_1/\rho_2\) are functions of \(\gamma\), \(M_1\), and \(\beta\). See also
calc_pressure_ratio()
andcalc_density_ratio()
.This method accepts scalar:
>>> ob = ObliqueShockRelation(gamma=1.4) >>> np.around(ob.calc_temperature_ratio(mach1=3, beta=37.8/180*np.pi), 10).tolist() 1.5607602899
as well as
numpy.ndarray
:>>> angle = 37.8/180*np.pi; angle = np.array([angle, angle]) >>> np.around(ob.calc_temperature_ratio(mach1=3, beta=angle), 10).tolist() [1.5607602899, 1.5607602899]
Parameters: - mach1 – Upstream Mach number \(M_1\), dimensionless.
- beta – Oblique shock angle \(\beta\) deflected from the upstream flow, in radian.
-
ObliqueShockRelation.
calc_dmach
(mach1, beta=None, theta=None, delta=1)¶ Calculate the downstream Mach number from the upstream Mach number \(M_1\) and either of the shock or flow deflection angles:
\[M_2 = \frac{M_{n2}}{\sin(\beta-\theta)}\]where \(M_{n2}\) is calculated from
calc_normal_dmach()
with \(M_{n1} = M_1\sin\beta\).The method can be invoked with only either \(\beta\) or \(\theta\):
>>> ob = ObliqueShockRelation(gamma=1.4) >>> ob.calc_dmach(3, beta=0.2, theta=0.1) Traceback (most recent call last): ... ValueError: got (beta=0.2, theta=0.1), but I need to take either beta or theta >>> ob.calc_dmach(3) Traceback (most recent call last): ... ValueError: got (beta=None, theta=None), but I need to take either beta or theta
This method accepts scalar:
>>> np.around(ob.calc_dmach(3, beta=37.8/180*np.pi), 10).tolist() 1.9924827009 >>> np.around(ob.calc_dmach(3, theta=20./180*np.pi), 10).tolist() 1.9941316656
as well as
numpy.ndarray
:>>> angle = 37.8/180*np.pi; angle = np.array([angle, angle]) >>> np.around(ob.calc_dmach(3, beta=angle), 10).tolist() [1.9924827009, 1.9924827009] >>> angle = 20./180*np.pi; angle = np.array([angle, angle]) >>> np.around(ob.calc_dmach(3, theta=angle), 10).tolist() [1.9941316656, 1.9941316656]
Parameters: - mach1 – Upstream Mach number \(M_1\), dimensionless.
- beta – Oblique shock angle \(\beta\) deflected from the upstream flow, in radian.
- theta – Downstream flow angle \(\theta\) deflected from the upstream flow, in radian.
- delta – A switching integer \(\delta\). For \(\delta = 0\), the function gives the solution of strong shock, while for \(\delta = 1\), it gives the solution of weak shock. This keyword argument is only valid when theta is given. The default value is 1.
-
ObliqueShockRelation.
calc_normal_dmach
(mach_n1)¶ Calculate the downstream Mach number from the given upstream Mach number \(M_{n1}\), in the direction normal to the shock:
\[M_{n2} = \sqrt{\frac{(\gamma-1)M_{n1}^2 + 2} {2\gamma M_{n1}^2 - (\gamma-1)}}\]This method accepts scalar:
>>> ob = ObliqueShockRelation(gamma=1.4) >>> np.around(ob.calc_normal_dmach(mach_n1=3), 10).tolist() 0.4751909633
as well as
numpy.ndarray
:>>> np.around(ob.calc_normal_dmach(mach_n1=np.array([3, 3])), 10).tolist() [0.4751909633, 0.4751909633]
Parameters: mach_n1 – Upstream Mach number \(M_{n1}\) normal to the shock wave, dimensionless.
-
ObliqueShockRelation.
calc_flow_angle
(mach1, beta)¶ Calculate the downstream flow angle \(\theta\) deflected from the upstream flow by using
calc_flow_tangent()
, in radian.This method accepts scalar:
>>> ob = ObliqueShockRelation(gamma=1.4) >>> angle = 48.25848/180*np.pi >>> np.around( ... ob.calc_flow_angle(mach1=4, beta=angle)/np.pi*180, 10).tolist() 32.0000000807
as well as
numpy.ndarray
:>>> angle = 48.25848/180*np.pi; angle = np.array([angle, angle]) >>> np.around((ob.calc_flow_angle(mach1=4, beta=angle)/np.pi*180), ... 10).tolist() [32.0000000807, 32.0000000807]
See Example 4.6 in [Anderson03] for the forward analysis. The above is the inverse analysis.
Parameters: - mach1 – Upstream Mach number \(M_1\), dimensionless.
- beta – Oblique shock angle \(\beta\) deflected from the upstream flow, in radian.
-
ObliqueShockRelation.
calc_flow_tangent
(mach1, beta)¶ Calculate the trigonometric tangent function \(\tan\beta\) of the downstream flow angle \(\theta\) deflected from the upstream flow by using the \(\theta\)-\(\beta\)-\(M\) relation:
\[\tan\theta = 2\cot\beta \frac{M_1^2\sin^2\beta - 1} {M_1^2(\gamma+\cos2\beta) + 2}\]This method accepts scalar:
>>> ob = ObliqueShockRelation(gamma=1.4) >>> angle = 48.25848/180*np.pi >>> np.around(ob.calc_flow_tangent(mach1=4, beta=angle), 10).tolist() 0.6248693539
as well as
numpy.ndarray
:>>> angle = 48.25848/180*np.pi; angle = np.array([angle, angle]) >>> np.around(ob.calc_flow_tangent(mach1=4, beta=angle), 10).tolist() [0.6248693539, 0.6248693539]
See Example 4.6 in [Anderson03] for the forward analysis. The above is the inverse analysis.
Parameters: - mach1 – Upstream Mach number \(M_1\), dimensionless.
- beta – Oblique shock angle \(\beta\) deflected from the upstream flow, in radian.
-
ObliqueShockRelation.
calc_shock_angle
(mach1, theta, delta=1)¶ Calculate the downstream shock angle \(\beta\) deflected from the upstream flow by using
calc_shock_tangent()
, in radian.This method accepts scalar:
>>> ob = ObliqueShockRelation(gamma=1.4) >>> angle = 32./180*np.pi >>> np.around(ob.calc_shock_angle(mach1=4, theta=angle, delta=1)/np.pi*180, 10).tolist() 48.2584798722
as well as
numpy.ndarray
:>>> angle = np.array([angle, angle]) >>> np.around( ... ob.calc_shock_angle(mach1=4, theta=angle, delta=1)/np.pi*180, ... 10).tolist() [48.2584798722, 48.2584798722]
See Example 4.6 in [Anderson03] for the analysis.
Parameters: - mach1 – Upstream Mach number \(M_1\), dimensionless.
- theta – Downstream flow angle \(\theta\) deflected from the upstream flow, in radian.
- delta – A switching integer \(\delta\). For \(\delta = 0\), the function gives the solution of strong shock, while for \(\delta = 1\), it gives the solution of weak shock. The default value is 1.
-
ObliqueShockRelation.
calc_shock_tangent
(mach1, theta, delta)¶ Calculate the downstream shock angle \(\beta\) deflected from the upstream flow by using the alternative \(\beta\)-\(\theta\)-\(M\) relation:
\[\tan\beta = \frac{M_1^2 - 1 + 2\lambda\cos\left(\frac{4\pi\delta + \cos^{-1}\chi}{3}\right)} {3\left(1 + \frac{\gamma-1}{2}M_1^2\right)\tan\theta}\]where \(\lambda\) and \(\chi\) are obtained internally by calling
calc_shock_tangent_aux()
.This method accepts scalar:
>>> ob = ObliqueShockRelation(gamma=1.4) >>> angle = 32./180*np.pi >>> np.around(ob.calc_shock_tangent(mach1=4, theta=angle, delta=1), ... 10).tolist() 1.1207391858
as well as
numpy.ndarray
:>>> angle = np.array([angle, angle]) >>> np.around(ob.calc_shock_tangent(mach1=4, theta=angle, delta=1), ... 10).tolist() [1.1207391858, 1.1207391858]
See Example 4.6 in [Anderson03] for the analysis.
Parameters: - mach1 – Upstream Mach number \(M_1\), dimensionless.
- theta – Downstream flow angle \(\theta\) deflected from the upstream flow, in radian.
- delta – A switching integer \(\delta\). For \(\delta = 0\), the function gives the solution of strong shock, while for \(\delta = 1\), it gives the solution of weak shock.
-
ObliqueShockRelation.
calc_shock_tangent_aux
(mach1, theta)¶ Calculate the \(\lambda\) and \(\chi\) functions used by
calc_shock_tangent()
:\[\lambda = \sqrt{(M_1^2-1)^2 - 3\left(1+\frac{\gamma-1}{2}M_1^2\right) \left(1+\frac{\gamma+1}{2}M_1^2\right)\tan^2\theta}\]\[\chi = \frac{(M_1^2-1)^3 - 9\left(1+\frac{\gamma-1}{2}M_1^2\right) \left(1+\frac{\gamma-1}{2}M_1^2+\frac{\gamma+1}{4}M_1^4\right) \tan^2\theta} {\lambda^3}\]This method accepts scalar:
>>> ob = ObliqueShockRelation(gamma=1.4) >>> lmbd, chi = ob.calc_shock_tangent_aux(mach1=4, theta=32./180*np.pi) >>> np.around([lmbd, chi], 10).tolist() [11.2080188412, 0.7428957121]
as well as
numpy.ndarray
:>>> angle = 32./180*np.pi; angle = np.array([angle, angle]) >>> lmbd, chi = ob.calc_shock_tangent_aux(mach1=4, theta=angle) >>> np.around(lmbd, 10).tolist() [11.2080188412, 11.2080188412] >>> np.around(chi, 10).tolist() [0.7428957121, 0.7428957121]
See Example 4.6 in [Anderson03] for the analysis.
Parameters: - mach1 – Upstream Mach number \(M_1\), dimensionless.
- theta – Downstream flow angle \(\theta\) deflected from the upstream flow, in radian.