20FlowReactor::FlowReactor(shared_ptr<Solution> sol,
const string& name)
21 : FlowReactor(sol, true, name)
25FlowReactor::FlowReactor(shared_ptr<Solution> sol,
bool clone,
const string& name)
26 : IdealGasReactor(sol, clone, name)
29 m_rho = m_thermo->density();
35void FlowReactor::getStateDae(
double* y,
double* ydot)
37 m_thermo->getMassFractions(y+m_offset_Y);
38 const vector<double>& mw = m_thermo->molecularWeights();
41 y[0] = m_thermo->density();
45 "Set mass flow rate before initializing reactor");
52 y[2] = m_thermo->pressure();
55 y[3] = m_thermo->temperature();
58 m_kin->getNetProductionRates(m_wdot.data());
62 updateSurfaceProductionRates();
65 std::fill(ydot, ydot + m_nv, 0.0);
76 DenseMatrix a(m_offset_Y + m_nsp, m_offset_Y + m_nsp);
79 a(0, 0) = -
GasConstant * m_thermo->temperature() / m_thermo->meanMolecularWeight();
81 a(0, 3) = - m_rho *
GasConstant / m_thermo->meanMolecularWeight();
82 for (
size_t i = 0; i < m_nsp; ++i) {
83 a(0, m_offset_Y + i) = - m_rho * m_thermo->temperature() / mw[i];
92 a(2, 1) = m_rho * m_u;
96 double cp_mass = m_thermo->cp_mass();
97 a(3, 3) = m_rho * m_u * cp_mass;
100 for (
size_t i = 0; i < m_nsp; ++i) {
101 a(m_offset_Y + i, m_offset_Y + i) = m_rho * m_u;
108 for (
size_t i = 0; i < m_nsp; ++i) {
109 h_sk_wk += m_sdot[i] * mw[i] / m_area;
121 ydot[2] = -m_u * h_sk_wk;
131 m_thermo->getPartialMolarEnthalpies(m_hk.data());
132 for (
size_t i = 0; i < m_nsp; ++i) {
133 ydot[3] -= m_hk[i] * (m_wdot[i] + m_sdot[i] / m_area);
141 for (
size_t i = 0; i < m_nsp; ++i) {
142 ydot[m_offset_Y + i] = -y[m_offset_Y + i] * h_sk_wk +
143 mw[i] * (m_wdot[i] + m_sdot[i] / m_area);
147 solve(a, ydot, 1, 0);
150void FlowReactor::updateState(
double* y)
155 m_thermo->setMassFractions_NoNorm(y + m_offset_Y);
156 m_thermo->setState_TP(y[3], y[2]);
159void FlowReactor::setMassFlowRate(
double mdot)
161 m_rho = m_thermo->density();
162 m_u = mdot/(m_rho * m_area);
165void FlowReactor::setArea(
double area) {
166 double mdot = m_rho * m_u * m_area;
168 setMassFlowRate(mdot);
171void FlowReactor::evalDae(
double time,
double* y,
double* ydot,
double* residual)
173 updateSurfaceProductionRates();
174 const vector<double>& mw = m_thermo->molecularWeights();
176 for (
size_t i = 0; i < m_nsp; ++i) {
177 sk_wk += m_sdot[i] * mw[i] / m_area;
179 m_thermo->getPartialMolarEnthalpies(m_hk.data());
182 m_kin->getNetProductionRates(m_wdot.data());
186 double drhodz = ydot[0];
187 double dudz = ydot[1];
188 double dPdz = ydot[2];
189 double dTdz = ydot[3];
192 residual[0] = m_rho - m_thermo->density();
196 residual[1] = m_u * drhodz + m_rho * dudz - sk_wk;
201 residual[2] = m_rho * m_u * dudz + m_u * sk_wk + dPdz;
211 double cp_mass = m_thermo->cp_mass();
212 residual[3] = m_rho * m_u * cp_mass * dTdz;
213 for (
size_t i = 0; i < m_nsp; ++i) {
214 residual[3] += m_hk[i] * (m_wdot[i] + m_sdot[i] / m_area);
223 for (
size_t i = 0; i < m_nsp; ++i) {
224 residual[i + m_offset_Y] = m_rho * m_u * ydot[i + m_offset_Y] +
225 y[i + m_offset_Y] * sk_wk -
226 mw[i] * (m_wdot[i] + m_sdot[i] / m_area);
227 dSumYdz += ydot[i + m_offset_Y];
233 double scale = 0.1 * m_rho * m_u / rtol;
234 for (
size_t i = 0; i < m_nsp; ++i) {
235 residual[i + m_offset_Y] +=
scale * std::max(0.0, y[i + m_offset_Y]) * dSumYdz;
239void FlowReactor::getConstraints(
double* constraints) {
241 std::fill(constraints, constraints + m_nv, 1.0);
244size_t FlowReactor::componentIndex(
const string& nm)
const
246 if (nm ==
"density") {
248 }
else if (nm ==
"speed") {
250 }
else if (nm ==
"pressure") {
252 }
else if (nm ==
"temperature") {
256 return m_thermo->speciesIndex(nm) + m_offset_Y;
259 "Component '{}' not found", nm);
263string FlowReactor::componentName(
size_t k)
272 return "temperature";
273 }
else if (k >= 4 && k < neq()) {
274 return m_thermo->speciesName(k - 4);
276 throw IndexError(
"FlowReactor::componentName",
"component", k, m_nv);
Headers for the DenseMatrix object, which deals with dense rectangular matrices and description of th...
Base class for kinetics managers and also contains the kineticsmgr module documentation (see Kinetics...
Header file for class ReactorSurface.
Header for a simple thermodynamics model of a surface phase derived from ThermoPhase,...
Header file for class ThermoPhase, the base class for phases with thermodynamic properties,...
Base class for exceptions thrown by Cantera classes.
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
An array index is out of range.
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
const double GasConstant
Universal Gas Constant [J/kmol/K].
Namespace for the Cantera kernel.
void solve(DenseMatrix &A, double *b, size_t nrhs, size_t ldb)
Solve Ax = b. Array b is overwritten on exit with x.