Cantera  4.0.0a1
Loading...
Searching...
No Matches
ConstPressureReactor.cpp
Go to the documentation of this file.
1//! @file ConstPressureReactor.cpp A constant pressure zero-dimensional reactor
2
3// This file is part of Cantera. See License.txt in the top-level directory or
4// at https://cantera.org/license.txt for license and copyright information.
5
13
14namespace Cantera
15{
16
17ConstPressureReactor::ConstPressureReactor(shared_ptr<Solution> sol,
18 const string& name)
19 : ConstPressureReactor(sol, true, name)
20{
21}
22
23ConstPressureReactor::ConstPressureReactor(shared_ptr<Solution> sol, bool clone,
24 const string& name)
25 : Reactor(sol, clone, name)
26{
27 m_nv = 2 + m_nsp; // mass, enthalpy, and mass fractions of each species
28}
29
30void ConstPressureReactor::getState(double* y)
31{
32 // set the first component to the total mass
33 y[0] = m_thermo->density() * m_vol;
34
35 // set the second component to the total enthalpy
36 y[1] = m_thermo->enthalpy_mass() * m_thermo->density() * m_vol;
37
38 // set components y+2 ... y+K+1 to the mass fractions Y_k of each species
39 m_thermo->getMassFractions(y+2);
40
41}
42
43void ConstPressureReactor::updateState(double* y)
44{
45 // The components of y are [0] the total mass, [1] the total enthalpy,
46 // [2...K+2) are the mass fractions of each species, and [K+2...] are the
47 // coverages of surface species on each wall.
48 m_mass = y[0];
49 m_thermo->setMassFractions_NoNorm(y+2);
50 if (m_energy) {
51 m_thermo->setState_HP(y[1]/m_mass, m_pressure);
52 } else {
53 m_thermo->setPressure(m_pressure);
54 }
55 m_vol = m_mass / m_thermo->density();
56 updateConnected(false);
57}
58
59void ConstPressureReactor::eval(double time, double* LHS, double* RHS)
60{
61 double& dmdt = RHS[0];
62 double* mdYdt = RHS + 2; // mass * dY/dt
63
64 dmdt = 0.0;
65
66 evalWalls(time);
67 updateSurfaceProductionRates();
68
69 const vector<double>& mw = m_thermo->molecularWeights();
70 const double* Y = m_thermo->massFractions();
71 double mdot_surf = dot(m_sdot.begin(), m_sdot.end(), mw.begin());
72 dmdt += mdot_surf;
73
74 if (m_chem) {
75 m_kin->getNetProductionRates(&m_wdot[0]); // "omega dot"
76 }
77
78 for (size_t k = 0; k < m_nsp; k++) {
79 // production in gas phase and from surfaces
80 mdYdt[k] = (m_wdot[k] * m_vol + m_sdot[k]) * mw[k];
81 // dilution by net surface mass flux
82 mdYdt[k] -= Y[k] * mdot_surf;
83 //Assign left-hand side of dYdt ODE as total mass
84 LHS[k+2] = m_mass;
85 }
86
87 // external heat transfer
88 double dHdt = m_Qdot;
89
90 if (m_energy) {
91 dHdt += m_thermo->intrinsicHeating() * m_vol;
92 }
93
94 // add terms for outlets
95 for (auto outlet : m_outlet) {
96 double mdot = outlet->massFlowRate();
97 dmdt -= mdot;
98 dHdt -= mdot * m_enthalpy;
99 }
100
101 // add terms for inlets
102 for (auto inlet : m_inlet) {
103 double mdot = inlet->massFlowRate();
104 dmdt += mdot; // mass flow into system
105 for (size_t n = 0; n < m_nsp; n++) {
106 double mdot_spec = inlet->outletSpeciesMassFlowRate(n);
107 // flow of species into system and dilution by other species
108 mdYdt[n] += mdot_spec - mdot * Y[n];
109 }
110 dHdt += mdot * inlet->enthalpy_mass();
111 }
112
113 if (m_energy) {
114 RHS[1] = dHdt;
115 } else {
116 RHS[1] = 0.0;
117 }
118}
119
120void ConstPressureReactor::evalSteady(double t, double* LHS, double* RHS)
121{
122 eval(t, LHS, RHS);
123 RHS[0] = m_mass - m_initialMass;
124}
125
126vector<size_t> ConstPressureReactor::initializeSteady()
127{
128 m_initialMass = m_mass;
129 return {0}; // mass
130}
131
132size_t ConstPressureReactor::componentIndex(const string& nm) const
133{
134 if (nm == "mass") {
135 return 0;
136 }
137 if (nm == "enthalpy") {
138 return 1;
139 }
140 try {
141 return m_thermo->speciesIndex(nm) + 2;
142 } catch (const CanteraError&) {
143 throw CanteraError("ConstPressureReactor::componentIndex",
144 "Component '{}' not found", nm);
145 }
146}
147
148string ConstPressureReactor::componentName(size_t k) {
149 if (k == 0) {
150 return "mass";
151 } else if (k == 1) {
152 return "enthalpy";
153 } else if (k >= 2 && k < neq()) {
154 return m_thermo->speciesName(k - 2);
155 }
156 throw IndexError("ConstPressureReactor::componentName", "component", k, m_nv);
157}
158
159double ConstPressureReactor::upperBound(size_t k) const {
160 if (k == 0) {
161 return BigNumber; // mass
162 } else if (k == 1) {
163 return BigNumber; // enthalpy
164 } else if (k >= 2 && k < m_nv) {
165 return 1.0; // species mass fraction or surface coverage
166 } else {
167 throw CanteraError("ConstPressureReactor::upperBound",
168 "Index {} is out of bounds.", k);
169 }
170}
171
172double ConstPressureReactor::lowerBound(size_t k) const {
173 if (k == 0) {
174 return 0; // mass
175 } else if (k == 1) {
176 return -BigNumber; // enthalpy
177 } else if (k >= 2 && k < m_nv) {
178 return -Tiny; // species mass fraction or surface coverage
179 } else {
180 throw CanteraError("ConstPressureReactor::lowerBound",
181 "Index {} is out of bounds.", k);
182 }
183}
184
185void ConstPressureReactor::resetBadValues(double* y) {
186 for (size_t k = 2; k < m_nv; k++) {
187 y[k] = std::max(y[k], 0.0);
188 }
189}
190
191}
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 base class WallBase.
Base class for exceptions thrown by Cantera classes.
An array index is out of range.
double dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
Definition utilities.h:82
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
const double Tiny
Small number to compare differences of mole fractions against.
Definition ct_defs.h:175
const double BigNumber
largest number to compare to inf.
Definition ct_defs.h:162
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...