The loadable library is accessible from Python and Ruby. It provides access to functions for the thermochemical gas model and, built on top of that, simple state-to-state and stream-tube flow analysis functions.

This is the reference manual for the Python flavour of the library and, because of the history of development, the library comes in the eilmer package. For example, to use the to set up a gas model and do a normal shock calculation from within your Python script, you might try the following:

from eilmer.gas import GasModel, GasState, GasFlow

gmodel = GasModel('cea-air5species-gas-model.lua')
state1 = GasState(gmodel)
state1.p = 80.0e3 # Pa
state1.T = 300.0 # K
state1.update_thermo_from_pT()
state1.update_sound_speed()
print("# Initial test gas:")
print("#   state1: %s" % state1)

print("# Normal shock, given shock speed")
vs = 2890.0
print("#   vs=%g" % vs)
state2 = GasState(gmodel)
flow = GasFlow(gmodel)
v2, vg = flow.normal_shock(state1, vs, state2)
print("#   v2=%g vg=%g" % (v2, vg))
print("#   state2: %s" % state2)

If you have not yet read the Gas Models User Guide, this is a good time to do so.

1. Installing the library

The gas models library for Python3 is part of a larger gas-dynamics toolkit and general getting started notes can be found at http://cfcfd.mechmining.uq.edu.au/docs/getting-started There, you will see how to get a copy of the source code, and a list of what other software you will need to build and install the tool kit, and a collection of environment variables that need to be set.

To install the library, move to the gas source directory and use the make utility.

cd dgd/src/gas
make install

Note that the loadable library needs to be built with the DMD64 compiler and that you need the Foreign-Function-Interface extensions for your Python and Ruby interpreters. On a LinuxMint system this package is python-cffi.

So that the Python interpreter can find the installed library, set your environment variables with something like:

export DGD=$HOME/dgdinst
export PYTHONPATH=${PYTHONPATH}:${DGD}/lib
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${DGD}/lib

2. Gas model and state objects

A number of gas models are encoded in D-language modules and are available via a generic interface.

2.1. GasModel

gmodel = GasModel(file_name)
file_name

string, no default
Specifies the name of the detailed gas model configuration file. This is a Lua format file, constructed as described in the Gas Models User Guide.

2.1.1. Properties

gmodel.id

The index to the underlying D-language gas model that is initialized during construction of the Python GasModel object.

gmodel.n_species

Is the number of chemical species in the gas model.

gmodel.species_names

Is the list of the chemical species names in the gas model. It is a list of strings. The indices of the particular species may be useful for some of the method calls below.

gmodel.n_modes

Is the number of internal energy modes (separate to the thermal internal energy) in the gas model.

gmodel.mol_masses

Is a list of molecular masses in units of kg/m^3.

2.1.2. Methods

gmodel.update_thermo_from_pT(gstate)

Given a GasState object, and assuming that its pressure, temperature and mass fractions are set, compute the other thermodynamic properties of the gas state. Returns None.

gmodel.update_thermo_from_rhou(gstate)

Given a GasState object, and assuming that its density, internal energy and mass fractions are set, compute the other thermodynamic properties of the gas state. Returns None.

gmodel.update_thermo_from_rhoT(gstate)

Given a GasState object, and assuming that its density, temperature and mass fractions are set, compute the other thermodynamic properties of the gas state. Returns None.

gmodel.update_thermo_from_rhop(gstate)

Given a GasState object, and assuming that its density, pressure and mass fractions are set, compute the other thermodynamic properties of the gas state. Returns None.

gmodel.update_thermo_from_ps(gstate, s)

Given a GasState object and a value of entropy, and assuming that gas state pressure and mass fractions are set, compute the other thermodynamic properties of the gas state. The units of entropy, s, are J/kg.K. Returns None.

gmodel.update_thermo_from_hs(gstate, h, s)

Given a GasState object and values of enthalpy and entropy, and assuming that gas state mass fractions are set, compute the other thermodynamic properties of the gas state. The units of enthalpy, h, are J/kg and the units of entropy, s, are J/kg.K. Returns None.

gmodel.update_sound_speed(gstate)

The underlying D-language gas model has the sound-speed calculation separate to the other calculations for other thermodynamic properties. This function reflects that separation, hovever, the other Python methods mentiond above actually do update the sound-speed along with the other thermodynamic properties of the gas state. Returns None.

gmodel.update_trans_coeffs(gstate)

Update the transport coefficients of viscosity and thermal conductivity. Returns None.

gmodel.Cv(gstate)

Returns the specific heat capacity for a constant volume process, J/kg.K.

gmodel.Cp(gstate)

Returns the specific heat capacity for a constant pressure process, J/kg.K.

gmodel.dpdrho_const_T(gstate)

