Nozzles

This module contains classes to build/visualize nozzle geometries, which can then be used with De_Laval_Solver.

Converget-Divergent Conical

class pygasflow.nozzles.cd_conical.CD_Conical_Nozzle(Ri, Re, Rt, Rj, R0, theta_c, theta_N=15, geometry_type='axisymmetric', N=100)[source]

Convergent-Divergent nozzle with conical divergent.

Examples

from pygasflow import CD_Conical_Nozzle
import matplotlib.pyplot as plt
Ri = 0.4
Re = 1.2
Rt = 0.2
geom = CD_Conical_Nozzle(Ri, Re, Rt, 0.15, 1, 30, 25)
x, y = geom.build_geometry(100)
plt.figure()
plt.plot(x, y)
plt.xlabel("Length")
plt.ylabel("Radius")
plt.grid()
plt.axis('equal')
plt.show()

(Source code, png, hires.png, pdf)

../../_images/index-1.png
pygasflow.nozzles.cd_conical.CD_Conical_Nozzle.__init__(self, Ri, Re, Rt, Rj, R0, theta_c, theta_N=15, geometry_type='axisymmetric', N=100)
Parameters
Rifloat

Inlet radius.

Refloat

Exit (outlet) radius.

Rtfloat

Throat radius.

Rjfloat

Radius of the junction between convergent and divergent.

R0float

Radius of the junction between combustion chamber and convergent.

theta_cfloat

Half angle [degrees] of the convergent.

theta_Nfloat

Half angle [degrees] of the conical divergent. Default to 15 deg.

geometry_typestring

Specify the geometry type of the nozzle. Can be either 'axisymmetric' or 'planar'. If 'planar' is specified, Ri, Re, Rt will be considered as half of the height of the respective sections (therefore, R is the distance from the line of symmetry and the nozzle wall). To compute the cross section area, “axisymmetric” uses the formula A = pi * r**2, whereas “planar” uses the formula A = 2 * r. Note the lack of width in the planar formula, this is because in the area ratios it simplifies, hence it is not considere here.

Nint

Number of discretization elements along the length of the nozzle. Default to 100.

pygasflow.nozzles.cd_conical.CD_Conical_Nozzle.build_geometry(self, N)

Discretize the length of the nozzle and compute the nozzle profile.

Parameters
Nint

Number of discretization elements along the length of the nozzle. Default to 100.

Returns
xarray_like

x-coordinate along the nozzle length.

yarray_like

y_coordinate of the nozzle wall.

Converget-Divergent TOP

class pygasflow.nozzles.cd_top.CD_TOP_Nozzle(Ri, Re, Rt, R0, theta_c, K=0.8, geometry_type='axisymmetric', N=100)[source]

Convergent-Divergent nozzle based on Rao’s Thrust Optimized Parabolic contours. This is an approximation to the more complex Rao’s method of characteristic.

Notes

Online you can find thesis and papers (the latter literally “copied” the procedure written in the thesis) that build the TOP profile based on the parabolic equation: \(x = a y^{2} + b y + c\)

Then they set the slope constraint on the start and end points of the parabolic section, ending up with a system of 3 equations in the unkowns a,b,c. This is wrong, because the aformentioned parabolic equation does not consider a rotated parabola!!!!

For example:

  1. \(x_{N} = a y_{N}^{2} + b y_{N} + c\)

  2. \(x_{E} = a y_{E}^{2} + b y_{E} + c\)

  3. \(\frac{d x_{N}}{d y_{N}} = 2 a y_{N} + b = \frac{1}{\tan{\theta_{N}}}\)

Here, you are not giving the constraint on the slope of the end point (xE, yE). Therefore, the computed theta_e will be wrong. Another example:

  1. \(x_{N} = a y_{N}^{2} + b y_{N} + c\)

  2. \(\frac{d x_{E}}{d y_{E}} = 2 a y_{E} + b = \frac{1}{\tan{\theta_{E}}}\)

  3. \(\frac{d x_{N}}{d y_{N}} = 2 a y_{N} + b = \frac{1}{\tan{\theta_{N}}}\)

Here, you end up with the correct computed slopes, but \(x_{E} - x_{N}\) will be wrong.

All this because the actual parabola is rotated!!! To solve for a rotated parabola, you can use the Quadratic Bézier parameterization or the general parabola equation: \(\left(A x + C y\right)^{2} + D x + E y + F = 0\)

Examples

from pygasflow import CD_TOP_Nozzle
import matplotlib.pyplot as plt
Ri = 0.4
Re = 1.2
Rt = 0.2
geom = CD_TOP_Nozzle(Ri, Re, Rt, 0.40, 30, 0.7)
x, y = geom.build_geometry(1000)
plt.figure()
plt.plot(x, y)
for k in geom.Intersection_Points.keys():
    plt.plot(*geom.Intersection_Points[k], 'v')
