Cantera  2.0
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 //====================================================================================================================
21 // create stoichiometry managers for the reactants of all reactions,
22 // for the products of the reversible reactions, and for the
23 // products of the irreversible reactions.
24 ReactionStoichMgr::ReactionStoichMgr()
25 {
26  m_dummy.resize(10,1.0);
27 }
28 //====================================================================================================================
29 ReactionStoichMgr::~ReactionStoichMgr()
30 {
31 }
32 
33 //====================================================================================================================
34 ReactionStoichMgr::ReactionStoichMgr(const ReactionStoichMgr& right) :
35  m_reactants(right.m_reactants),
36  m_revproducts(right.m_revproducts),
37  m_irrevproducts(right.m_irrevproducts),
38  m_dummy(right.m_dummy)
39 {
40 }
41 
42 //====================================================================================================================
43 ReactionStoichMgr& ReactionStoichMgr::operator=(const ReactionStoichMgr& right)
44 {
45  if (this != &right) {
46 
47  m_reactants = right.m_reactants;
48  m_revproducts = right.m_revproducts;
49  m_irrevproducts = right.m_irrevproducts;
50  m_dummy = right.m_dummy;
51  }
52  return *this;
53 }
54 //====================================================================================================================
56 add(size_t rxn, const std::vector<size_t>& reactants,
57  const std::vector<size_t>& products,
58  bool reversible)
59 {
60 
61  m_reactants.add(rxn, reactants);
62 
63  if (reversible) {
64  m_revproducts.add(rxn, products);
65  } else {
66  m_irrevproducts.add(rxn, products);
67  }
68 }
69 
70 
72 add(size_t rxn, const ReactionData& r)
73 {
74 
75  std::vector<size_t> rk;
76  doublereal frac;
77  bool isfrac = false;
78  for (size_t n = 0; n < r.reactants.size(); n++) {
79  size_t ns = size_t(r.rstoich[n]);
80  frac = r.rstoich[n] - 1.0*int(r.rstoich[n]);
81  if (frac != 0.0) {
82  isfrac = true;
83  }
84  for (size_t m = 0; m < ns; m++) {
85  rk.push_back(r.reactants[n]);
86  }
87  }
88 
89  // if the reaction has fractional stoichiometric coefficients
90  // or specified reaction orders, then add it in a general reaction
91  if (isfrac || r.global || rk.size() > 3) {
92  m_reactants.add(rxn, r.reactants, r.rorder, r.rstoich);
93  } else {
94  m_reactants.add(rxn, rk);
95  }
96 
97  std::vector<size_t> pk;
98  isfrac = false;
99  for (size_t n = 0; n < r.products.size(); n++) {
100  size_t ns = size_t(r.pstoich[n]);
101  frac = r.pstoich[n] - 1.0*int(r.pstoich[n]);
102  if (frac != 0.0) {
103  isfrac = true;
104  }
105  for (size_t m = 0; m < ns; m++) {
106  pk.push_back(r.products[n]);
107  }
108  }
109 
110  if (r.reversible) {
111  if (isfrac && !r.isReversibleWithFrac) {
112  throw CanteraError("ReactionStoichMgr::add",
113  "Fractional product stoichiometric coefficients only allowed "
114  "\nfor irreversible reactions and most reversible reactions");
115  }
116  if (pk.size() > 3 || r.isReversibleWithFrac) {
117  m_revproducts.add(rxn, r.products, r.porder, r.pstoich);
118  } else {
119  m_revproducts.add(rxn, pk);
120  }
121  } else if (isfrac || pk.size() > 3) {
122  m_irrevproducts.add(rxn, r.products, r.porder, r.pstoich);
123  } else {
124  m_irrevproducts.add(rxn, pk);
125  }
126 }
127 
129 getCreationRates(size_t nsp, const doublereal* ropf,
130  const doublereal* ropr, doublereal* c)
131 {
132  // zero out the output array
133  fill(c, c + nsp, 0.0);
134 
135  // the forward direction creates product species
136  m_revproducts.incrementSpecies(ropf, c);
137  m_irrevproducts.incrementSpecies(ropf, c);
138 
139  // the reverse direction creates reactant species
140  m_reactants.incrementSpecies(ropr, c);
141 }
142 
144 getDestructionRates(size_t nsp, const doublereal* ropf,
145  const doublereal* ropr, doublereal* d)
146 {
147  fill(d, d + nsp, 0.0);
148  // the reverse direction destroys products in reversible reactions
149  m_revproducts.incrementSpecies(ropr, d);
150  // the forward direction destroys reactants
151  m_reactants.incrementSpecies(ropf, d);
152 }
153 
155 getNetProductionRates(size_t nsp, const doublereal* ropnet, doublereal* w)
156 {
157  fill(w, w + nsp, 0.0);
158  // products are created for positive net rate of progress
159  m_revproducts.incrementSpecies(ropnet, w);
160  m_irrevproducts.incrementSpecies(ropnet, w);
161  // reactants are destroyed for positive net rate of progress
162  m_reactants.decrementSpecies(ropnet, w);
163 }
164 
166 getReactionDelta(size_t nr, const doublereal* g, doublereal* dg)
167 {
168  fill(dg, dg + nr, 0.0);
169  // products add
170  m_revproducts.incrementReactions(g, dg);
171  m_irrevproducts.incrementReactions(g, dg);
172  // reactants subtract
173  m_reactants.decrementReactions(g, dg);
174 }
175 
177 getRevReactionDelta(size_t nr, const doublereal* g, doublereal* dg)
178 {
179  fill(dg, dg + nr, 0.0);
180  m_revproducts.incrementReactions(g, dg);
181  m_reactants.decrementReactions(g, dg);
182 }
183 
185 multiplyReactants(const doublereal* c, doublereal* r)
186 {
187  m_reactants.multiply(c, r);
188 }
189 
191 multiplyRevProducts(const doublereal* c, doublereal* r)
192 {
193  m_revproducts.multiply(c, r);
194 }
195 
196 
197 void ReactionStoichMgr::
198 write(string filename)
199 {
200  ofstream f(filename.c_str());
201  f << "namespace mech {" << endl;
202  writeCreationRates(f);
203  writeDestructionRates(f);
204  writeNetProductionRates(f);
205  writeMultiplyReactants(f);
206  writeMultiplyRevProducts(f);
207  f << "} // namespace mech" << endl;
208  f.close();
209 }
210 
211 void ReactionStoichMgr::
212 writeCreationRates(ostream& f)
213 {
214  f << " void getCreationRates(const doublereal* rf, const doublereal* rb," << endl;
215  f << " doublereal* c) {" << endl;
216  map<size_t, string> out;
217  m_revproducts.writeIncrementSpecies("rf",out);
218  m_irrevproducts.writeIncrementSpecies("rf",out);
219  m_reactants.writeIncrementSpecies("rb",out);
220  map<size_t, string>::iterator b;
221  for (b = out.begin(); b != out.end(); ++b) {
222  string rhs = wrapString(b->second);
223  rhs[1] = '=';
224  f << " c[" << b->first << "] " << rhs << ";" << endl;
225  }
226  f << " }" << endl << endl << endl;
227 }
228 
229 void ReactionStoichMgr::
230 writeDestructionRates(ostream& f)
231 {
232  f << " void getDestructionRates(const doublereal* rf, const doublereal* rb," << endl;
233  f << " doublereal* d) {" << endl;
234  map<size_t, string> out;
235  m_revproducts.writeIncrementSpecies("rb",out);
236  m_reactants.writeIncrementSpecies("rf",out);
237  map<size_t, string>::iterator b;
238  for (b = out.begin(); b != out.end(); ++b) {
239  string rhs = wrapString(b->second);
240  rhs[1] = '=';
241  f << " d[" << b->first << "] " << rhs << ";" << endl;
242  }
243  f << " }" << endl << endl << endl;
244 }
245 
246 void ReactionStoichMgr::
247 writeNetProductionRates(ostream& f)
248 {
249  f << " void getNetProductionRates(const doublereal* r, doublereal* w) {" << endl;
250  map<size_t, string> out;
251  m_revproducts.writeIncrementSpecies("r",out);
252  m_irrevproducts.writeIncrementSpecies("r",out);
253  m_reactants.writeDecrementSpecies("r",out);
254  map<size_t, string>::iterator b;
255  for (b = out.begin(); b != out.end(); ++b) {
256  string rhs = wrapString(b->second);
257  rhs[1] = '=';
258  f << " w[" << b->first << "] " << rhs << ";" << endl;
259  }
260  f << " }" << endl << endl << endl;
261 }
262 
263 void ReactionStoichMgr::
264 writeMultiplyReactants(ostream& f)
265 {
266  f << " void multiplyReactants(const doublereal* c, doublereal* r) {" << endl;
267  map<size_t, string> out;
268  m_reactants.writeMultiply("c",out);
269  map<size_t, string>::iterator b;
270  for (b = out.begin(); b != out.end(); ++b) {
271  string rhs = b->second;
272  f << " r[" << b->first << "] *= " << rhs << ";" << endl;
273  }
274  f << " }" << endl << endl << endl;
275 }
276 
277 void ReactionStoichMgr::
278 writeMultiplyRevProducts(ostream& f)
279 {
280  f << " void multiplyRevProducts(const doublereal* c, doublereal* r) {" << endl;
281  map<size_t, string> out;
282  m_revproducts.writeMultiply("c",out);
283  map<size_t, string>::iterator b;
284  for (b = out.begin(); b != out.end(); ++b) {
285  string rhs = b->second;
286  f << " r[" << b->first << "] *= " << rhs << ";" << endl;
287  }
288  f << " }" << endl << endl << endl;
289 }
290 }