Returns the derivative. Equivalent to RT for a thermally perfect gas.

gmodel.R(gstate)

Returns the gas constant for the gas state. Units are J/kg.K.

gmodel.gamma(gstate)

Returns the ratio of specific heats for the gas state. Nondimensional.

gmodel.Prandtl(gstate)

Returns the ratio of momentum diffusivity to thermal diffusivity. Nondimensional.

gmodel.internal_energy(gstate)

Returns the full internal energy of the gas state. This is the sum of thermal internal energy and any other internal energy modes of the gas model. Units are J/kg.

gmodel.enthalpy(gstate)

Returns the specific enthalpy of the gas state, in J/kg.

gmodel.entropy(gstate)

Returns the specific entropy of the gas state, in J/kg.K.

gmodel.molecular_mass(gstate)

Returns the molecular mass of the gas state, in kg/m^3. This is most useful for chemically-reacting gases where the value will change with mixture fractions of the species.

gmodel.enthalpy_isp(gstate, isp)

Returns the specific enthalpy for a particular chemical species, at index isp, of the gas state. Units are J/kg.

gmodel.entropy_isp(gstate, isp)

Returns the specific entropy for a particular chemical species, at index isp, of the gas state. Units are J/kg.K.

gmodel.gibbs_free_energy_isp(gstate, isp)

Returns the Gibbs Free Energy value for a particular chemical species, at index isp, of the gas state. Units are J/kg.

gmodel.massf2molef(massf)

Given the mass fractions of a gas mixture, returns the list of equivalent mole fractions. The mass-fraction values may be supplied in a dictionary.

gmodel.molef2massf(molef)

Given the mole fractions of a gas mixture, returns the list of equivalent mass fractions. The mole-fraction values may be supplied in a dictionary.

2.2. GasState

Any number of gas state onjects may be constructed in the context of a gas model.

gstate = GasState(gmodel)

The gas state object retains a reference to the gas model used in its construction.

2.2.1. Properties

gstate.id

The index to the underlying D-language gas state that is initialized during the construction of the Python GasState object.

gstate.rho

Gas density, in kg/m^3. This property may be used in an expression or a new value may be assigned.

gstate.p

Gas pressure, in Pa. This property may be used in an expression or a new value may be assigned.

gstate.T

Gas temperature, in K. This property may be used in an expression or a new value may be assigned.

gstate.u

Thermal internal energy, in J/kg. This property may be used in an expression or a new value may be assigned.

gstate.a

Sound speed, m/s. This property is read-only.

gstate.k

Thermal conductivity, in W/m.K. This property is read-only.

gstate.mu

Dynamic viscosity, Pa.s. This property is read-only.

gstate.massf

Is a list of the mass fractions of the chemical species. It may be assigned a list with all of the species mass fraction values in order. It may also be assigned a dictionary, with named entries. In the dictionary form, you need provide only the non-zero values. In any case, the mass fractions should sum to 1.0.

gstate.massf_as_dict

Is a dictionary of named mass-fraction values. It is a read-only property. You may, however, assign to the massf property.

gstate.molef

Is a list of the mole fractions of the chemical species. It may be assigned a list with all of the species mass fraction values in order. It may also be assigned a dictionary, with named entries. In the dictionary form, you need provide only the non-zero values. In any case, the mole fractions should sum to 1.0.

gstate.molef_as_dict

Is a dictionary of named mole-fraction values. It is a read-only property. You may, however, assign to the molef property.

gstate.conc

Is a list of the concentrations, in mole/m^3, of the chemical species. It is a read-only property.

gstate.conc_as_dict

Is a dictionary of named concentration values. It is a read-only property.

gstate.u_modes

Is a list of internal-energy values for a multi-temperature gas. Units are J/kg. When assigning a list, the full list must be supplied.

gstate.T_modes

Is a list of temperature values, in K, for a multi-temperature gas. When assigning a list, the full list must be supplied.

gstate.k_modes

Is a list of thermal diffusivity coefficient values, in W/m.K, for a multi-temperature gas. It is a read-only property.

gstate.ceaSavedData

Is a dictionary of the data saved from the call out to the CEA2 program that was made when updating the thermodynamic properties for the gas state of the equilibrium mixture. This property is specific to the CEAgas model. If it exists, it contains the entries:

"p"

static pressure, Pa

"rho"

density, kg/m^3

"u"

specific internal energy, J/kg

"h"

specific enthalpy, J/kg

"T"

temperature, K

"a"

sound speed, m/s

"Mmass"

average molecular mass of the equilibrium mixture, kg/mole

"Rgas"

effective gas constant, J/kg/K

"gamma"

effective ratio of specific heats

"Cp"

effective specific heat, constant pressure, J/kg

"s"

specific entropy, J/kg.K

"mu"