plt.xlabel("Length")
plt.ylabel("Radius")
plt.axis('equal')
plt.grid()
plt.show()

(Source code, png, hires.png, pdf)

../../_images/index-2.png
pygasflow.nozzles.cd_top.CD_TOP_Nozzle.__init__(self, Ri, Re, Rt, R0, theta_c, K=0.8, geometry_type='axisymmetric', N=100)
Parameters
Rifloat

Inlet radius.

Refloat

Exit (outlet) radius.

Rtfloat

Throat radius.

R0float

Radius of the junction between combustion chamber and convergent.

theta_cfloat

Half angle in degrees of the convergent.

Kfloat

Fractional Length of the nozzle with respect to a same exit area ratio conical nozzle with 15 deg half-cone angle. Default to 0.8.

geometry_typestring

Specify the geometry type of the nozzle. Can be either 'axisymmetric' or 'planar'. If 'planar' is specified, Ri, Re, Rt will be considered as half of the height of the respective sections (therefore, R is the distance from the line of symmetry and the nozzle wall). To compute the cross section area, “axisymmetric” uses the formula A = pi * r**2, whereas “planar” uses the formula A = 2 * r. Note the lack of width in the planar formula, this is because in the area ratios it simplifies, hence it is not considered here.

Nint

Number of discretization elements along the length of the nozzle. Default to 100.

pygasflow.nozzles.cd_top.CD_TOP_Nozzle.build_geometry(self, N)

Discretize the length of the nozzle and compute the nozzle profile.

Parameters
Nint

Number of discretization elements along the length of the nozzle. Default to 100.

Returns
xarray_like

x-coordinate along the nozzle length.

yarray_like

y_coordinate of the nozzle wall.

Minimum Length Nozzle with MoC

pygasflow.nozzles.moc.min_length_supersonic_nozzle_moc(ht, n, Me=None, A_ratio=None, gamma=1.4)[source]

Compute the contour of the minimum length supersonic nozzle in a planar case with the Method of characteristics.

The method of characteristics provides a technique for properly designing the contour of a supersonic nozzle for shockfree, isentropic flow, taking into account the multidimensional flow inside the duct.

Assumptions:

  • Planar case

  • Sharp corner at the throat,

  • M = 1 and theta = 0 at the throat.

Parameters
htfloat

Throat height. Must be > 0.

nint

Number of characteristic lines.

Mefloat

Mach number at the exit section. Default to None. Must be > 1. If set to None, A_ratio must be provided. If both are set, Me will be used.

A_ratiofloat

Ratio between the exit area and the throat area. Since this nozzle is planar, it is equivalent to Re/Rt. It must be > 1. Default to None. If set to None, Me must be provided. If both are set, Me will be used.

gammafloat

Specific heats ratio. Default to 1.4. Must be > 1.

Returns
wallnp.ndarray [2 x n+1]

Coordinates of points on the nozzle’s wall

characteristicslist

List of dictionaries. Each dictionary contains the keys “x”, “y” for the coordinates of the points of each characteristic. Here, with characteristic, I mean the points of the right and left running characteristic.

left_runn_charslist

List of dictionaries. Each dictionary contains the keys “Km”, “Kp”, “theta”, “nu”, “M”, “mu”, “x”, “y”. Each dictionary represents the points lying on the same left-running characteristic.

theta_w_maxfloat

Maximum wall inclination at the sharp corner.

Examples

from pygasflow.nozzles.moc import min_length_supersonic_nozzle_moc
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cmx
ht = 1.5
n = 20
Me = 5
gamma = 1.4
wall, characteristics, left_runn_chars, theta_w_max = min_length_supersonic_nozzle_moc(ht, n, Me, None, gamma)
x, y, z = np.array([]), np.array([]), np.array([])
for char in left_runn_chars:
    x = np.append(x, char["x"])
    y = np.append(y, char["y"])
    z = np.append(z, char["M"])
plt.figure()
# draw characteristics lines
for c in characteristics:
    plt.plot(c["x"], c["y"], "k:", linewidth=0.65)
    # draw nozzle wall
    plt.plot(wall[:, 0], wall[:, 1], "k")
# over impose grid points colored by Mach number
sc = plt.scatter(x, y, c=z, s=15, vmin=min(z), vmax=max(z), cmap=cmx.cool)
cbar = plt.colorbar(sc, orientation='vertical', aspect=40)
cbar.ax.get_yaxis().labelpad = 15
cbar.ax.set_ylabel("Mach number", rotation=270)
plt.xlabel("x")
plt.ylabel("y")
plt.title(r"$M_e$ = {}, n = {}, ht = {} ".format(Me, n, ht))
plt.grid()
plt.axis('equal')
plt.tight_layout()
plt.show()

(Source code, png, hires.png, pdf)

