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