effective viscosity coefficient, Pa.s

"mass"

dictionary of mass-fraction values for the species in the equilibrium mixture.

2.2.2. Methods

gstate.copy_values(other_gstate)

Copy property values from the other_gstate object. It is assumed that the GasModel is the same for east of the GasState objects.

gstate.update_thermo_from_pT()

Assuming that its pressure, temperature and mass fractions are set, compute the other thermodynamic properties of the gas state. Returns None.

gstate.update_thermo_from_rhou()

Assuming that its density, internal energy and mass fractions are set, compute the other thermodynamic properties of the gas state. Returns None.

gstate.update_thermo_from_rhoT()

Assuming that its density, temperature and mass fractions are set, compute the other thermodynamic properties of the gas state. Returns None.

gstate.update_thermo_from_rhop()

Assuming that its density, pressure and mass fractions are set, compute the other thermodynamic properties of the gas state. Returns None.

gstate.update_thermo_from_ps(s)

Given a value of entropy, and assuming that gas state pressure and mass fractions are set, compute the other thermodynamic properties of the gas state. The units of entropy, s, are J/kg.K. Returns None.

gstate.update_thermo_from_hs(h, s)

Given values of enthalpy and entropy, and assuming that gas state mass fractions are set, compute the other thermodynamic properties of the gas state. The units of enthalpy, h, are J/kg and the units of entropy, s, are J/kg.K. Returns None.

gstate.update_sound_speed()

The underlying D-language gas model has the sound-speed calculation separate to the other calculations for other thermodynamic properties. This function reflects that separation, hovever, the other Python methods mentiond above actually do update the sound-speed along with the other thermodynamic properties of the gas state. Returns None.

gstate.update_trans_coeffs()

Update the transport coefficients of viscosity and thermal conductivity. Returns None.

2.2.3. Other properties

gstate.Cv

Returns the specific heat capacity for a constant volume process, J/kg.K.

gstate.Cp

Returns the specific heat capacity for a constant pressure process, J/kg.K.

gstate.dpdrho_const_T

Returns the derivative. Equivalent to RT for a thermally perfect gas.

gstate.R

Returns the gas constant for the gas state. Units are J/kg.K.

gstate.gamma

Returns the ratio of specific heats for the gas state. Nondimensional.

gmodel.Prandtl(gstate)

Returns the ratio of momentum diffusivity to thermal diffusivity. Nondimensional.

gstate.internal_energy

Returns the full internal energy of the gas state. This is the sum of thermal internal energy and any other internal energy modes of the gas model. Units are J/kg.

gstate.enthalpy

Returns the specific enthalpy of the gas state, in J/kg.

gstate.entropy

Returns the specific entropy of the gas state, in J/kg.K.

gstate.molecular_mass

Returns the molecular mass of the gas state, in kg/m^3. This is most useful for chemically-reacting gases where the value will change with mixture fractions of the species.

gstate.enthalpy_isp(isp)

Returns the specific enthalpy for a particular chemical species, at index isp, of the gas state. Units are J/kg.

gstate.entropy_isp(isp)

Returns the specific entropy for a particular chemical species, at index isp, of the gas state. Units are J/kg.K.

gstate.gibbs_free_energy_isp(isp)

Returns the Gibbs Free Energy value for a particular chemical species, at index isp, of the gas state. Units are J/kg.

3. Thermochemical kinetics

If you have a gas model with several chemical species and/or with more than one temperature you may be interested in allowing the thermochamical processes to change the gas state in an otherwise isolated blob of gas.

Before trying the following functions, you should read the Reacting Gas Guide.

3.1. ThermochemicalReactor objects

reactor = ThermochemicalReactor(gmodel, filename1, filename2="")
gmodel

GasModel object, no default
is a reference to a suitable gas model. Not all gas models will have associated reactors but some, such as the ThermallyPerfectGas model do.

filename1

string, no default.
File name for the detailed chemistry configuration file.

filename2

string, default: ""
File name for the second detailed thermochemical configuration file. Only a few files will require a second configuration file.

3.2. Methods

To update the gas state over a finite interval of time, call

reactor.update_state(gstate, t_interval, dt_suggest)
gstate

GasState object, no default.
The gas state which will be altered. Because the hypothetical reactor is isolated, the density and internal energy of the blob of gas will remain fixed, while other thermochemical properties, including mass- and mole-fractions change.

t_interval

Float, no default.
The time interval, in seconds, over which to evolve the gas state.

dt_suggest

Float, default -1.0
The suggested time step size for the thermochemical update. The default value of -1.0 indicates to the reactor that we have no godd idea and that it should select something suitable.

Returns the last successful time-step size, so that the value may be used in subsequent calls.

4. State-to-state flow processes