../../_images/index-3.png
class pygasflow.nozzles.moc.CD_Min_Length_Nozzle(Ri, Re, Rt, Rj, R0, theta_c, n, gamma=1.4, N=100)[source]

Planar Convergent-Divergent nozzle based on Minimum Length computed with the Method of Characteristics.

Examples

from pygasflow import CD_Min_Length_Nozzle
import matplotlib.pyplot as plt
Ri = 0.4
Rt = 0.2
Re = 1.2
Rj = 0.1
R0 = 0.2
theta_c = 40
nozzle = CD_Min_Length_Nozzle(Ri, Re, Rt, Rj, R0, theta_c, 10)
x, y = nozzle.build_geometry(1000)
plt.figure()
plt.plot(x, y)
plt.xlabel("Length")
plt.ylabel("Radius")
plt.grid()
plt.axis('equal')
plt.show()

(Source code, png, hires.png, pdf)

../../_images/index-4.png
pygasflow.nozzles.moc.CD_Min_Length_Nozzle.__init__(self, Ri, Re, Rt, Rj, R0, theta_c, n, gamma=1.4, N=100)
Parameters
Rifloat

Inlet radius.

Refloat

Exit (outlet) radius.

Rtfloat

Throat radius.

Rjfloat

Radius of the junction between convergent and divergent.

R0float

Radius of the junction between combustion chamber and convergent.

theta_cfloat

Half angle [degrees] of the convergent.

nint

Number of characteristic lines. Must be > 2.

gammafloat

Specific heats ratio. Default to 1.4. Must be > 1.

Nint

Number of discretization elements along the length of the nozzle. Default to 100.

pygasflow.nozzles.moc.CD_Min_Length_Nozzle.build_geometry(self, N)

Discretize the length of the nozzle and compute the nozzle profile.

Parameters
Nint

Number of discretization elements along the length of the nozzle. Default to 100.

Returns
xarray_like

x-coordinate along the nozzle length.

yarray_like

y_coordinate of the nozzle wall.

Rao Parabola Angles

class pygasflow.nozzles.rao_parabola_angles.Rao_Parabola_Angles[source]

This class is used to generate the relation from the extracted data of plot 4-16, page 77, Modern Engineering for Design of Liquid-Propellant Rocket Engines, D.K. Huzel and D.H. Huang.

Useful for finding the Rao’s parabola angles given the fractional length and the area ratio, or vice-versa.

The plot relate the Rao’s TOP nozzle:

  • theta_n, initial parabola angle

  • theta_e, final parabola angle

with the expansion ratio, epsilon, varying the fractional nozzle length Lf.

Note that the data has been manually extracted from the plot in the book, hence it is definitely a huge “approximation”. If you have the original Rao’s plot, you can probably extract better data.

Examples

Visualize the plot:

from pygasflow import Rao_Parabola_Angles
p = Rao_Parabola_Angles()
p.plot()

(Source code, png, hires.png, pdf)

../../_images/index-5.png

Compute the angles at the end points of Rao’s parabola for a nozzle with fractional length 68 and area ratio 35:

>>> from pygasflow import Rao_Parabola_Angles
>>> p = Rao_Parabola_Angles()
>>> print(p.angles_from_Lf_Ar(68, 35))
(36.11883335948745, 10.695233384809715)

Compute the area ratio for a nozzle with fractional length 68 and an angle at the start of the parabola of 35 degrees:

>>> p.area_ratio_from_Lf_angle(68, theta_n=35)
24.83022334667575
pygasflow.nozzles.rao_parabola_angles.Rao_Parabola_Angles.angles_from_Lf_Ar(self, Lf, Ar)

Compute the angles at the end points of Rao’s parabola. Note that linear interpolation is used if Lf is different than 60, 70, 80, 90, 100.

Parameters
Lffloat

Fractional length in percent. Must be 60 <= Lf <= 100.

Arfloat

Area ratio. Must be 5 <= Ar <= 50.

Returns
theta_nfloat

Angle in degrees at the start of the parabola.

theta_efloat

Angle in degrees at the end of the parabola (at the exit section).

pygasflow.nozzles.rao_parabola_angles.Rao_Parabola_Angles.area_ratio_from_Lf_angle(self, Lf=60, **kwargs)

Compute the Area Ratio given Lf, theta_n or theta_e.

Parameters
Lffloat

Fractional length in percent. Must be 60 <= Lf <= 100.

kwargsfloat.

It can either be:

theta_nfloat

The angle in degrees at the start of the parabola.

theta_efloat

The angle in degrees at the end of the parabola.

Returns
Arfloat

The area ratio corresponding to the given angle and Lf. Note that linear interpolation is used if Lf is different than 60, 70, 80, 90, 100.

pygasflow.nozzles.rao_parabola_angles.Rao_Parabola_Angles.plot(self, N=30)

Plot the relation.

Parameters
Nint

Number of interpolated point for each curve. Default to 30.