Cantera  2.1.2
ReactionStoichMgr.cpp
Go to the documentation of this file.
1 //------------------------------------------------
2 ///
3 /// @file ReactionStoichMgr.cpp
4 ///
5 ///
6 //------------------------------------------------
7 
9 
13 
14 #include <fstream>
15 
16 using namespace std;
17 
18 namespace Cantera
19 {
20 ReactionStoichMgr::ReactionStoichMgr()
21 {
22  m_dummy.resize(10,1.0);
23 }
24 
25 ReactionStoichMgr::~ReactionStoichMgr()
26 {
27 }
28 
29 ReactionStoichMgr::ReactionStoichMgr(const ReactionStoichMgr& right) :
30  m_reactants(right.m_reactants),
31  m_revproducts(right.m_revproducts),
32  m_irrevproducts(right.m_irrevproducts),
33  m_dummy(right.m_dummy)
34 {
35 }
36 
37 ReactionStoichMgr& ReactionStoichMgr::operator=(const ReactionStoichMgr& right)
38 {
39  if (this != &right) {
40 
41  m_reactants = right.m_reactants;
42  m_revproducts = right.m_revproducts;
43  m_irrevproducts = right.m_irrevproducts;
44  m_dummy = right.m_dummy;
45  }
46  return *this;
47 }
48 
50 add(size_t rxn, const std::vector<size_t>& reactants,
51  const std::vector<size_t>& products,
52  bool reversible)
53 {
54 
55  m_reactants.add(rxn, reactants);
56 
57  if (reversible) {
58  m_revproducts.add(rxn, products);
59  } else {
60  m_irrevproducts.add(rxn, products);
61  }
62 }
63 
65 add(size_t rxn, const ReactionData& r)
66 {
67 
68  std::vector<size_t> rk;
69  doublereal frac;
70  bool isfrac = false;
71  for (size_t n = 0; n < r.reactants.size(); n++) {
72  size_t ns = size_t(r.rstoich[n]);
73  frac = r.rstoich[n] - 1.0*int(r.rstoich[n]);
74  if (frac != 0.0) {
75  isfrac = true;
76  }
77  for (size_t m = 0; m < ns; m++) {
78  rk.push_back(r.reactants[n]);
79  }
80  }
81 
82  // if the reaction has fractional stoichiometric coefficients
83  // or specified reaction orders, then add it in a general reaction
84  if (isfrac || r.global || rk.size() > 3) {
85  m_reactants.add(rxn, r.reactants, r.rorder, r.rstoich);
86  } else {
87  m_reactants.add(rxn, rk);
88  }
89 
90  std::vector<size_t> pk;
91  isfrac = false;
92  for (size_t n = 0; n < r.products.size(); n++) {
93  size_t ns = size_t(r.pstoich[n]);
94  frac = r.pstoich[n] - 1.0*int(r.pstoich[n]);
95  if (frac != 0.0) {
96  isfrac = true;
97  }
98  for (size_t m = 0; m < ns; m++) {
99  pk.push_back(r.products[n]);
100  }
101  }
102 
103  if (r.reversible) {
104  if (isfrac && !r.isReversibleWithFrac) {
105  throw CanteraError("ReactionStoichMgr::add",
106  "Fractional product stoichiometric coefficients only allowed "
107  "\nfor irreversible reactions and most reversible reactions");
108  }
109  if (pk.size() > 3 || r.isReversibleWithFrac) {
110  m_revproducts.add(rxn, r.products, r.porder, r.pstoich);
111  } else {
112  m_revproducts.add(rxn, pk);
113  }
114  } else if (isfrac || pk.size() > 3) {
115  m_irrevproducts.add(rxn, r.products, r.porder, r.pstoich);
116  } else {
117  m_irrevproducts.add(rxn, pk);
118  }
119 }
120 
122 getCreationRates(size_t nsp, const doublereal* ropf,
123  const doublereal* ropr, doublereal* c)
124 {
125  // zero out the output array
126  fill(c, c + nsp, 0.0);
127 
128  // the forward direction creates product species
129  m_revproducts.incrementSpecies(ropf, c);
130  m_irrevproducts.incrementSpecies(ropf, c);
131 
132  // the reverse direction creates reactant species
133  m_reactants.incrementSpecies(ropr, c);
134 }
135 
137 getDestructionRates(size_t nsp, const doublereal* ropf,
138  const doublereal* ropr, doublereal* d)
139 {
140  fill(d, d + nsp, 0.0);
141  // the reverse direction destroys products in reversible reactions
142  m_revproducts.incrementSpecies(ropr, d);
143  // the forward direction destroys reactants
144  m_reactants.incrementSpecies(ropf, d);
145 }
146 
148 getNetProductionRates(size_t nsp, const doublereal* ropnet, doublereal* w)
149 {
150  fill(w, w + nsp, 0.0);
151  // products are created for positive net rate of progress
152  m_revproducts.incrementSpecies(ropnet, w);
153  m_irrevproducts.incrementSpecies(ropnet, w);
154  // reactants are destroyed for positive net rate of progress
155  m_reactants.decrementSpecies(ropnet, w);
156 }
157 
159 getReactionDelta(size_t nr, const doublereal* g, doublereal* dg)
160 {
161  fill(dg, dg + nr, 0.0);
162  // products add
163  m_revproducts.incrementReactions(g, dg);
164  m_irrevproducts.incrementReactions(g, dg);
165  // reactants subtract
166  m_reactants.decrementReactions(g, dg);
167 }
168 
170 getRevReactionDelta(size_t nr, const doublereal* g, doublereal* dg)
171 {
172  fill(dg, dg + nr, 0.0);
173  m_revproducts.incrementReactions(g, dg);
174  m_reactants.decrementReactions(g, dg);
175 }
176 
178 multiplyReactants(const doublereal* c, doublereal* r)
179 {
180  m_reactants.multiply(c, r);
181 }
182 
184 multiplyRevProducts(const doublereal* c, doublereal* r)
185 {
186  m_revproducts.multiply(c, r);
187 }
188 
189 void ReactionStoichMgr::
190 write(const string& filename)
191 {
192  ofstream f(filename.c_str());
193  f << "namespace mech {" << endl;
194  writeCreationRates(f);
195  writeDestructionRates(f);
196  writeNetProductionRates(f);
197  writeMultiplyReactants(f);
198  writeMultiplyRevProducts(f);
199  f << "} // namespace mech" << endl;
200  f.close();
201 }
202 
203 void ReactionStoichMgr::
204 writeCreationRates(ostream& f)
205 {
206  f << " void getCreationRates(const doublereal* rf, const doublereal* rb," << endl;
207  f << " doublereal* c) {" << endl;
208  map<size_t, string> out;
209  m_revproducts.writeIncrementSpecies("rf",out);
210  m_irrevproducts.writeIncrementSpecies("rf",out);
211  m_reactants.writeIncrementSpecies("rb",out);
212  map<size_t, string>::iterator b;
213  for (b = out.begin(); b != out.end(); ++b) {
214  string rhs = wrapString(b->second);
215  rhs[1] = '=';
216  f << " c[" << b->first << "] " << rhs << ";" << endl;
217  }
218  f << " }" << endl << endl << endl;
219 }
220 
221 void ReactionStoichMgr::
222 writeDestructionRates(ostream& f)
223 {
224  f << " void getDestructionRates(const doublereal* rf, const doublereal* rb," << endl;
225  f << " doublereal* d) {" << endl;
226  map<size_t, string> out;
227  m_revproducts.writeIncrementSpecies("rb",out);
228  m_reactants.writeIncrementSpecies("rf",out);
229  map<size_t, string>::iterator b;
230  for (b = out.begin(); b != out.end(); ++b) {
231  string rhs = wrapString(b->second);
232  rhs[1] = '=';
233  f << " d[" << b->first << "] " << rhs << ";" << endl;
234  }
235  f << " }" << endl << endl << endl;
236 }
237 
238 void ReactionStoichMgr::
239 writeNetProductionRates(ostream& f)
240 {
241  f << " void getNetProductionRates(const doublereal* r, doublereal* w) {" << endl;
242  map<size_t, string> out;
243  m_revproducts.writeIncrementSpecies("r",out);
244  m_irrevproducts.writeIncrementSpecies("r",out);
245  m_reactants.writeDecrementSpecies("r",out);
246  map<size_t, string>::iterator b;
247  for (b = out.begin(); b != out.end(); ++b) {
248  string rhs = wrapString(b->second);
249  rhs[1] = '=';
250  f << " w[" << b->first << "] " << rhs << ";" << endl;
251  }
252  f << " }" << endl << endl << endl;
253 }
254 
255 void ReactionStoichMgr::
256 writeMultiplyReactants(ostream& f)
257 {
258  f << " void multiplyReactants(const doublereal* c, doublereal* r) {" << endl;
259  map<size_t, string> out;
260  m_reactants.writeMultiply("c",out);
261  map<size_t, string>::iterator b;
262  for (b = out.begin(); b != out.end(); ++b) {
263  string rhs = b->second;
264  f << " r[" << b->first << "] *= " << rhs << ";" << endl;
265  }
266  f << " }" << endl << endl << endl;
267 }
268 
269 void ReactionStoichMgr::
270 writeMultiplyRevProducts(ostream& f)
271 {
272  f << " void multiplyRevProducts(const doublereal* c, doublereal* r) {" << endl;
273  map<size_t, string> out;
274  m_revproducts.writeMultiply("c",out);
275  map<size_t, string>::iterator b;
276  for (b = out.begin(); b != out.end(); ++b) {
277  string rhs = b->second;
278  f << " r[" << b->first << "] *= " << rhs << ";" << endl;
279  }
280  f << " }" << endl << endl << endl;
281 }
282 }
virtual void getNetProductionRates(size_t nsp, const doublereal *ropnet, doublereal *w)
Species net production rates.
virtual void getDestructionRates(size_t nSpecies, const doublereal *fwdRatesOfProgress, const doublereal *revRatesOfProgress, doublereal *destructionRates)
Species destruction rates.
virtual void getCreationRates(size_t nSpecies, const doublereal *fwdRatesOfProgress, const doublereal *revRatesOfProgress, doublereal *creationRates)
Species creation rates.
Header file declaring class ReactionStoichMgr.
virtual void getRevReactionDelta(size_t nr, const doublereal *g, doublereal *dg)
Given an array of species properties 'g', return in array 'dg' the change in this quantity in the rev...
vector_fp pstoich
Product stoichiometric coefficients, in the order given by products.
Definition: ReactionData.h:62
virtual void getReactionDelta(size_t nReactions, const doublereal *g, doublereal *dg)
Calculates the change of a molar species property in a reaction.
vector_fp porder
Reaction order of the reverse reaction with respect to each product species, in the order given by pr...
Definition: ReactionData.h:55
bool isReversibleWithFrac
Some reactions can be elementary reactions but have fractional stoichiometries with respect to some p...
Definition: ReactionData.h:131
std::vector< size_t > products
Indices of product species.
Definition: ReactionData.h:45
virtual void multiplyReactants(const doublereal *C, doublereal *R)
Given an array of concentrations C, multiply the entries in array R by the concentration products for...
Intermediate class which stores data about a reaction and its rate parameterization before adding the...
Definition: ReactionData.h:16
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:68
Reaction mechanism stoichiometry manager.
std::vector< size_t > reactants
Indices of reactant species.
Definition: ReactionData.h:44
vector_fp rstoich
Reactant stoichiometric coefficients, in the order given by reactants.
Definition: ReactionData.h:59
std::string wrapString(const std::string &s, const int len)
Line wrap a string via a copy operation.
bool reversible
True if the current reaction is reversible. False otherwise.
Definition: ReactionData.h:76
virtual void multiplyRevProducts(const doublereal *c, doublereal *r)
Given an array of concentrations C, multiply the entries in array R by the concentration products for...
bool global
True for "global" reactions which do not follow elementary mass action kinetics, i.e.
Definition: ReactionData.h:124
vector_fp rorder
Reaction order with respect to each reactant species, in the order given by reactants.
Definition: ReactionData.h:50
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
virtual void add(size_t rxn, const std::vector< size_t > &reactants, const std::vector< size_t > &products, bool reversible)
Add a reaction with mass-action kinetics.