For processes involving the general gas models, flow analysis functions are collected as methods of the GasFlow class. An object of this class needs to be constructed in the context of a particular gas model.

flow = GasFlow(gmodel)

4.1. Normal shock

For shock processing when we want to restrict the processing to the ideal-gas behaviour, use the following function.

v2, vg = flow.ideal_shock(state1, vs, state2)

Input:

state1

GasState object, no default.
The initial gas state, before passing through the shock.

vs

Float, no default.
Speed of gas, in m/s, coming into the shock (in a shock stationary frame), or the speed of the shock into quiescent gas (lab frame).

state2

GasState object, no default.
The state of the gas after shock processing. Although you might expect state2 as output, you need to construct it first and pass it into the function to have its values mutated.

The function returns a tuple of velocities.

v2

Float The post-shock gas speed, in m/s, relative to the shock front.

vg

Float The post-shock gas speed, in m/s, in the lab frame, for the case where the shock in moving into a quiescent gas.

For shock processing with more general, but still chemically-frozen, gas behaviour, use the following function.

v2, vg = flow.normal_shock(state1, vs, state2)

Input:

state1

GasState object, no default.
The initial gas state, before passing through the shock.

vs

Float, no default.
Speed of gas, in m/s, coming into the shock (in a shock stationary frame), or the speed of the shock into quiescent gas (lab frame).

state2

GasState object, no default.
The state of the gas after shock processing. Although you might expect state2 as output, you need to construct it first and pass it into the function to have its values mutated.

The function returns a tuple of velocities.

v2

Float The post-shock gas speed, in m/s, relative to the shock front.

vg

Float The post-shock gas speed, in m/s, in the lab frame, for the case where the shock in moving into a quiescent gas.

For the case where the pressure ratio is provided, use the function:

v2, vg = flow.normal_shock_p2p1(state1, p2p1, state2)

Input:

state1

GasState object, no default.
The initial gas state, before passing through the shock.

p2p1

Float, no default.
Ratio of pressures p2/p1 across the shock.

state2

GasState object, no default.
The state of the gas after shock processing. Although you might expect state2 as output, you need to construct it first and pass it into the function to have its values mutated.

The function returns a tuple of velocities.

v2

Float The post-shock gas speed, in m/s, relative to the shock front.

vg

Float The post-shock gas speed, in m/s, in the lab frame, for the case where the shock in moving into a quiescent gas.

For a reflected shock, as would be observed in a shock tunnel, we have the function:

vr = flow.reflected_shock(state2, vg, state5)

Input:

state1

GasState object, no default.
The state of the gas approaching the reflected-shock front.

vg

Float The speed of the incoming gas (in m/s) in the lab frame.

state5

GasState object, no default.
The state of the gas after reflected-shock processing. Although you might expect state5 as output, you need to construct it first and pass it into the function to have its values mutated.

The function returns vr, the speed of the reflected shock (in m/s) in the lab frame.

4.2. Reversible steady flow

Allow a gas to expand through a steady isentropic process, from stagnation to a lower pressure.

v = flow.expand_from_stagnation(state0, p_over_p0, state1)

Input:

state0

GasState object, no default.
The initial stagnation state.

p_over_p0

Float, no default.
The pressure of the expanded gas divided by the stagnation pressure.

state1

GasState object, no default.
The state of the gas after expansion. Although you might expect state1 as output, you need to construct it first and pass it into the function to have its values mutated.

The function returns v. the velocity (in m/s) of the expanded gas.

Allow a gas to expand through a steady isentropic process, from stagnation to a particular Mach number.

v = flow.expand_to_mach(state0, mach, state1)

Input:

state0

GasState object, no default.
The initial stagnation state.

mach

Float, no default.
The Mach number of the expanded gas.

state1

GasState object, no default.
The state of the gas after expansion. Although you might expect state1 as output, you need to construct it first and pass it into the function to have its values mutated.

The function returns v. the velocity (in m/s) of the expanded gas.

Given a free-stream, compute the corresponding stagnation condition.

flow.total_condition(state1, v1, state0)

Input:

state1

GasState object, no default.
The free-stream state.

v1

Float, no default.
The velocity (in m/s) of the free stream.

state0

GasState object, no default.
The stagnation state, following an isentropic compression from the free-stream state. Although you might expect state0 as output, you need to construct it first and pass it into the function to have its values mutated.

4.3. Pitot probe flow

Compute the state of gas at the stagnation point on a Pitot probe. For a subsonic free-stream flow, this will be the same as for an isentropic compression. For a supersonic flow, there will be a normal shock, followed by an isentropic compression.

flow.pitot_condition(state1, v1, state2pitot)

Input:

state1

GasState object, no default.
The free-stream state.

v1

Float, no default.
The velocity (in m/s) of the free stream.

