C-D Nozzles
pygasflow comes with a nozzle subpackage, aimed to build and visuale different nozzle designs.
At the time of writing, three different nozzles are implemented:
CD_Conical_Nozzle: the nozzle’s divergent is conical. Support both planar and axisymmetric geometry.CD_TOP_Nozzle: Thrust Optimized Parabolic, based on Rao’s parabolic approximation. Support both planar and axisymmetric geometry.CD_Min_Length_Nozzle: Minimum Length Nozzle built with the Method of Characteristics where the expansion takes place through a centered Prandtl-Meyer wave emanating from a sharp corner throat. Support only planar geometry.
[1]:
import numpy as np
import matplotlib.pyplot as plt
from pygasflow.nozzles import (
CD_Conical_Nozzle,
CD_TOP_Nozzle,
CD_Min_Length_Nozzle
)
Let’s look at the help, for example about the CD_Conical_Nozzle:
[2]:
CD_Conical_Nozzle?
Init signature:
CD_Conical_Nozzle(
Ri=0.4,
Re=1.2,
Rt=0.2,
Rj=0.1,
R0=0,
theta_c=40,
theta_N=15,
**params,
)
Docstring:
Convergent-Divergent nozzle with conical divergent.
Examples
--------
Compute the length of a conical nozzle:
>>> from pygasflow.nozzles import CD_Conical_Nozzle
>>> Ri, Re, Rt = 0.4, 1.2, 0.2
>>> nozzle = CD_Conical_Nozzle(Ri, Re, Rt, theta_c=30, theta_N=25)
>>> nozzle.length
np.float64(2.53988146753074)
Change the angle of the divergent section and retrieve the new length
of the nozzle:
>>> nozzle.theta_N = 60
>>> nozzle.length
np.float64(1.0082903768654763)
Visualize the nozzle:
.. bokeh-plot::
:source-position: above
from pygasflow.nozzles import CD_Conical_Nozzle
Ri, Re, Rt = 0.4, 1.2, 0.2
nozzle = CD_Conical_Nozzle(Ri, Re, Rt, theta_c=30, theta_N=25)
nozzle.plot(interactive=False)
Parameters of 'CD_Conical_Nozzle'
=================================
Parameters changed from their default values are marked in red.
Soft bound values are marked in cyan.
C/V= Constant/Variable, RO/RW = ReadOnly/ReadWrite, AN=Allow None
Name Value Type Bounds Mode
inlet_radius 0.4 Number (0, 3) V RW
outlet_radius 1.2 Number (0, 3) V RW
throat_radius 0.2 Number (0, 3) V RW
junction_radius_j 0.1 Number (0, 0.5) V RW
junction_radius_0 0 Number (0, 0.5) V RW
theta_c 40 Number (0, 90) V RW
theta_N 15 Number (0, 90) V RW
theta_e 15 Number C RW
fractional_length 0.8 Number (0.6, 1) V RW
geometry_type 'axisymmetric' Selector V RW
N 200 Integer (10, 1000) V RW
error_log '' String V RW
is_interactive_app False Boolean V RW
title '' String V RW
gamma 1.4 Number (1, 2) V RW
n_lines 10 Integer (3, None) V RW
inlet_area 0.0 Number (0, None) C RW
outlet_area 0.0 Number (0, None) C RW
throat_area 0.0 Number (0, None) C RW
length_convergent 0.0 Number V RW AN
length_divergent 0.0 Number V RW AN
length 0.0 Number (0, None) V RW
length_array None Array C RW AN
wall_radius_array None Array C RW AN
area_ratio_array None Array C RW AN
shockwave_location (None, None) Tuple C RW
Parameter docstrings:
=====================
inlet_radius: Alias ``Ri`` in the constructor.
outlet_radius: Alias ``Re`` in the constructor.
throat_radius: Alias ``Rt`` in the constructor.
junction_radius_j: Radius of the junction between convergent and divergent.
Alias ``Rj`` in the constructor.
junction_radius_0: Radius of the junction between combustion chamber and convergent.
Alias ``R0`` in the constructor.
theta_c: Half angle [degrees] of the convergent
theta_N: Half angle [degrees] of the conical divergent
theta_e: Half angle [degrees] of the conical divergent at the exit section.
fractional_length: Fractional Length of the nozzle with respect to a same exit
area ratio conical nozzle with 15 deg half-cone angle.
Alias ``K`` in the constructor.
geometry_type: Specify the geometry type of the nozzle:
* ``"planar"``: the radius indicates the distance from the line
of symmetry and the nozzle wall. The area is computed with
``A = 2 * r``. Note the lack of depth in the formula: this is
because it simplifies.
* ``"axisymmetric"``: the area is computed with
``A = pi * r**2``.
N: Number of discretization elements along the length of the nozzle.
error_log: Visualize on the interactive application any error that raises
from the computation.
is_interactive_app: If True, exceptions are going to be intercepted and shown on
error_log, otherwise fall back to the standard behaviour.
title: < No docstring available >
gamma: Ratio of specific heats, γ = Cp / Cv
n_lines: < No docstring available >
inlet_area: < No docstring available >
outlet_area: < No docstring available >
throat_area: < No docstring available >
length_convergent: < No docstring available >
length_divergent: < No docstring available >
length: Total length of the nozzle, convergent + divergent.
length_array: < No docstring available >
wall_radius_array: < No docstring available >
area_ratio_array: < No docstring available >
shockwave_location: Location of the shockwave in the divergent: (loc, radius).
Init docstring:
Parameters
----------
Ri : float
Inlet radius.
Re : float
Exit (outlet) radius.
Rt : float
Throat radius.
R0 : float
Radius of the junction between combustion chamber and convergent.
Rj : float
Radius of the junction between convergent and divergent.
File: ~/Documents/Development/pygasflow/pygasflow/nozzles/cd_conical.py
Type: ParameterizedMetaclass
Subclasses:
Axisymmetric nozzles
Axisymmetric nozzles use a circular cross section. Let’s define the important parameters:
[3]:
Ri = 0.4 # inlet radius of the convergent section
Rt = 0.2 # throat radius
Re = 1.2 # exit (outlet) radius of the divergent section
Rj = 0.1 # junction radius between the convergent and divergent at
# the throat section. Used in the conical nozzle.
R0 = 0 # junction radius between the combustion chamber and the convergent
theta_c = 40 # half cone angle of the convergent section
theta_N = 15 # half cone angle of the divergent section
# fractional lengths. Used to construct TOP nozzles.
K = [0.6, 0.7, 0.8, 0.9, 1]
Here I create a nozzles list for convenience. The different nozzles will be appended to this list. Note that I also specify the geometry type to be axisymmetric.
[4]:
geom_type = "axisymmetric"
nozzles = []
nozzles.append(CD_Conical_Nozzle(Ri, Re, Rt, Rj, R0, theta_c=theta_c, theta_N=theta_N, geometry_type=geom_type))
for k in K:
nozzles.append(CD_TOP_Nozzle(Ri, Rt, R0, theta_c, k, geometry_type=geom_type))
I can print the nozzle object to get a textual description. We can notice that the areas have been computed using the circular area formula. I can access the different values with the methods seen above.
[5]:
print(nozzles[0])
C-D Conical Nozzle
Radius:
Ri 0.4
Re 1.2
Rt 0.2
Areas:
Ai 0.5026548245743669
Ae 4.523893421169302
At 0.12566370614359174
Lengths:
Lc 0.27474774194546225
Ld 3.7452160573276165
L 4.019963799273079
Angles:
theta_c 40
theta_N 15
Here I plot the different nozzles for comparison.
[6]:
plt.figure()
for i, g in enumerate(nozzles):
lbl = "Conical"
if i != 0:
lbl = "TOP: K = {}".format(K[i-1])
x, y = g.build_geometry()
plt.plot(x, y, label=lbl)
plt.legend()
plt.xlabel("Length")
plt.ylabel("Radius")
plt.title("Axisymmetric")
plt.minorticks_on()
plt.grid(which='major', linestyle='-', alpha=0.7)
plt.grid(which='minor', linestyle=':', alpha=0.5)
plt.axis('equal')
plt.show()
The difference in the convergent’s length between conical and TOP nozzles is due to the different throat junction radius. Rao’s TOP nozzle uses a prescribed radius, whereas in the conical nozzle we can specify the radius we’d like.
From this picture we can also appreciate the Fractional Length of the nozzle with respect to a same exit area ratio conical nozzle with 15 deg half-cone angle.
Planar Nozzles
With planar nozzles the width is constant along the length of the nozzle. In this case, the radius corresponds to half height of the cross section (the distance from the line of symmetry of the planar nozzle, to the wall).
[7]:
geom_type = "planar"
conical = CD_Conical_Nozzle(Ri, Re, Rt, Rj, R0, theta_c=theta_c, theta_N=theta_N, geometry_type=geom_type)
# fractional length of the TOP nozzle
K = 0.7
top = CD_TOP_Nozzle(Ri, Rt, R0, theta_c, 0.7, geometry_type=geom_type)
print(top)
C-D TOP Nozzle
Radius:
Ri 0.4
Re 1.2000000000000002
Rt 0.2
Areas:
Ai 0.8
Ae 2.4000000000000004
At 0.4
Lengths:
Lc 0.3475417887987028
Ld 2.619476340869189
L 2.967018129667892
Angles:
theta_c 40
theta_N 29.526881404482012
theta_e 14.248957413040683
For the CD_Min_Length_Nozzle we also need to specify the specific heats ratio of the gas and the number of characteristics lines to use.
[8]:
# number of characteristics
n = 15
# specific heats ratio
gamma = 1.4
moc = CD_Min_Length_Nozzle(Ri, Re, Rt, Rj, R0, theta_c, n, gamma)
[9]:
x1, y1 = conical.build_geometry()
x2, y2 = top.build_geometry()
x3, y3 = moc.build_geometry()
plt.figure()
plt.plot(x1, y1, label="conical")
plt.plot(x2, y2, label="TOP: K = {}".format(top.fractional_length))
plt.plot(x3, y3, label="MOC")
plt.legend()
plt.xlabel("Length")
plt.ylabel("Half Height")
plt.title("Planar")
plt.minorticks_on()
plt.grid(which='major', linestyle='-', alpha=0.7)
plt.grid(which='minor', linestyle=':', alpha=0.5)
plt.axis('equal')
plt.show()
[ ]: