Cantera  2.1.2
AqueousKinetics.cpp
Go to the documentation of this file.
1 /**
2  * @file AqueousKinetics.cpp
3  *
4  * Homogeneous kinetics in an aqueous phase, either condensed
5  * or dilute in salts
6  *
7  */
8 /*
9  * Copyright (2006) Sandia Corporation. Under the terms of
10  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
11  * U.S. Government retains certain rights in this software.
12  */
13 
18 
19 using namespace std;
20 
21 namespace Cantera
22 {
23 
24 AqueousKinetics::AqueousKinetics(thermo_t* thermo) :
25  Kinetics(),
26  m_nfall(0),
27  m_nirrev(0),
28  m_nrev(0),
29  m_ROP_ok(false),
30  m_temp(0.0),
31  m_finalized(false)
32 {
33  warn_deprecated("AqueousKinetics",
34  "Unfinished implementation of this class will be removed.");
35  if (thermo != 0) {
36  addPhase(*thermo);
37  }
38 }
39 
41  Kinetics(),
42  m_nfall(0),
43  m_nirrev(0),
44  m_nrev(0),
45  m_ROP_ok(false),
46  m_temp(0.0),
47  m_finalized(false)
48 {
49  *this = right;
50 }
51 
52 AqueousKinetics& AqueousKinetics::operator=(const AqueousKinetics& right)
53 {
54  if (this == &right) {
55  return *this;
56  }
57 
58  Kinetics::operator=(right);
59 
60  m_nfall = right.m_nfall;
61  m_rates = right.m_rates;
62  m_index = right.m_index;
63  m_irrev = right.m_irrev;
64 
65  m_rxnstoich = right.m_rxnstoich;
66 
67  m_fwdOrder = right.m_fwdOrder;
68  m_nirrev = right.m_nirrev;
69  m_nrev = right.m_nrev;
70  m_rgroups = right.m_rgroups;
71  m_pgroups = right.m_pgroups;
72  m_rxntype = right.m_rxntype;
73  m_rrxn = right.m_rrxn;
74  m_prxn = right.m_prxn;
75  m_dn = right.m_dn;
76  m_revindex = right.m_revindex;
77  m_rxneqn = right.m_rxneqn;
78 
79  m_ropf = right.m_ropf;
80  m_ropr = right.m_ropr;
81  m_ropnet = right.m_ropnet;
82  m_ROP_ok = right.m_ROP_ok;
83  m_temp = right.m_temp;
84  m_rfn = right.m_rfn;
85  m_rkcn = right.m_rkcn;
86 
87  m_conc = right.m_conc;
88  m_grt = right.m_grt;
89  m_finalized = right.m_finalized;
90 
91  throw CanteraError("GasKinetics::operator=()",
92  "Unfinished implementation");
93 
94  return *this;
95 
96 }
97 
98 Kinetics* AqueousKinetics::duplMyselfAsKinetics(const std::vector<thermo_t*> & tpVector) const
99 {
100  AqueousKinetics* gK = new AqueousKinetics(*this);
101  gK->assignShallowPointers(tpVector);
102  return gK;
103 }
104 
105 void AqueousKinetics::
106 update_T() {}
107 
108 void AqueousKinetics::
109 update_C() {}
110 
112 {
113  doublereal T = thermo().temperature();
114  doublereal logT = log(T);
115  m_rates.update(T, logT, &m_rfn[0]);
116 
117  m_temp = T;
118  updateKc();
119  m_ROP_ok = false;
120 }
121 
124 {
125  thermo().getActivityConcentrations(&m_conc[0]);
126 
127  m_ROP_ok = false;
128 }
129 
131 {
132  doublereal rt = GasConstant * m_temp;
133 
134  thermo().getStandardChemPotentials(&m_grt[0]);
135  fill(m_rkcn.begin(), m_rkcn.end(), 0.0);
136  for (size_t k = 0; k < thermo().nSpecies(); k++) {
137  doublereal logStandConc_k = thermo().logStandardConc(k);
138  m_grt[k] -= rt * logStandConc_k;
139  }
140 
141  // compute Delta G^0 for all reversible reactions
142  m_rxnstoich.getRevReactionDelta(m_ii, &m_grt[0], &m_rkcn[0]);
143 
144  //doublereal logStandConc = m_kdata->m_logStandConc;
145  doublereal rrt = 1.0/(GasConstant * thermo().temperature());
146  for (size_t i = 0; i < m_nrev; i++) {
147  size_t irxn = m_revindex[i];
148  m_rkcn[irxn] = exp(m_rkcn[irxn]*rrt);
149  }
150 
151  for (size_t i = 0; i != m_nirrev; ++i) {
152  m_rkcn[ m_irrev[i] ] = 0.0;
153  }
154 }
155 
157 {
158  _update_rates_T();
159 
160  thermo().getStandardChemPotentials(&m_grt[0]);
161  fill(m_rkcn.begin(), m_rkcn.end(), 0.0);
162  doublereal rt = GasConstant * m_temp;
163  for (size_t k = 0; k < thermo().nSpecies(); k++) {
164  doublereal logStandConc_k = thermo().logStandardConc(k);
165  m_grt[k] -= rt * logStandConc_k;
166  }
167 
168  // compute Delta G^0 for all reactions
169  m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], &m_rkcn[0]);
170 
171  doublereal rrt = 1.0/(GasConstant * thermo().temperature());
172  for (size_t i = 0; i < m_ii; i++) {
173  kc[i] = exp(-m_rkcn[i]*rrt);
174  }
175 
176  // force an update of T-dependent properties, so that m_rkcn will
177  // be updated before it is used next.
178  m_temp = 0.0;
179 }
180 
181 void AqueousKinetics::getDeltaGibbs(doublereal* deltaG)
182 {
183  /*
184  * Get the chemical potentials of the species in the
185  * ideal gas solution.
186  */
187  thermo().getChemPotentials(&m_grt[0]);
188  /*
189  * Use the stoichiometric manager to find deltaG for each
190  * reaction.
191  */
192  m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], deltaG);
193 }
194 
195 void AqueousKinetics::getDeltaEnthalpy(doublereal* deltaH)
196 {
197  /*
198  * Get the partial molar enthalpy of all species in the
199  * ideal gas.
200  */
201  thermo().getPartialMolarEnthalpies(&m_grt[0]);
202  /*
203  * Use the stoichiometric manager to find deltaG for each
204  * reaction.
205  */
206  m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], deltaH);
207 }
208 
209 void AqueousKinetics::getDeltaEntropy(doublereal* deltaS)
210 {
211  /*
212  * Get the partial molar entropy of all species in the
213  * solid solution.
214  */
215  thermo().getPartialMolarEntropies(&m_grt[0]);
216  /*
217  * Use the stoichiometric manager to find deltaS for each
218  * reaction.
219  */
220  m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], deltaS);
221 }
222 
223 void AqueousKinetics::getDeltaSSGibbs(doublereal* deltaG)
224 {
225  /*
226  * Get the standard state chemical potentials of the species.
227  * This is the array of chemical potentials at unit activity
228  * We define these here as the chemical potentials of the pure
229  * species at the temperature and pressure of the solution.
230  */
231  thermo().getStandardChemPotentials(&m_grt[0]);
232  /*
233  * Use the stoichiometric manager to find deltaG for each
234  * reaction.
235  */
236  m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], deltaG);
237 }
238 
239 void AqueousKinetics::getDeltaSSEnthalpy(doublereal* deltaH)
240 {
241  /*
242  * Get the standard state enthalpies of the species.
243  * This is the array of chemical potentials at unit activity
244  * We define these here as the enthalpies of the pure
245  * species at the temperature and pressure of the solution.
246  */
247  thermo().getEnthalpy_RT(&m_grt[0]);
248  doublereal RT = thermo().temperature() * GasConstant;
249  for (size_t k = 0; k < m_kk; k++) {
250  m_grt[k] *= RT;
251  }
252  /*
253  * Use the stoichiometric manager to find deltaG for each
254  * reaction.
255  */
256  m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], deltaH);
257 }
258 
259 void AqueousKinetics::getDeltaSSEntropy(doublereal* deltaS)
260 {
261  /*
262  * Get the standard state entropy of the species.
263  * We define these here as the entropies of the pure
264  * species at the temperature and pressure of the solution.
265  */
266  thermo().getEntropy_R(&m_grt[0]);
267  doublereal R = GasConstant;
268  for (size_t k = 0; k < m_kk; k++) {
269  m_grt[k] *= R;
270  }
271  /*
272  * Use the stoichiometric manager to find deltaS for each
273  * reaction.
274  */
275  m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], deltaS);
276 }
277 
278 void AqueousKinetics::updateROP()
279 {
280  _update_rates_T();
281  _update_rates_C();
282 
283  if (m_ROP_ok) {
284  return;
285  }
286 
287  // copy rate coefficients into ropf
288  copy(m_rfn.begin(), m_rfn.end(), m_ropf.begin());
289 
290  // multiply by perturbation factor
291  multiply_each(m_ropf.begin(), m_ropf.end(), m_perturb.begin());
292 
293  // copy the forward rates to the reverse rates
294  copy(m_ropf.begin(), m_ropf.end(), m_ropr.begin());
295 
296  // for reverse rates computed from thermochemistry, multiply
297  // the forward rates copied into m_ropr by the reciprocals of
298  // the equilibrium constants
299  multiply_each(m_ropr.begin(), m_ropr.end(), m_rkcn.begin());
300 
301  // multiply ropf by concentration products
302  m_rxnstoich.multiplyReactants(&m_conc[0], &m_ropf[0]);
303  //m_reactantStoich.multiply(m_conc.begin(), ropf.begin());
304 
305  // for reversible reactions, multiply ropr by concentration
306  // products
307  m_rxnstoich.multiplyRevProducts(&m_conc[0], &m_ropr[0]);
308  //m_revProductStoich.multiply(m_conc.begin(), ropr.begin());
309 
310  for (size_t j = 0; j != m_ii; ++j) {
311  m_ropnet[j] = m_ropf[j] - m_ropr[j];
312  }
313 
314  m_ROP_ok = true;
315 }
316 
318 getFwdRateConstants(doublereal* kfwd)
319 {
320  _update_rates_T();
321  _update_rates_C();
322 
323  // copy rate coefficients into ropf
324  copy(m_rfn.begin(), m_rfn.end(), m_ropf.begin());
325 
326  // multiply by perturbation factor
327  multiply_each(m_ropf.begin(), m_ropf.end(), m_perturb.begin());
328 
329  for (size_t i = 0; i < m_ii; i++) {
330  kfwd[i] = m_ropf[i];
331  }
332 }
333 
335 getRevRateConstants(doublereal* krev, bool doIrreversible)
336 {
337  /*
338  * go get the forward rate constants. -> note, we don't
339  * really care about speed or redundancy in these
340  * informational routines.
341  */
342  getFwdRateConstants(krev);
343 
344  if (doIrreversible) {
345  getEquilibriumConstants(&m_ropnet[0]);
346  for (size_t i = 0; i < m_ii; i++) {
347  krev[i] /= m_ropnet[i];
348  }
349  } else {
350  /*
351  * m_rkcn[] is zero for irreversible reactions
352  */
353  for (size_t i = 0; i < m_ii; i++) {
354  krev[i] *= m_rkcn[i];
355  }
356  }
357 }
358 
360 {
361  if (r.reactionType == ELEMENTARY_RXN) {
362  addElementaryReaction(r);
363  }
364 
365  // operations common to all reaction types
366  installReagents(r);
367  installGroups(reactionNumber(), r.rgroups, r.pgroups);
369  m_rxneqn.push_back(r.equation);
370 }
371 
372 void AqueousKinetics::addElementaryReaction(ReactionData& r)
373 {
374  size_t iloc;
375 
376  // install rate coeff calculator
377  iloc = m_rates.install(reactionNumber(), r);
378 
379  // add constant term to rate coeff value vector
380  m_rfn.push_back(r.rateCoeffParameters[0]);
381 
382  // forward rxn order equals number of reactants
383  m_fwdOrder.push_back(r.reactants.size());
384  registerReaction(reactionNumber(), ELEMENTARY_RXN, iloc);
385 }
386 
387 void AqueousKinetics::installReagents(const ReactionData& r)
388 {
389 
390  m_ropf.push_back(0.0); // extend by one for new rxn
391  m_ropr.push_back(0.0);
392  m_ropnet.push_back(0.0);
393  size_t n, ns, m;
394  doublereal nsFlt;
395  doublereal reactantGlobalOrder = 0.0;
396  doublereal productGlobalOrder = 0.0;
397  size_t rnum = reactionNumber();
398 
399  std::vector<size_t> rk;
400  size_t nr = r.reactants.size();
401  for (n = 0; n < nr; n++) {
402  nsFlt = r.rstoich[n];
403  reactantGlobalOrder += nsFlt;
404  ns = (size_t) nsFlt;
405  if ((doublereal) ns != nsFlt) {
406  if (ns < 1) {
407  ns = 1;
408  }
409  }
410  if (r.rstoich[n] != 0.0) {
411  m_rrxn[r.reactants[n]][rnum] += r.rstoich[n];
412  }
413  for (m = 0; m < ns; m++) {
414  rk.push_back(r.reactants[n]);
415  }
416  }
417  m_reactants.push_back(rk);
418 
419  std::vector<size_t> pk;
420  size_t np = r.products.size();
421  for (n = 0; n < np; n++) {
422  nsFlt = r.pstoich[n];
423  productGlobalOrder += nsFlt;
424  ns = (size_t) nsFlt;
425  if ((double) ns != nsFlt) {
426  if (ns < 1) {
427  ns = 1;
428  }
429  }
430  if (r.pstoich[n] != 0.0) {
431  m_prxn[r.products[n]][rnum] += r.pstoich[n];
432  }
433  for (m = 0; m < ns; m++) {
434  pk.push_back(r.products[n]);
435  }
436  }
437  m_products.push_back(pk);
438 
439  m_rkcn.push_back(0.0);
440 
441  m_rxnstoich.add(reactionNumber(), r);
442 
443  if (r.reversible) {
444  m_dn.push_back(productGlobalOrder - reactantGlobalOrder);
445  m_revindex.push_back(reactionNumber());
446  m_nrev++;
447  } else {
448  m_dn.push_back(productGlobalOrder - reactantGlobalOrder);
449  m_irrev.push_back(reactionNumber());
450  m_nirrev++;
451  }
452 }
453 
454 void AqueousKinetics::installGroups(size_t irxn,
455  const vector<grouplist_t>& r,
456  const vector<grouplist_t>& p)
457 {
458  if (!r.empty()) {
459  writelog("installing groups for reaction "+int2str(reactionNumber()));
460  m_rgroups[reactionNumber()] = r;
461  m_pgroups[reactionNumber()] = p;
462  }
463 }
464 
466 {
467  m_kk = thermo().nSpecies();
468  m_rrxn.resize(m_kk);
469  m_prxn.resize(m_kk);
470  m_conc.resize(m_kk);
471  m_grt.resize(m_kk);
472 }
473 
475 {
476  if (!m_finalized) {
477  m_finalized = true;
478 
479  // Guarantee that these arrays can be converted to double* even in the
480  // special case where there are no reactions defined.
481  if (!m_ii) {
482  m_perturb.resize(1, 1.0);
483  m_ropf.resize(1, 0.0);
484  m_ropr.resize(1, 0.0);
485  m_ropnet.resize(1, 0.0);
486  m_rkcn.resize(1, 0.0);
487  }
488  }
489 }
490 
492 {
493  return m_finalized;
494 }
495 
496 }
std::vector< grouplist_t > rgroups
Optional data used in reaction path diagrams.
Definition: ReactionData.h:64
Kinetics manager for elementary aqueous-phase chemistry.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Definition: stringUtils.cpp:40
virtual void init()
Prepare the class for the addition of reactions.
virtual void getDeltaEnthalpy(doublereal *deltaH)
Return the vector of values for the reactions change in enthalpy.
void incrementRxnCount()
Increment the number of reactions in the mechanism by one.
Definition: Kinetics.h:859
std::vector< std::vector< size_t > > m_reactants
This is a vector of vectors containing the reactants for each reaction.
Definition: Kinetics.h:908
int reactionType
Type of the reaction.
Definition: ReactionData.h:39
virtual void assignShallowPointers(const std::vector< thermo_t * > &tpVector)
Reassign the pointers within the Kinetics object.
Definition: Kinetics.cpp:144
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
Definition: ThermoPhase.h:721
thermo_t & thermo(size_t n=0)
This method returns a reference to the nth ThermoPhase object defined in this kinetics mechanism...
Definition: Kinetics.h:288
size_t m_kk
The number of species in all of the phases that participate in this kinetics mechanism.
Definition: Kinetics.h:891
virtual void getDeltaGibbs(doublereal *deltaG)
Return the vector of values for the reaction gibbs free energy change.
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...
virtual void addReaction(ReactionData &r)
Add a single reaction to the mechanism.
AqueousKinetics(thermo_t *thermo=0)
Constructor. Creates an empty reaction mechanism.
virtual void getRevRateConstants(doublereal *krev, bool doIrreversible=false)
Return the reverse rate constants.
virtual void getDeltaSSEntropy(doublereal *deltaS)
Return the vector of values for the change in the standard state entropies for each reaction...
virtual void getReactionDelta(size_t nReactions, const doublereal *g, doublereal *dg)
Calculates the change of a molar species property in a reaction.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:76
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
Definition: ThermoPhase.h:711
virtual void finalize()
Finish adding reactions and prepare for use.
virtual void getEquilibriumConstants(doublereal *kc)
Return a vector of Equilibrium constants.
void multiply_each(OutputIter x_begin, OutputIter x_end, InputIter y_begin)
Multiply each entry in x by the corresponding entry in y.
Definition: utilities.h:227
vector_fp rateCoeffParameters
Vector of rate coefficient parameters.
Definition: ReactionData.h:91
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:101
std::string equation
The reaction equation. Used only for display purposes.
Definition: ReactionData.h:109
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...
std::vector< grouplist_t > pgroups
Optional data used in reaction path diagrams.
Definition: ReactionData.h:65
vector_fp m_dn
Difference between the input global reactants order and the input global products order...
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: ThermoPhase.h:595
vector_fp m_perturb
Vector of perturbation factors for each reaction's rate of progress vector.
Definition: Kinetics.h:895
Public interface for kinetics managers.
Definition: Kinetics.h:131
Intermediate class which stores data about a reaction and its rate parameterization before adding the...
Definition: ReactionData.h:16
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
Definition: ThermoPhase.h:638
Kinetics & operator=(const Kinetics &right)
Assignment operator.
Definition: Kinetics.cpp:62
std::vector< size_t > reactants
Indices of reactant species.
Definition: ReactionData.h:44
void updateKc()
Update the equilibrium constants in molar units.
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:252
virtual void getDeltaSSEnthalpy(doublereal *deltaH)
Return the vector of values for the change in the standard state enthalpies of reaction.
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
Definition: ThermoPhase.h:731
doublereal temperature() const
Temperature (K).
Definition: Phase.h:528
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
Definition: ThermoPhase.h:465
virtual bool ready() const
Returns true if the kinetics manager has been properly initialized and finalized. ...
std::vector< std::vector< size_t > > m_products
This is a vector of vectors containing the products for each reaction.
Definition: Kinetics.h:921
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:66
size_t m_ii
Number of reactions in the mechanism.
Definition: Kinetics.h:887
const int ELEMENTARY_RXN
A reaction with a rate coefficient that depends only on temperature.
Definition: reaction_defs.h:26
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...
virtual void getFwdRateConstants(doublereal *kfwd)
Return the forward rate constants.
Contains declarations for string manipulation functions within Cantera.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
Definition: ThermoPhase.h:628
virtual doublereal logStandardConc(size_t k=0) const
Natural logarithm of the standard concentration of the kth species.
void writelog(const std::string &msg)
Write a message to the screen.
Definition: global.cpp:43
virtual void addPhase(thermo_t &thermo)
Add a phase to the kinetics manager object.
Definition: Kinetics.cpp:255
virtual Kinetics * duplMyselfAsKinetics(const std::vector< thermo_t * > &tpVector) const
Duplication routine for objects which inherit from Kinetics.
virtual void getDeltaEntropy(doublereal *deltaS)
Return the vector of values for the reactions change in entropy.
virtual void getDeltaSSGibbs(doublereal *deltaG)
Return the vector of values for the reaction standard state gibbs free energy change.
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.