state2pitot

GasState object, no default.
The stagnation state at the probe tip, after compression from the free-stream state. Although you might expect state2pitot as output, you need to construct it first and pass it into the function to have its values mutated.

4.4. Steady flow in a duct

Steady, isentropic flow through a variable-area duct. Internally, this function iterates guesses for the pressure ratio, in order to keep mass-flux equal.

v2 = flow.steady_flow_with_area_change(state1, v1, area2_over_area1, state2,
                                       tol=1.0e-4)

Input:

state1

GasState object, no default.
The state at point 1 in the duct.

v1

Float, no default.
The velocity (in m/s) at point 1.

area2_over_area1

Float, no default.
The ratio of areas of the two points.

state2

GasState object, no default.
The gas state at point 2. Although you might expect state2 as output, you need to construct it first and pass it into the function to have its values mutated.

tol

Float, default 1.0e-4
Tolerance on the mass-flux error.

4.5. Unsteady reversible flow

For compression and expansion processes that travel as a wave, the analysis steps along a characteristic trajectory that traverses the wave and integrates the effects numerically.

v2 = flow.finite_wave_dp(state1, v1, characteristic, p2, state2,
                         steps=100)

Input:

state1

GasState object, no default.
The state before wave processing.

v1

Float, no default.
The velocity (in m/s) before wave processing. Positive velocities are to the right.

characteristic

string, no default.
Name of the characteristic trajectory that the integration process follows. Options are "cplus" and "cminus". If the unsteady processing wave is moving left through the gas, the integration follows a "cplus" characteristic trajectory (from the left initial state to the right final state).

p2

Float, no default.
The pressure (in Pa) after wave processing.

state2

GasState object, no default.
The gas state after wave processing. Although you might expect state2 as output, you need to construct it first and pass it into the function to have its values mutated.

steps

Int, default: 100
The pressure change is divided into a number of steps and the effects are integrated numerically.

The function returns v2, the velocity of the gas following wave processing.

For the cases where we know the velocity of the expanded gas, we can take steps in velocity to get to the expanded state.

v2 = flow.finite_wave_dv(state1, v1, characteristic, v2_target, state2,
                         steps=100, t_min=200.0)

Input:

state1

GasState object, no default.
The state before wave processing.

v1

Float, no default.
The velocity (in m/s) before wave processing.

characteristic

string, no default.
Name of the characteristic trajectory that the integration process follows. Options are "cplus" and "cminus". If the unsteady processing wave is moving left through the gas, the integration follows a "cplus" characteristic trajectory (from the left initial state to the right final state).

v2_target

Float, no default.
The expected velocity (in m/s) after wave processing.

state2

GasState object, no default.
The gas state after wave processing. Although you might expect state2 as output, you need to construct it first and pass it into the function to have its values mutated.

steps

Int, default: 100
The velocity change is divided into a number of steps and the effects are integrated numerically.

t_min

Float, default: 200.0
Minimum temperature (in degrees K) of the gas through the expansion. Because we are stepping in velocity, it is easy to demand a final velocity that can exceed the maximum velocity for a physically realizable expansion. A typical symptom of demanding too strong an expansion is a negative temperature for the expanded gas.

The function returns v2, the velocity of the gas following wave processing.

4.6. Riemann problem

The Riemann problem is at the core of our larger-scale CFD codes. Left and Right gas states are allowed to interact at their contact surface. Processing of each initial state is via a left-running wave (into the Left state) and a right-running wave (into the Right state). The results of wave processing are two intermediate states (labelled star) that have a common pressure and velocity at the contact surface. Osher’s approximate Riemann solver assumes that both processing waves are isentropic.

pstar, wstar, wL, wR, velX0 = flow.osher_riemann(stateL, stateR, velL, velR,
                                                 stateLstar, stateRstar, stateX0)

Input:

stateL

GasState object, no default.
The state on the left of the contact surface.

stateR

GasState object, no default.
The state on the right of the contact surface.

velL

Float, no default.
The velocity of the gas (in m/s) in the left initial state.

velR

Float, no default.
The velocity of the gas (in m/s) in the right initial state.

stateLstar

GasState object, no default.
The left intermediate state after wave processing.

stateRstar

GasState object, no default.
The right intermediate state after wave processing.

stateX0

GasState object, no default.
The interpolated state at the initial contact-surface location, after wave processing. As part of a flow simulation code, the details of this state may be used to compute the flux of mass, momentum and energy across the initial constact-surface location.

Although you might expect stateLstar and statRstar as output, you need to construct them first and pass them into the function to have their values mutated.

The function returns:

pstar

Float The common pressure at the contact surface between the intermediate states.

wstar

Float The common velocity at the contact surface between the intermediate states.

wL

