[1D] Deprecate component name 'u' in favor of 'velocity'

This commit is contained in:
Ingmar Schoegl
2020-02-26 16:29:20 -06:00
committed by Ray Speth
parent 856a00bd01
commit eb638254e4
10 changed files with 93 additions and 64 deletions

View File

@@ -31,13 +31,13 @@ f.solve(loglevel=loglevel, auto=True)
# Solve with the energy equation enabled
f.save('h2_adiabatic.xml', 'mix', 'solution with mixture-averaged transport')
f.show_solution()
print('mixture-averaged flamespeed = {0:7f} m/s'.format(f.u[0]))
print('mixture-averaged flamespeed = {0:7f} m/s'.format(f.velocity[0]))
# Solve with multi-component transport properties
f.transport_model = 'Multi'
f.solve(loglevel) # don't use 'auto' on subsequent solves
f.show_solution()
print('multicomponent flamespeed = {0:7f} m/s'.format(f.u[0]))
print('multicomponent flamespeed = {0:7f} m/s'.format(f.velocity[0]))
f.save('h2_adiabatic.xml', 'multi', 'solution with multicomponent transport')
# write the velocity, temperature, density, and mole fractions to a CSV file

View File

@@ -111,8 +111,8 @@ for p in p_range:
f.fuel_inlet.mdot *= rel_pressure_increase ** exp_mdot_p
f.oxidizer_inlet.mdot *= rel_pressure_increase ** exp_mdot_p
# Update velocities
f.set_profile('u', normalized_grid,
f.u * rel_pressure_increase ** exp_u_p)
f.set_profile('velocity', normalized_grid,
f.velocity * rel_pressure_increase ** exp_u_p)
f.set_profile('V', normalized_grid,
f.V * rel_pressure_increase ** exp_V_p)
# Update pressure curvature
@@ -167,7 +167,7 @@ while np.max(f.T) > temperature_limit_extinction:
f.fuel_inlet.mdot *= strain_factor ** exp_mdot_a
f.oxidizer_inlet.mdot *= strain_factor ** exp_mdot_a
# Update velocities
f.set_profile('u', normalized_grid, f.u * strain_factor ** exp_u_a)
f.set_profile('velocity', normalized_grid, f.velocity * strain_factor ** exp_u_a)
f.set_profile('V', normalized_grid, f.V * strain_factor ** exp_V_a)
# Update pressure curvature
f.set_profile('lambda', normalized_grid, f.L * strain_factor ** exp_lam_a)
@@ -203,7 +203,7 @@ for p in p_selected:
# Plot the axial velocity profiles (normalized by the fuel inlet velocity)
# for selected pressures
ax2.plot(f.grid / f.grid[-1], f.u / f.u[0],
ax2.plot(f.grid / f.grid[-1], f.velocity / f.velocity[0],
label='{0:05.1f} bar'.format(p))
ax1.legend(loc=0)
@@ -231,7 +231,7 @@ for n in n_selected:
# Plot the axial velocity profiles (normalized by the fuel inlet velocity)
# for the strain rate loop (selected)
ax4.plot(f.grid / f.grid[-1], f.u / f.u[0],
ax4.plot(f.grid / f.grid[-1], f.velocity / f.velocity[0],
label=format(a_max, '.2e') + ' 1/s')
ax3.legend(loc=0)

View File

@@ -88,7 +88,7 @@ n_last_burning = 0
# List of peak temperatures
T_max = [np.max(f.T)]
# List of maximum axial velocity gradients
a_max = [np.max(np.abs(np.gradient(f.u) / np.gradient(f.grid)))]
a_max = [np.max(np.abs(np.gradient(f.velocity) / np.gradient(f.grid)))]
# Simulate counterflow flames at increasing strain rates until the flame is
# extinguished. To achieve a fast simulation, an initial coarse strain rate
@@ -109,7 +109,7 @@ while True:
f.fuel_inlet.mdot *= strain_factor ** exp_mdot_a
f.oxidizer_inlet.mdot *= strain_factor ** exp_mdot_a
# Update velocities
f.set_profile('u', normalized_grid, f.u * strain_factor ** exp_u_a)
f.set_profile('velocity', normalized_grid, f.velocity * strain_factor ** exp_u_a)
f.set_profile('V', normalized_grid, f.V * strain_factor ** exp_V_a)
# Update pressure curvature
f.set_profile('lambda', normalized_grid, f.L * strain_factor ** exp_lam_a)
@@ -125,7 +125,7 @@ while True:
description='Cantera version ' + ct.__version__ +
', reaction mechanism ' + reaction_mechanism)
T_max.append(np.max(f.T))
a_max.append(np.max(np.abs(np.gradient(f.u) / np.gradient(f.grid))))
a_max.append(np.max(np.abs(np.gradient(f.velocity) / np.gradient(f.grid))))
# If the temperature difference is too small and the minimum relative
# strain rate increase is reached, abort
if ((T_max[-2] - T_max[-1] < delta_T_min) &

View File

@@ -24,7 +24,7 @@ f = ct.FreeFlame(gas, width=width)
f.set_refine_criteria(ratio=3, slope=0.07, curve=0.14)
f.solve(loglevel=1, auto=True)
print('\nmixture-averaged flamespeed = {:7f} m/s\n'.format(f.u[0]))
print('\nmixture-averaged flamespeed = {:7f} m/s\n'.format(f.velocity[0]))
# Use the adjoint method to calculate sensitivities
sens = f.get_flame_speed_reaction_sensitivities()

View File

@@ -31,7 +31,7 @@ f.solve(loglevel=loglevel, stage=2, enable_energy=True)
f.save('CH4_adiabatic.xml', 'ion', 'solution with ionized gas transport')
f.show_solution()
print('mixture-averaged flamespeed = {0:7f} m/s'.format(f.u[0]))
print('mixture-averaged flamespeed = {0:7f} m/s'.format(f.velocity[0]))
# write the velocity, temperature, density, and mole fractions to a CSV file
f.write_csv('CH4_adiabatic.csv', quiet=False)

View File

@@ -29,12 +29,12 @@ def derivative(x, y):
def computeStrainRates(oppFlame):
# Compute the derivative of axial velocity to obtain normal strain rate
strainRates = derivative(oppFlame.grid, oppFlame.u)
strainRates = derivative(oppFlame.grid, oppFlame.velocity)
# Obtain the location of the max. strain rate upstream of the pre-heat zone.
# This is the characteristic strain rate
maxStrLocation = abs(strainRates).argmax()
minVelocityPoint = oppFlame.u[:maxStrLocation].argmin()
minVelocityPoint = oppFlame.velocity[:maxStrLocation].argmin()
# Characteristic Strain Rate = K
strainRatePoint = abs(strainRates[:minVelocityPoint]).argmax()
@@ -130,15 +130,17 @@ if '--plot' in sys.argv:
# Axial Velocity Plot
plt.subplot(1, 2, 1)
plt.plot(oppFlame.grid, oppFlame.u, 'r', lw=2)
plt.plot(oppFlame.grid, oppFlame.velocity, 'r', lw=2)
plt.xlim(oppFlame.grid[0], oppFlame.grid[-1])
plt.xlabel('Distance (m)')
plt.ylabel('Axial Velocity (m/s)')
# Identify the point where the strain rate is calculated
plt.plot(oppFlame.grid[strainRatePoint], oppFlame.u[strainRatePoint], 'gs')
plt.plot(oppFlame.grid[strainRatePoint],
oppFlame.velocity[strainRatePoint], 'gs')
plt.annotate('Strain-Rate point',
xy=(oppFlame.grid[strainRatePoint], oppFlame.u[strainRatePoint]),
xy=(oppFlame.grid[strainRatePoint],
oppFlame.velocity[strainRatePoint]),
xytext=(0.001, 0.1),
arrowprops={'arrowstyle': '->'})

View File

@@ -170,8 +170,23 @@ class FlameBase(Sim1D):
def u(self):
"""
Array containing the velocity [m/s] normal to the flame at each point.
.. deprecated:: 2.5
To be deprecated with version 2.5, and removed thereafter.
Replaced by property `velocity`.
"""
return self.profile(self.flame, 'u')
warnings.warn("To be removed after Cantera 2.5. "
"Replaced by property 'velocity'",
DeprecationWarning)
return self.profile(self.flame, 'velocity')
@property
def velocity(self):
"""
Array containing the velocity [m/s] normal to the flame at each point.
"""
return self.profile(self.flame, 'velocity')
@property
def V(self):
@@ -272,7 +287,7 @@ class FlameBase(Sim1D):
z = self.grid
T = self.T
u = self.u
u = self.velocity
V = self.V
with open(filename, 'w', newline='') as csvfile:
@@ -303,8 +318,6 @@ class FlameBase(Sim1D):
for e in self._extra:
if e == 'grid':
val = self.grid
elif e == 'velocity':
val = self.profile(self.flame, 'u')
elif e == 'gradient':
val = self.profile(self.flame, 'V')
else:
@@ -380,8 +393,6 @@ class FlameBase(Sim1D):
val = getattr(arr, e)[idx]
if e in ['grid', 'qdot']:
pass
elif e == 'velocity':
self.set_profile('u', xi, val)
elif e == 'gradient':
self.set_profile('V', xi, val)
else:
@@ -730,7 +741,7 @@ class FreeFlame(FlameBase):
Yeq = self.gas.Y
u1 = self.inlet.mdot/self.gas.density
self.set_profile('u', locs, [u0, u0, u1, u1])
self.set_profile('velocity', locs, [u0, u0, u1, u1])
self.set_profile('T', locs, [T0, T0, Teq, Teq])
# Pick the location of the fixed temperature point, using an existing
@@ -824,12 +835,12 @@ class FreeFlame(FlameBase):
"""
def g(sim):
return sim.u[0]
return sim.velocity[0]
Nvars = sum(D.n_components * D.n_points for D in self.domains)
# Index of u[0] in the global solution vector
i_Su = self.inlet.n_components + self.flame.component_index('u')
i_Su = self.inlet.n_components + self.flame.component_index('velocity')
dgdx = np.zeros(Nvars)
dgdx[i_Su] = 1
@@ -856,13 +867,13 @@ class IonFlameBase(FlameBase):
"""
z = self.grid
T = self.T
u = self.u
u = self.velocity
V = self.V
E = self.E
with open(filename, 'w', newline='') as csvfile:
writer = _csv.writer(csvfile)
writer.writerow(['z (m)', 'u (m/s)', 'V (1/s)', 'T (K)',
writer.writerow(['z (m)', 'velocity (m/s)', 'V (1/s)', 'T (K)',
'E (V/m)', 'rho (kg/m3)'] + self.gas.species_names)
for n in range(self.flame.n_points):
self.set_gas_state(n)
@@ -972,7 +983,7 @@ class BurnerFlame(FlameBase):
u1 = self.burner.mdot/self.gas.density
locs = [0.0, 0.2, 1.0]
self.set_profile('u', locs, [u0, u1, u1])
self.set_profile('velocity', locs, [u0, u1, u1])
self.set_profile('T', locs, [T0, Teq, Teq])
for n in range(self.gas.n_species):
self.set_profile(self.gas.species_name(n),
@@ -1162,7 +1173,7 @@ class CounterflowDiffusionFlame(FlameBase):
T[-1] = T0o
zrel = (zz - zz[0])/dz
self.set_profile('u', [0.0, 1.0], [u0f, -u0o])
self.set_profile('velocity', [0.0, 1.0], [u0f, -u0o])
self.set_profile('V', [0.0, x0/dz, 1.0], [0.0, a, 0.0])
self.set_profile('T', zrel, T)
for k,spec in enumerate(self.gas.species_names):
@@ -1273,10 +1284,10 @@ class CounterflowDiffusionFlame(FlameBase):
.. math:: a_{o} = \sqrt{-\frac{\Lambda}{\rho_{o}}}
"""
if definition == 'mean':
return - (self.u[-1] - self.u[0]) / self.grid[-1]
return - (self.velocity[-1] - self.velocity[0]) / self.grid[-1]
elif definition == 'max':
return np.max(np.abs(np.gradient(self.u) / np.gradient(self.grid)))
return np.max(np.abs(np.gradient(self.velocity) / np.gradient(self.grid)))
elif definition == 'stoichiometric':
if fuel is None:
@@ -1292,7 +1303,7 @@ class CounterflowDiffusionFlame(FlameBase):
if 'C' in self.gas.element_names:
stoich += self.gas.n_atoms(fuel, 'C')
d_u_d_z = np.gradient(self.u) / np.gradient(self.grid)
d_u_d_z = np.gradient(self.velocity) / np.gradient(self.grid)
phi = (self.X[self.gas.species_index(fuel)] * stoich /
np.maximum(self.X[self.gas.species_index(oxidizer)], 1e-20))
z_stoich = np.interp(-1., -phi, self.grid)
@@ -1407,7 +1418,7 @@ class ImpingingJet(FlameBase):
[Y0[k], Y0[k]])
locs = np.array([0.0, 1.0])
self.set_profile('u', locs, [u0, 0.0])
self.set_profile('velocity', locs, [u0, 0.0])
self.set_profile('V', locs, [0.0, 0.0])
@@ -1498,7 +1509,7 @@ class CounterflowPremixedFlame(FlameBase):
# estimate stagnation point
x0 = rhou*uu * dz / (rhou*uu + rhob*ub)
self.set_profile('u', [0.0, 1.0], [uu, -ub])
self.set_profile('velocity', [0.0, 1.0], [uu, -ub])
self.set_profile('V', [0.0, x0/dz, 1.0], [0.0, a, 0.0])
@@ -1571,5 +1582,5 @@ class CounterflowTwinPremixedFlame(FlameBase):
dz = zz[-1] - zz[0]
a = 2 * uu / dz
self.set_profile('u', [0.0, 1.0], [uu, 0])
self.set_profile('velocity', [0.0, 1.0], [uu, 0])
self.set_profile('V', [0.0, 1.0], [0.0, a])

View File

@@ -194,7 +194,7 @@ class TestFreeFlame(utilities.CanteraTest):
self.sim.set_refine_criteria(ratio=4, slope=0.8, curve=0.8)
self.sim.solve(refine_grid=True, auto=True, loglevel=0)
self.assertNear(self.sim.u[0], 17.02, 1e-1)
self.assertNear(self.sim.velocity[0], 17.02, 1e-1)
self.assertLess(self.sim.grid[-1], 2.0) # grid should not be too wide
@@ -241,7 +241,7 @@ class TestFreeFlame(utilities.CanteraTest):
rhou = self.sim.inlet.mdot
# Check continuity
for rhou_j in self.sim.density * self.sim.u:
for rhou_j in self.sim.density * self.sim.velocity:
self.assertNear(rhou_j, rhou, 1e-4)
def test_solution_array_output(self):
@@ -272,7 +272,7 @@ class TestFreeFlame(utilities.CanteraTest):
# Check continuity
rhou = self.sim.inlet.mdot
for rhou_j in self.sim.density * self.sim.u:
for rhou_j in self.sim.density * self.sim.velocity:
self.assertNear(rhou_j, rhou, 1e-4)
def test_mixture_averaged_case1(self):
@@ -309,15 +309,15 @@ class TestFreeFlame(utilities.CanteraTest):
# Forward sensitivities
dk = 1e-4
Su0 = self.sim.u[0]
Su0 = self.sim.velocity[0]
for m in range(self.gas.n_reactions):
self.gas.set_multiplier(1.0) # reset all multipliers
self.gas.set_multiplier(1+dk, m) # perturb reaction m
self.sim.solve(loglevel=0, refine_grid=False)
Suplus = self.sim.u[0]
Suplus = self.sim.velocity[0]
self.gas.set_multiplier(1-dk, m) # perturb reaction m
self.sim.solve(loglevel=0, refine_grid=False)
Suminus = self.sim.u[0]
Suminus = self.sim.velocity[0]
fwd = (Suplus-Suminus)/(2*Su0*dk)
self.assertNear(fwd, dSdk_adj[m], 5e-3)
@@ -330,12 +330,12 @@ class TestFreeFlame(utilities.CanteraTest):
self.create_sim(p, Tin, reactants)
self.solve_fixed_T()
self.solve_mix(ratio=5, slope=0.5, curve=0.3)
Su_mix = self.sim.u[0]
Su_mix = self.sim.velocity[0]
# Multicomponent flame speed should be similar but not identical to
# the mixture-averaged flame speed.
self.solve_multi()
Su_multi = self.sim.u[0]
Su_multi = self.sim.velocity[0]
self.assertFalse(self.sim.soret_enabled)
self.assertNear(Su_mix, Su_multi, 5e-2)
@@ -346,7 +346,7 @@ class TestFreeFlame(utilities.CanteraTest):
self.sim.soret_enabled = True
self.sim.solve(loglevel=0, refine_grid=True)
self.assertTrue(self.sim.soret_enabled)
Su_soret = self.sim.u[0]
Su_soret = self.sim.velocity[0]
self.assertNear(Su_multi, Su_soret, 2e-1)
self.assertNotEqual(Su_multi, Su_soret)
@@ -429,7 +429,7 @@ class TestFreeFlame(utilities.CanteraTest):
os.remove(filename)
Y1 = self.sim.Y
u1 = self.sim.u
u1 = self.sim.velocity
V1 = self.sim.V
P1 = self.sim.P
@@ -455,7 +455,7 @@ class TestFreeFlame(utilities.CanteraTest):
self.assertNear(P1, P2a)
Y2 = self.sim.Y
u2 = self.sim.u
u2 = self.sim.velocity
V2 = self.sim.V
self.assertArrayNear(Y1, Y2)
@@ -464,7 +464,7 @@ class TestFreeFlame(utilities.CanteraTest):
self.solve_fixed_T()
Y3 = self.sim.Y
u3 = self.sim.u
u3 = self.sim.velocity
V3 = self.sim.V
# TODO: These tolereances seem too loose, but the tests fail on some
@@ -478,7 +478,12 @@ class TestFreeFlame(utilities.CanteraTest):
for attr in ct.FlameBase.__dict__:
if isinstance(ct.FlameBase.__dict__[attr], property):
getattr(self.sim, attr)
if attr == 'u':
msg = "Replaced by property 'velocity'"
with self.assertWarnsRegex(DeprecationWarning, msg):
getattr(self.sim, attr)
else:
getattr(self.sim, attr)
def test_save_restore_add_species(self):
reactants = 'H2:1.1, O2:1, AR:5'
@@ -571,7 +576,7 @@ class TestFreeFlame(utilities.CanteraTest):
def test_replace_grid(self):
self.create_sim(ct.one_atm, 300.0, 'H2:1.1, O2:1, AR:5')
self.solve_fixed_T()
ub = self.sim.u[-1]
ub = self.sim.velocity[-1]
# add some points to the grid
grid = list(self.sim.grid)
@@ -581,7 +586,7 @@ class TestFreeFlame(utilities.CanteraTest):
self.sim.set_initial_guess()
self.solve_fixed_T()
self.assertNear(self.sim.u[-1], ub, 1e-2)
self.assertNear(self.sim.velocity[-1], ub, 1e-2)
def test_exceed_max_grid_points(self):
self.create_sim(ct.one_atm, 400.0, 'H2:1.1, O2:1, AR:5')
@@ -657,7 +662,7 @@ class TestDiffusionFlame(utilities.CanteraTest):
self.solve_mix()
data = np.empty((self.sim.flame.n_points, self.gas.n_species + 4))
data[:,0] = self.sim.grid
data[:,1] = self.sim.u
data[:,1] = self.sim.velocity
data[:,2] = self.sim.V
data[:,3] = self.sim.T
data[:,4:] = self.sim.Y.T
@@ -696,7 +701,7 @@ class TestDiffusionFlame(utilities.CanteraTest):
data = np.empty((self.sim.flame.n_points, self.gas.n_species + 4))
data[:,0] = self.sim.grid
data[:,1] = self.sim.u
data[:,1] = self.sim.velocity
data[:,2] = self.sim.V
data[:,3] = self.sim.T
data[:,4:] = self.sim.Y.T
@@ -752,7 +757,7 @@ class TestDiffusionFlame(utilities.CanteraTest):
self.solve_mix()
data = np.empty((self.sim.flame.n_points, self.gas.n_species + 4))
data[:,0] = self.sim.grid
data[:,1] = self.sim.u
data[:,1] = self.sim.velocity
data[:,2] = self.sim.V
data[:,3] = self.sim.T
data[:,4:] = self.sim.Y.T
@@ -838,7 +843,7 @@ class TestCounterflowPremixedFlame(utilities.CanteraTest):
data = np.empty((sim.flame.n_points, gas.n_species + 4))
data[:,0] = sim.grid
data[:,1] = sim.u
data[:,1] = sim.velocity
data[:,2] = sim.V
data[:,3] = sim.T
data[:,4:] = sim.Y.T
@@ -927,7 +932,7 @@ class TestBurnerFlame(utilities.CanteraTest):
sim.solve(loglevel=0, auto=True)
# nonreacting solution
self.assertNear(sim.T[-1], sim.T[0], 1e-6)
self.assertNear(sim.u[-1], sim.u[0], 1e-6)
self.assertNear(sim.velocity[-1], sim.velocity[0], 1e-6)
self.assertArrayNear(sim.Y[:,0], sim.Y[:,-1], 1e-6, atol=1e-6)

View File

@@ -101,7 +101,7 @@ int flamespeed(double phi)
double uout = inlet.mdot()/rho_out;
value = {uin, uin, uout, uout};
flame.setInitialGuess("u",locs,value);
flame.setInitialGuess("velocity",locs,value);
value = {temp, temp, Tad, Tad};
flame.setInitialGuess("T",locs,value);
@@ -135,21 +135,24 @@ int flamespeed(double phi)
bool refine_grid = true;
flame.solve(loglevel,refine_grid);
double flameSpeed_mix = flame.value(flowdomain,flow.componentIndex("u"),0);
double flameSpeed_mix = flame.value(flowdomain,
flow.componentIndex("velocity"),0);
print("Flame speed with mixture-averaged transport: {} m/s\n",
flameSpeed_mix);
// now switch to multicomponent transport
flow.setTransport(*trmulti);
flame.solve(loglevel, refine_grid);
double flameSpeed_multi = flame.value(flowdomain,flow.componentIndex("u"),0);
double flameSpeed_multi = flame.value(flowdomain,
flow.componentIndex("velocity"),0);
print("Flame speed with multicomponent transport: {} m/s\n",
flameSpeed_multi);
// now enable Soret diffusion
flow.enableSoret(true);
flame.solve(loglevel, refine_grid);
double flameSpeed_full = flame.value(flowdomain,flow.componentIndex("u"),0);
double flameSpeed_full = flame.value(flowdomain,
flow.componentIndex("velocity"),0);
print("Flame speed with multicomponent transport + Soret: {} m/s\n",
flameSpeed_full);
@@ -159,9 +162,12 @@ int flamespeed(double phi)
"z (m)", "T (K)", "U (m/s)", "Y(CO)");
for (size_t n = 0; n < flow.nPoints(); n++) {
Tvec.push_back(flame.value(flowdomain,flow.componentIndex("T"),n));
COvec.push_back(flame.value(flowdomain,flow.componentIndex("CO"),n));
CO2vec.push_back(flame.value(flowdomain,flow.componentIndex("CO2"),n));
Uvec.push_back(flame.value(flowdomain,flow.componentIndex("u"),n));
COvec.push_back(flame.value(flowdomain,
flow.componentIndex("CO"),n));
CO2vec.push_back(flame.value(flowdomain,
flow.componentIndex("CO2"),n));
Uvec.push_back(flame.value(flowdomain,
flow.componentIndex("velocity"),n));
zvec.push_back(flow.grid(n));
print("{:9.6f}\t{:8.3f}\t{:5.3f}\t{:7.5f}\n",
flow.grid(n), Tvec[n], Uvec[n], COvec[n]);

View File

@@ -574,7 +574,7 @@ string StFlow::componentName(size_t n) const
{
switch (n) {
case 0:
return "u";
return "velocity";
case 1:
return "V";
case 2:
@@ -595,6 +595,11 @@ string StFlow::componentName(size_t n) const
size_t StFlow::componentIndex(const std::string& name) const
{
if (name=="u") {
warn_deprecated("StFlow::componentIndex",
"To be changed after Cantera 2.5. "
"Solution component 'u' renamed to 'velocity'");
return 0;
} else if (name=="velocity") {
return 0;
} else if (name=="V") {
return 1;