Cantera  2.5.1
IdealGasReactor.cpp
Go to the documentation of this file.
1 //! @file IdealGasReactor.cpp A 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 
8 #include "cantera/zeroD/Wall.h"
9 
10 using namespace std;
11 
12 namespace Cantera
13 {
14 
15 void IdealGasReactor::setThermoMgr(ThermoPhase& thermo)
16 {
17  //! @TODO: Add a method to ThermoPhase that indicates whether a given
18  //! subclass is compatible with this reactor model
19  if (thermo.type() != "IdealGas") {
20  throw CanteraError("IdealGasReactor::setThermoMgr",
21  "Incompatible phase type provided");
22  }
23  Reactor::setThermoMgr(thermo);
24 }
25 
26 void IdealGasReactor::getState(double* y)
27 {
28  if (m_thermo == 0) {
29  throw CanteraError("IdealGasReactor::getState",
30  "Error: reactor is empty.");
31  }
32  m_thermo->restoreState(m_state);
33 
34  // set the first component to the total mass
35  m_mass = m_thermo->density() * m_vol;
36  y[0] = m_mass;
37 
38  // set the second component to the total volume
39  y[1] = m_vol;
40 
41  // Set the third component to the temperature
42  y[2] = m_thermo->temperature();
43 
44  // set components y+3 ... y+K+2 to the mass fractions of each species
45  m_thermo->getMassFractions(y+3);
46 
47  // set the remaining components to the surface species
48  // coverages on the walls
49  getSurfaceInitialConditions(y + m_nsp + 3);
50 }
51 
52 void IdealGasReactor::initialize(doublereal t0)
53 {
54  Reactor::initialize(t0);
55  m_uk.resize(m_nsp, 0.0);
56 }
57 
58 void IdealGasReactor::updateState(doublereal* y)
59 {
60  // The components of y are [0] the total mass, [1] the total volume,
61  // [2] the temperature, [3...K+3] are the mass fractions of each species,
62  // and [K+3...] are the coverages of surface species on each wall.
63  m_mass = y[0];
64  m_vol = y[1];
65  m_thermo->setMassFractions_NoNorm(y+3);
66  m_thermo->setState_TR(y[2], m_mass / m_vol);
67  updateSurfaceState(y + m_nsp + 3);
68  updateConnected(true);
69 }
70 
71 void IdealGasReactor::evalEqs(doublereal time, doublereal* y,
72  doublereal* ydot, doublereal* params)
73 {
74  double dmdt = 0.0; // dm/dt (gas phase)
75  double mcvdTdt = 0.0; // m * c_v * dT/dt
76  double* dYdt = ydot + 3;
77 
78  evalWalls(time);
79  applySensitivity(params);
80  m_thermo->restoreState(m_state);
81  m_thermo->getPartialMolarIntEnergies(&m_uk[0]);
82  const vector_fp& mw = m_thermo->molecularWeights();
83  const doublereal* Y = m_thermo->massFractions();
84 
85  if (m_chem) {
86  m_kin->getNetProductionRates(&m_wdot[0]); // "omega dot"
87  }
88 
89  double mdot_surf = evalSurfaces(time, ydot + m_nsp + 3);
90  dmdt += mdot_surf;
91 
92  // compression work and external heat transfer
93  mcvdTdt += - m_pressure * m_vdot - m_Q;
94 
95  for (size_t n = 0; n < m_nsp; n++) {
96  // heat release from gas phase and surface reactions
97  mcvdTdt -= m_wdot[n] * m_uk[n] * m_vol;
98  mcvdTdt -= m_sdot[n] * m_uk[n];
99  // production in gas phase and from surfaces
100  dYdt[n] = (m_wdot[n] * m_vol + m_sdot[n]) * mw[n] / m_mass;
101  // dilution by net surface mass flux
102  dYdt[n] -= Y[n] * mdot_surf / m_mass;
103  }
104 
105  // add terms for outlets
106  for (auto outlet : m_outlet) {
107  double mdot = outlet->massFlowRate();
108  dmdt -= mdot; // mass flow out of system
109  mcvdTdt -= mdot * m_pressure * m_vol / m_mass; // flow work
110  }
111 
112  // add terms for inlets
113  for (auto inlet : m_inlet) {
114  double mdot = inlet->massFlowRate();
115  dmdt += mdot; // mass flow into system
116  mcvdTdt += inlet->enthalpy_mass() * mdot;
117  for (size_t n = 0; n < m_nsp; n++) {
118  double mdot_spec = inlet->outletSpeciesMassFlowRate(n);
119  // flow of species into system and dilution by other species
120  dYdt[n] += (mdot_spec - mdot * Y[n]) / m_mass;
121 
122  // In combination with h_in*mdot_in, flow work plus thermal
123  // energy carried with the species
124  mcvdTdt -= m_uk[n] / mw[n] * mdot_spec;
125  }
126  }
127 
128  ydot[0] = dmdt;
129  ydot[1] = m_vdot;
130  if (m_energy) {
131  ydot[2] = mcvdTdt / (m_mass * m_thermo->cv_mass());
132  } else {
133  ydot[2] = 0;
134  }
135 
136  resetSensitivity(params);
137 }
138 
139 size_t IdealGasReactor::componentIndex(const string& nm) const
140 {
141  size_t k = speciesIndex(nm);
142  if (k != npos) {
143  return k + 3;
144  } else if (nm == "mass") {
145  return 0;
146  } else if (nm == "volume") {
147  return 1;
148  } else if (nm == "temperature") {
149  return 2;
150  } else {
151  return npos;
152  }
153 }
154 
155 std::string IdealGasReactor::componentName(size_t k) {
156  if (k == 2) {
157  return "temperature";
158  } else {
159  return Reactor::componentName(k);
160  }
161 }
162 
163 
164 }
Header file for base class WallBase.
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:102
virtual std::string type() const
String indicating the thermodynamic model implemented.
Definition: ThermoPhase.h:113
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:188
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:180
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264