# 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:

1. The angle of the oblique shock wave deflected from the upstream is $$\beta$$; the shock angle.
2. 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.

Figure 1: Oblique shock wave by a wedge

$$M$$ is Mach number. $$\theta$$ is the flow deflection angle. $$\beta$$ is the oblique shock angle.

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.

Figure 2: Properties across an oblique shock

The flow properties in the upstream zone of the oblique shock are $$v_1, M_1, \rho_1, p_1, T_1$$. Those in the downstream zone of the shock are $$v_2, M_2, \rho_2, p_2, T_2$$.
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:

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() and calc_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.