Float The leading-edge wave speed of the left-moving wave. If the wave is a compression, this is the shock speed.

wR

Float The leading-edge wave speed of the right-moving wave. If the wave is a compression, this is the shock speed.

velX0

Float The velocity of the gas, interpolated at the initial location of the contact-surface.

4.7. Riemann subproblem for L1d

The Lagrangian flow solver has a specialized Riemann solver at its core.

pstar, wstar = flow.lrivp(stateL, stateR, velL, velR)

Input:

stateL

GasState object, no default.
The state on the left of the contact surface.

stateR

GasState object, no default.
The state on the right of the contact surface.

velL

Float, no default.
The velocity of the gas (in m/s) in the left initial state.

velR

Float, no default.
The velocity of the gas (in m/s) in the right initial state.

The function returns:

pstar

Float The common pressure at the contact surface between the intermediate states.

wstar

Float The common velocity at the contact surface between the intermediate states.

When the gas is up against a solid face of a piston, we have the contact-surface velocity as known and we need to compute just the gas pressure at the contact-surface.

pstar = flow.piston_at_left(stateR, velR, wstar)

Input:

stateR

GasState object, no default.
The state on the right of the contact surface.

velR

Float, no default.
The velocity of the gas (in m/s) in the right initial state.

wstar

Float, no default.
The velocity (in m/s) of the gas at the contact (piston) surface.

The function returns pstar (in Pa), the pressure at the contact surface.

pstar = flow.piston_at_right(stateL, velL, wstar)

Input:

stateL

GasState object, no default.
The state on the left of the contact surface.

velL

Float, no default.
The velocity of the gas (in m/s) in the left initial state.

wstar

Float, no default.
The velocity (in m/s) of the gas at the contact (piston) surface.

The function returns pstar (in Pa), the pressure at the contact surface.

4.8. Oblique shock

Oblique straight shocks are analysed by splitting the velocity into normal and tangential components. The shock angle, with respect to the initial stream direction, is beta. The streamline deflection angle is theta.

Given a shock angle, we can get the flow state after shock processing directly.

theta, v2 = flow.theta_oblique(state1, v1, beta, state2)

Input:

state1

GasState object, no default.
The state before shock wave processing.

v1

Float, no default.
The velocity of the gas (in m/s) before shock wave processing.

beta

Float, no default.
Angle, in radians, of the shock with respect to the initial flow direction.

state2

GasState object, no default.
The gas state after wave processing. Although you might expect state2 as output, you need to construct it first and pass it into the function to have its values mutated.

The function returns theta the stream deflection angle (in radians) and v2, the speed of the gas in that deflected stream.

When you know the deflection angle and you want the shock angle, use the following function.

beta = flow.beta_oblique(state1, v1, theta)

Input:

state1

GasState object, no default.
The state before shock wave processing.

v1

Float, no default.
The velocity of the gas (in m/s) before shock wave processing.

theta

Float, no default.
Deflection angle, in radians, of the streamlines through the shock.

The function returns shock angle beta for the weak shock solution for the given streamline deflection angle. The flow is assumed to remain supersonic following the shock. The strong-shock solution, resulting in subsonic downstream flow, would be sensitive the (unspecified) details of whatever is downstream and supporting the shock.

4.9. Conical shock

For the limits of thermochemically-frozen and thermochemical-equilibrium gases, there is a conical flow analysis for shock waves.

Given the free-stream condition and a conical shock angle, the radial flow conditions can be integrated from just after the shock to the supporting conical body. The axis of the supporting cone is aligned with the free-stream direction.

theta_c, v2_c = flow.theta_cone(state1, v1, beta, state_c)

Input:

state1

GasState object, no default.
The free-stream state, before shock wave processing.

v1

Float, no default.
The velocity of the gas (in m/s) in the free stream, before shock wave processing.

beta

Float, no default.
Angle, in radians, of the conical shock with respect to the initial flow direction.

state_c

GasState object, no default.
The gas state at the cone surface. Although you might expect state_c as output, you need to construct it first and pass it into the function to have its values mutated.

The function returns theta_c the stream deflection angle (in radians) at the cone surface and v2_c, the speed of the gas in that deflected stream up the conical surface.

When you know the deflecting cone angle and you want the shock angle, use the following function.

beta = flow.beta_cone(state1, v1, theta)

Input:

state1

GasState object, no default.
The free-stream state, before shock wave processing.

v1

Float, no default.
The velocity of the gas (in m/s) in the free stream, before shock wave processing.

theta

Float, no default.
Angle, in radians, of the deflecting cone.

The function returns shock angle beta for the weak shock solution. The flow is assumed to remain supersonic following the shock. A subsonic post-shock flow would be associated with a detached shock and the flow field would not match the assumed conical arrangement.

5. State-to-state processes (ideal gas)

