Example 13 from RP-1311ΒΆ
Note
The python script for this example is available in the source/bind/python/cea/samples directory of the CEA repository.
Here we describe how to run example 13 from RP-1311 [1] using the Python API.
This is a rocket problem assuming an infinite-area combustor (IAC), using N2H4(L), Be(a), and H2O2(L) as reactants. This problem demonstrates how to call the insert parameter for a rocket problem, adding BeO(L) to the initial guess for the equilibrium evaluation. The resulting equilibrium mixtures also include non-negligible amounts of condensed species.
First import the required libraries:
import numpy as np
import cea
Use cea.units for unit conversions and cea.R inline when normalizing enthalpy.
Declare the reactants and set their amounts and initial temperatures. Currently, the Python API requires species names to be in bytes format, so we use the b"" syntax to create byte strings. The initial reactant temperatures, reac_T, will be used later to compute the chamber enthalpy. The amounts of each are specified through the fuel_weights, oxidant_weights, and pct_fuel variables specified here. Setting the fuel_weights array equal to [0.8, 0.2, 0.0] means that N2H4(L) constitutes 80% of the fuel, and Be(a) makes up the other 20% of the fuel mixture by weight. Similarly, setting the oxidant_weights array equal to [0.0, 0.0, 1.0] means that H2O2(L) constitutes 100% of the oxidant. These values will be used in conjunction later with pct_weight to compute the overall weight fraction array of the reactant mixture.
reac_names = [b"N2H4(L)", b"Be(a)", b"H2O2(L)"]
fuel_weights = np.array([0.8, 0.2, 0.0])
oxidant_weights = np.array([0.0, 0.0, 1.0])
reac_T = np.array([298.15, 298.15, 298.15]) # Reactant temperatures (K)
pct_fuel = 67.0
Next we set a variable for our trace parameter, defining the threshold below which species concentrations are assumed to be 0.
trace = 1e-10
Next, set some states for the rocket analysis. We will pass these values into the RocketSolver later.
pc = cea.units.psi_to_bar(3000) # Chamber pressure (bar)
pi_p = [3.0, 10.0, 30.0, 300.0] # Pressure ratio
Now we will instantiate the reactant and product Mixture objects.
To create the product Mixture, we pass the list of reactant names along with the flag products_from_reactants=True, which will return the full set of possible product species.
We will also create the list of insert species that we will pass into the RocketSolver next.
reac = cea.Mixture(reac_names)
prod = cea.Mixture(reac_names, products_from_reactants=True)
insert = [b"BeO(L)"]
Now initialize the RocketSolver and RocketSolution class instances.
We pass in the optional arguments insert and trace to the RocketSolver class initialization.
solver = cea.RocketSolver(prod, reactants=reac, trace=trace, insert=insert)
solution = cea.RocketSolution(solver)
Compute the array of weight fractions for the reactant mixture:
of_ratio = (100.0 - pct_fuel) / pct_fuel
weights = reac.of_ratio_to_weights(oxidant_weights, fuel_weights, of_ratio)
Compute the chamber enthalpy value based on the reactants weights and temperatures. We will pass this in later when we call solve().
Note that this value is normalized by R here.
hc = reac.calc_property(cea.ENTHALPY, weights, reac_T)/cea.R
Now we can solve the solve() function:
solver.solve(solution, weights, pc, pi_p, iac=True, hc=hc)
Finally, querry the solution variables and print them out:
num_pts = solution.num_pts
T = solution.T
P = cea.units.bar_to_atm(solution.P)
rho = 1e-3*solution.density
enthalpy = cea.units.joule_to_cal(solution.enthalpy)
energy = cea.units.joule_to_cal(solution.energy)
gibbs = cea.units.joule_to_cal(solution.gibbs_energy)
entropy = cea.units.joule_to_cal(solution.entropy)
n = solution.n
M_1n = solution.M
MW = solution.MW
cp_eq = cea.units.joule_to_cal(solution.cp_eq)
Mach = solution.Mach
gamma_s = solution.gamma_s
v_sonic = solution.sonic_velocity
ae_at = solution.ae_at
c_star = cea.units.m_per_s_to_ft_per_s(solution.c_star)
Cf = solution.coefficient_of_thrust
Isp = solution.Isp/9.80665
Isp_vac = solution.Isp_vacuum/9.80665
print("P, atm ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3f}".format(P[i]), end=" ")
else:
print("{0:10.3f}".format(P[i]))
print("T, K ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3f}".format(T[i]), end=" ")
else:
print("{0:10.3f}".format(T[i]))
print("Density, g/cm^3", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3g}".format(rho[i]), end=" ")
else:
print("{0:10.3g}".format(rho[i]))
print("H, cal/g ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.2f}".format(enthalpy[i]), end=" ")
else:
print("{0:10.2f}".format(enthalpy[i]))
print("U, cal/g ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.2f}".format(energy[i]), end=" ")
else:
print("{0:10.2f}".format(energy[i]))
print("G, cal/g ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.1f}".format(gibbs[i]), end=" ")
else:
print("{0:10.1f}".format(gibbs[i]))
print("S, cal/g-K ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3f}".format(entropy[i]), end=" ")
else:
print("{0:10.3f}".format(entropy[i]))
print("M, (1/n) ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3f}".format(M_1n[i]), end=" ")
else:
print("{0:10.3f}".format(M_1n[i]))
print("MW ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3f}".format(MW[i]), end=" ")
else:
print("{0:10.3f}".format(MW[i]))
print("Cp, cal/g-K ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3f}".format(cp_eq[i]), end=" ")
else:
print("{0:10.3f}".format(cp_eq[i]))
print("Gamma_s ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.4f}".format(gamma_s[i]), end=" ")
else:
print("{0:10.4f}".format(gamma_s[i]))
print("Son. vel., m/s ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.2f}".format(v_sonic[i]), end=" ")
else:
print("{0:10.2f}".format(v_sonic[i]))
print("Mach ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3f}".format(Mach[i]), end=" ")
else:
print("{0:10.3f}".format(Mach[i]))
print("")
print("PERFORMANCE PARAMETERS")
print("")
print("Ae/At ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.4f}".format(ae_at[i]), end=" ")
else:
print("{0:10.4f}".format(ae_at[i]))
print("C*, ft/s ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.2f}".format(c_star[i]), end=" ")
else:
print("{0:10.2f}".format(c_star[i]))
print("Cf ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.4f}".format(Cf[i]), end=" ")
else:
print("{0:10.4f}".format(Cf[i]))
print("Ivac, lb-s/lb ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3f}".format(Isp_vac[i]), end=" ")
else:
print("{0:10.3f}".format(Isp_vac[i]))
print("Isp, lb-s/lb ", end=" ")
for i in range(num_pts):
if i < num_pts-1:
print("{0:10.3f}".format(Isp[i]), end=" ")
else:
print("{0:10.3f}".format(Isp[i]))
print()
print("MOLE FRACTIONS")
print("")
trace_species = []
for prod in solution.mole_fractions:
if np.any(solution.mole_fractions[prod] > trace):
print("{0:15s}".format(prod), end=" ")
for j in range(len(solution.mole_fractions[prod])):
if j < len(solution.mole_fractions[prod])-1:
print("{0:10.5g}".format(solution.mole_fractions[prod][j]), end=" ")
else:
print("{0:10.5g}".format(solution.mole_fractions[prod][j]))
else:
trace_species.append(prod)
print()
print("TRACE SPECIES:")
max_cols = 8
nrows = (len(trace_species) + max_cols - 1) // max_cols
for i in range(nrows):
print(" ".join("{0:15s}".format(trace_species[j]) for j in range(i * max_cols, min((i + 1) * max_cols, len(trace_species)))))
This results in the following output to the terminal:
P, atm 204.138 125.281 68.046 20.414 6.805 0.680
T, K 3002.540 2851.000 2851.000 2449.698 2068.730 1398.106
Density, g/cm^3 0.0138 0.00891 0.00483 0.00169 0.000669 9.91e-05
H, cal/g -234.01 -403.87 -611.80 -995.93 -1291.19 -1761.87
U, cal/g -592.87 -744.29 -952.71 -1287.95 -1537.45 -1928.24
G, cal/g -10072.6 -9745.9 -9953.9 -9023.0 -8069.9 -6343.1
S, cal/g-K 3.277 3.277 3.277 3.277 3.277 3.277
M, (1/n) 16.627 16.643 16.619 16.670 16.694 16.700
MW 13.431 13.420 13.405 13.378 13.377 13.378
Cp, cal/g-K 0.974 0.000 0.000 0.813 0.747 0.665
Gamma_s 1.1515 0.9979 0.9974 1.1791 1.1916 1.2180
Son. vel., m/s 1314.87 1192.19 1192.73 1200.25 1108.03 920.76
Mach 0.000 1.000 1.491 2.104 2.684 3.883
PERFORMANCE PARAMETERS
Ae/At 0.0000 1.0000 1.2363 2.4856 5.3385 30.0004
C*, ft/s 6386.75 6386.75 6386.75 6386.75 6386.75 6386.75
Cf 0.0000 0.6124 0.9133 1.2971 1.5279 1.8368
Ivac, lb-s/lb 0.000 243.396 263.111 306.823 338.619 384.464
Isp, lb-s/lb 0.000 121.571 181.306 257.481 303.294 364.613
MOLE FRACTIONS
Be 8.5544e-06 4.1033e-06 7.5534e-06 2.5505e-07 1.9172e-09 1.4393e-16
Be(OH)2 0.0072678 0.0057344 0.0057215 0.0014065 0.00020281 4.5262e-07
Be2O 1.1221e-06 4.0985e-07 7.5446e-07 5.5565e-09 5.3694e-12 5.606e-22
Be2O2 1.8492e-07 9.0835e-08 1.6729e-07 3.1776e-09 9.8507e-12 3.6727e-20
Be3O3 3.2166e-06 1.9697e-06 3.6277e-06 7.568e-08 2.5733e-10 1.1253e-18
Be4O4 9.2887e-07 7.4489e-07 1.3719e-06 3.683e-08 1.6849e-10 1.5897e-18
BeH 1.3243e-06 4.8345e-07 6.5487e-07 1.1009e-08 4.1984e-11 6.6186e-19
BeH2 7.0102e-06 2.8949e-06 2.8856e-06 8.8386e-08 9.5162e-10 6.8426e-16
BeN 4.3183e-08 1.3137e-08 1.7812e-08 1.6559e-10 2.9079e-13 4.1644e-22
BeO 4.359e-07 1.8631e-07 3.4313e-07 8.1179e-09 3.7299e-11 6.566e-19
BeOH 0.00022402 0.00012482 0.00016916 1.1082e-05 2.335e-07 7.1452e-13
H 0.007146 0.0055921 0.0075786 0.0028413 0.00062797 3.6751e-06
H2 0.51468 0.51518 0.51377 0.51519 0.51626 0.51664
H2O 0.053371 0.054925 0.054802 0.059185 0.060446 0.060664
H2O2 4.3791e-09 2.1323e-09 2.1285e-09 2.004e-10 7.8656e-12 3.4764e-16
HNO 8.6849e-08 4.1263e-08 4.1208e-08 3.7031e-09 1.5209e-10 8.6972e-15
HNO2 1.9242e-10 8.0962e-11 8.0894e-11 4.7618e-12 1.0221e-13 7.4123e-19
HO2 2.0568e-09 9.3034e-10 1.2621e-09 7.7342e-11 1.3662e-12 2.9585e-18
N 4.1872e-07 1.9115e-07 2.593e-07 1.691e-08 3.7932e-10 1.8929e-15
N2 0.22449 0.22435 0.22415 0.22374 0.22373 0.22376
N2H2 7.2231e-09 2.7375e-09 1.481e-09 9.5737e-11 4.5049e-12 1.3131e-15
N2O 7.9158e-09 3.8882e-09 3.8866e-09 3.857e-10 1.7835e-11 1.4552e-15
N3H 1.411e-10 4.5333e-11 2.4548e-11 9.1327e-13 2.0287e-14 5.2666e-19
NH 2.3329e-06 1.0891e-06 1.0871e-06 9.1901e-08 3.6387e-09 1.7282e-13
NH2 1.8652e-05 9.8459e-06 7.2321e-06 1.105e-06 1.2065e-07 2.2644e-10
NH2OH 2.6057e-09 1.0468e-09 5.6608e-10 4.32e-11 2.3068e-12 9.2313e-16
NH3 0.0003067 0.00021088 0.00011398 4.9816e-05 2.7364e-05 1.3079e-05
NO 1.6315e-05 1.0305e-05 1.3985e-05 2.5602e-06 2.032e-07 4.6237e-11
O 2.0862e-06 1.1814e-06 2.1769e-06 2.3209e-07 7.2162e-09 5.494e-14
O2 8.5536e-08 5.0299e-08 9.2727e-08 1.098e-08 3.6115e-10 3.0766e-15
OH 0.0002671 0.00019071 0.00025858 7.0365e-05 9.3363e-06 1.0156e-08
BeO(L) 0.19218 0.17345 0.031752 0 0 0
BeO(a) 0 0 0 0 0.19869 0.19892
BeO(b) 0 0.020211 0.16164 0.1975 0 0
TRACE SPECIES:
Be2 HNO3 N2H4 N2O3 N2O4 N2O5 N3 NH2NO2
NO2 NO3 O3 Be(L) Be(OH)2(b) Be(a) Be(b) Be3N2(L)
Be3N2(a) Be3N2(b) H2O(L) H2O(cr)