If the calorically-perfect ideal gas model is sufficient for your analysis needs, there is simple set of ideal-gas relations collected into the eilmer.ideal_gas package.

The following functions do not use the generalized gas models but assume a gas bahaviour for fixed ratio of specific heats.

To get access to the functions, import the module into your Python script. For example:

import eilmer.ideal_gas_flow as igf
M = 2.0
print("Normal shock jump...")
print("Computed: M=%g: M2=%g, T2/T1=%g, p2/p1=%g, r2/r1=%g" %
      (M, igf.m2_shock(M), igf.T2_T1(M), igf.p2_p1(M), igf.r2_r1(M)))
print("Expected: M1=2, M2=0.5774, T2/T1=1.687, p2/p1=4.50, r2/r1=2.667")

5.1. Isentropic/adiabatic steady flow

igf.A_Astar(M, g=1.4)

Input:

M

Float, no default. Mach number at area A, assuming sonic condition at area Astar

g

Float, default: 1.4
Ratio of specific heats

Returns area ratio, A/Astar, for an isentropic, quasi-one-dimensional flow.

igf.T0_T(M, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns T0/T, the ratio of total temperature over static temperature for adiabatic flow.

igf.p0_p(M, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns p0/p, the ratio of total pressure over static pressure for isentropic flow.

igf.r0_r(M, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns rho0/rho, the ratio of stagnation density over local for isentropic flow.

5.2. Normal shock

igf.m2_shock(M1, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns m2, Mach number following the shock processing.

igf.r2_r1(M1, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns density ratio, r2/r1, across a normal shock.

igf.v2_v1(M1, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns velocity ratio, v2/v1, across a normal shock.

igf.p2_p1(M1, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns static pressure ratio, p2/p1, across a normal shock.

igf.T2_T1(M1, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns static temperature ratio, T2/T1, across a normal shock.

igf.p02_p01(M1, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns stagnation pressure ratio, p02/p01, across a normal shock.

igf.ds_Cv(M1, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns nondimensional entropy change, ds/Cv, across a normal shock.

igf.pitot_p(p1, M1, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns pitot pressure for a specified Mach number free-stream flow. The value will have the same units as input p1.

5.3. Flow with heat addition.

One-dimensional flow with heat addition is also known as Rayleigh-line flow. The flow starts with local Mach number, M, and (hypothetically) enough heat is added for the flow to reach sonic (Mstar=1) condition.

igf.T0_T0star(M, g=1.4)

Input:

M

Float, no default. initial Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns T0/T0star where T0 is the total temperature of the initial flow and T0star is the total temperature that would be achieved if enough heat is added to get to the sonic condition.

igf.M_Rayleigh(T0T0star, g=1.4)

Input:

T0T0star

Float, no default. T0/T0star where T0 is the total temperature of the initial flow and T0star is the total temperature that would be achieved if enough heat is added to get to the sonic condition.

g

Float, default: 1.4
Ratio of specific heats

Returns the initial Mach number, M, of the flow.

igf.T_Tstar(M, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns T/Tstar where T is the static temperature of the initial flow and Tstar is the static temperature that would be achieved if enough heat is added to get to sonic condition.

igf.p_pstar(M, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns p/pstar where p is the static pressure of the initial flow and pstar is the static pressure that would be achieved if enough heat is added to get to sonic conditions.

igf.r_rstar(M, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns density ratio, rho/rhostar, where rho is the density of the initial flow and rhostar is the density that would be achieved if enough heat is added to get to sonic conditions.

igf.p0_p0star(M, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns p0/p0star where p0 is the total pressure of the initial flow and p0star is the total pressure that would be achieved if enough heat is added to get to sonic conditions.

5.4. Supersonic turning

igf.PM1(M, g=1.4)

Input:

M

Float, no default. Mach number.

g

Float, default: 1.4
Ratio of specific heats

Returns Prandtl-Meyer function value, in radians.

igf.PM2(nu, g=1.4)

Input:

nu

Float, no default. Prandtl-Meyer function value, in radians.

g

Float, default: 1.4
Ratio of specific heats

Returns corresponding Mach number.

5.5. Oblique shock

igf.beta_obl(M1, theta, g=1.4, tol=1.0e-6)

Input:

M1

Float, no default. Mach number of gas before the shock.

theta

Float, no default. Steamline deflection angle, in radians.

g

Float, default: 1.4
Ratio of specific heats

Returns shock angle, beta (in radians), with respect to the original stream direction.

igf.beta_obl2(M1, p2_p1, g=1.4)

Input:

M1

Float, no default. Mach number of gas before the shock.

p2_p1

Float, no default.
Static pressure ratio, p2/p1, across the shock.

g

Float, default: 1.4
Ratio of specific heats

Returns shock angle, beta (in radians), with respect to the original stream direction.

igf.theta_obl(M1, beta, g=1.4)

Input:

M1

Float, no default. Mach number of gas before the shock.

beta

Float, no default.
Shock angle, in radians, relative to the original stream direction.

g

Float, default: 1.4
Ratio of specific heats

Returns deflection angle of the stream, theta (in radians).

igf.M2_obl(M1, beta, theta, g=1.4)

Input:

M1

Float, no default. Mach number of gas before the shock.

beta

Float, no default.
Shock angle, in radians, relative to the original stream direction.

theta

Float, no default. Steamline deflection angle, in radians.

g

Float, default: 1.4
Ratio of specific heats

Returns M2, Mach number in flow after the shock.

igf.r2_r1_obl(M1, beta, g=1.4)

Input:

M1

Float, no default. Mach number of gas before the shock.

beta

Float, no default.
Shock angle, in radians, relative to the original stream direction.

g

Float, default: 1.4
Ratio of specific heats

Returns density ratio, rho2/rho1 across an oblique shock.

igf.vn2_vn1_obl(M1, beta, g=1.4)

Input:

M1

Float, no default. Mach number of gas before the shock.

beta

Float, no default.
Shock angle, in radians, relative to the original stream direction.

g

Float, default: 1.4
Ratio of specific heats

Returns normal-velocity ratio, vn1/vn2, across an oblique shock.

igf.v2_v1_obl(M1, beta, g=1.4)

Input:

M1

Float, no default. Mach number of gas before the shock.

beta

Float, no default.
Shock angle, in radians, relative to the original stream direction.

g

Float, default: 1.4
Ratio of specific heats

Returns flow-speed ratio, v2/v1, across an oblique shock.

igf.p2_p1_obl(M1, beta, g=1.4)

Input:

M1

Float, no default. Mach number of gas before the shock.

beta

Float, no default.
Shock angle, in radians, relative to the original stream direction.

g

Float, default: 1.4
Ratio of specific heats

Returns static pressure ratio, p2/p1, across an oblique shock.

igf.T2_T1_obl(M1, beta, g=1.4)

Input:

M1

Float, no default. Mach number of gas before the shock.

beta

Float, no default.
Shock angle, in radians, relative to the original stream direction.

g

Float, default: 1.4
Ratio of specific heats

Returns static temperature ratio, T2/T1, across an oblique shock.

igf.p02_p01_obl(M1, beta, g=1.4)

Input:

M1

Float, no default. Mach number of gas before the shock.

beta

Float, no default.
Shock angle, in radians, relative to the original stream direction.

g

Float, default: 1.4
Ratio of specific heats

Returns ratio of stagnation pressures, p02/p01, across an oblique shock.

5.6. Taylor-Maccoll cone flow

Compute the cone-surface angle and conditions given the shock wave angle. The computation starts with the oblique-shock jump and then integrates across theta until V_theta goes through zero. The cone surface corresponds to V_theta == 0.

igf.theta_cone(V1, p1, T1, beta, R=287.1, g=1.4)

Input:

V1

Float, no default. Speed of gas (in m/s) entering the shock.

p1

Float, no default. Static pressure of gas (in Pa) entering the shock.

T1

Float, no default. Static temperature of gas (in K) entering the shock.

beta

Float, no default.
Shock angle, in radians, relative to the original stream direction.

R

Float, default: 287.1
Gas constant, in J/kg.K

g

Float, default: 1.4
Ratio of specific heats

Returns tuple of (theta_c, V_c, p_c, T_c).

theta_c

stream deflection angle, in radians

V_c

the cone-surface speed of gas, in m/s

p_c

the cone-surface pressure, in Pa

T_c

the cone-surface static temperature, in K

igf.beta_cone(V1, p1, T1, theta, R=287.1, g=1.4)

Input:

V1

Float, no default. Speed of gas (in m/s) entering the shock.

p1

Float, no default. Static pressure of gas (in Pa) entering the shock.

T1

Float, no default. Static temperature of gas (in K) entering the shock.

theta

Float, no default.
Cone deflection angle, in radians.

R

Float, default: 287.1
Gas constant, in J/kg.K

g

Float, default: 1.4
Ratio of specific heats

Returns beta, the shock wave angle (in radians) with respect to the free-stream flow direction.

igf.beta_cone2(M1, theta, R=287.1, g=1.4)

Input:

M1

Float, no default. Mach number of gas entering the shock.

theta

Float, no default.
Cone deflection angle, in radians.

R

Float, default: 287.1
Gas constant, in J/kg.K

g

Float, default: 1.4
Ratio of specific heats

Returns beta, the shock wave angle (in radians) with respect to the free-stream flow direction.