Cantera  3.3.0a1
Loading...
Searching...
No Matches
InterfaceKinetics.h
Go to the documentation of this file.
1/**
2 * @file InterfaceKinetics.h
3 */
4
5// This file is part of Cantera. See License.txt in the top-level directory or
6// at https://cantera.org/license.txt for license and copyright information.
7
8#ifndef CT_IFACEKINETICS_H
9#define CT_IFACEKINETICS_H
10
11#include "Kinetics.h"
12
13namespace Cantera
14{
15
16// forward declarations
17class SurfPhase;
18class ImplicitSurfChem;
19
20//! A kinetics manager for heterogeneous reaction mechanisms. The reactions are
21//! assumed to occur at a 2D interface between two 3D phases.
22/*!
23 * There are some important additions to the behavior of the kinetics class due
24 * to the presence of multiple phases and a heterogeneous interface. If a
25 * reactant phase doesn't exists, that is, has a mole number of zero, a
26 * heterogeneous reaction can not proceed from reactants to products. Note it
27 * could perhaps proceed from products to reactants if all of the product phases
28 * exist.
29 *
30 * In order to make the determination of whether a phase exists or not actually
31 * involves the specification of additional information to the kinetics object.,
32 * which heretofore has only had access to intrinsic field information about the
33 * phases (for example, temperature, pressure, and mole fraction).
34 *
35 * The extrinsic specification of whether a phase exists or not must be
36 * specified on top of the intrinsic calculation of the reaction rate. This
37 * class carries a set of booleans indicating whether a phase in the
38 * heterogeneous mechanism exists or not.
39 *
40 * Additionally, the class carries a set of booleans around indicating whether a
41 * product phase is stable or not. If a phase is not thermodynamically stable,
42 * it may be the case that a particular reaction in a heterogeneous mechanism
43 * will create a product species in the unstable phase. However, other reactions
44 * in the mechanism will destruct that species. This may cause oscillations in
45 * the formation of the unstable phase from time step to time step within a ODE
46 * solver, in practice. In order to avoid this situation, a set of booleans is
47 * tracked which sets the stability of a phase. If a phase is deemed to be
48 * unstable, then species in that phase will not be allowed to be birthed by the
49 * kinetics operator. Nonexistent phases are deemed to be unstable by default,
50 * but this can be changed.
51 *
52 * @ingroup kineticsmgr
53 */
55{
56public:
57 //! Constructor
58 InterfaceKinetics() = default;
59
60 ~InterfaceKinetics() override;
61
62 void resizeReactions() override;
63
64 string kineticsType() const override {
65 return "surface";
66 }
67
68 //! Set the electric potential in the nth phase
69 /*!
70 * @param n phase Index in this kinetics object.
71 * @param V Electric potential (volts)
72 */
73 void setElectricPotential(int n, double V);
74
75 //! @name Reaction Rates Of Progress
76 //! @{
77
78 //! Equilibrium constant for all reactions including the voltage term
79 /*!
80 * Kc = exp(deltaG/RT)
81 *
82 * where deltaG is the electrochemical potential difference between
83 * products minus reactants.
84 */
85 void getEquilibriumConstants(double* kc) override;
86
87 void getDeltaGibbs(double* deltaG) override;
88
89 void getDeltaElectrochemPotentials(double* deltaM) override;
90 void getDeltaEnthalpy(double* deltaH) override;
91 void getDeltaEntropy(double* deltaS) override;
92
93 void getDeltaSSGibbs(double* deltaG) override;
94 void getDeltaSSEnthalpy(double* deltaH) override;
95 void getDeltaSSEntropy(double* deltaS) override;
96
97 //! @}
98 //! @name Reaction Mechanism Informational Query Routines
99 //! @{
100
101 void getFwdRateConstants(double* kfwd) override;
102 void getRevRateConstants(double* krev, bool doIrreversible=false) override;
103
104 //! @}
105 //! @name Reaction Mechanism Construction
106 //! @{
107
108 //! Add a thermo phase to the kinetics manager object.
109 /*!
110 * This must be done before the function init() is called or
111 * before any reactions are input. The lowest dimensional phase, where reactions
112 * occur, must be added first.
113 *
114 * This function calls Kinetics::addThermo). It also sets the following
115 * fields:
116 *
117 * m_phaseExists[]
118 *
119 * @param thermo Reference to the ThermoPhase to be added.
120 */
121 void addThermo(shared_ptr<ThermoPhase> thermo) override;
122
123 void init() override;
124 void resizeSpecies() override;
125 bool addReaction(shared_ptr<Reaction> r, bool resize=true) override;
126 void modifyReaction(size_t i, shared_ptr<Reaction> rNew) override;
127 void setMultiplier(size_t i, double f) override;
128 //! @}
129
130 //! Internal routine that updates the Rates of Progress of the reactions
131 /*!
132 * This is actually the guts of the functionality of the object
133 */
134 void updateROP() override;
135
136 //! Update properties that depend on temperature
137 /*!
138 * Current objects that this function updates:
139 * m_kdata->m_rfn
140 * updateKc();
141 */
142 void _update_rates_T();
143
144 //! Update properties that depend on the electric potential
145 void _update_rates_phi();
146
147 //! Update properties that depend on the species mole fractions and/or
148 //! concentration,
149 /*!
150 * This method fills out the array of generalized concentrations by calling
151 * method getActivityConcentrations for each phase, which classes
152 * representing phases should overload to return the appropriate quantities.
153 */
154 void _update_rates_C();
155
156 //! Advance the surface coverages in time
157 /*!
158 * This method carries out a time-accurate advancement of the
159 * surface coverages for a specified amount of time.
160 *
161 * @f[
162 * \dot {\theta}_k = \dot s_k (\sigma_k / s_0)
163 * @f]
164 *
165 * @param tstep Time value to advance the surface coverages
166 * @param rtol The relative tolerance for the integrator
167 * @param atol The absolute tolerance for the integrator
168 * @param maxStepSize The maximum step-size the integrator is allowed to take.
169 * If zero, this option is disabled.
170 * @param maxSteps The maximum number of time-steps the integrator can take.
171 * If not supplied, uses the default value in CVodeIntegrator (20000).
172 * @param maxErrTestFails the maximum permissible number of error test failures
173 * If not supplied, uses the default value in CVODES (7).
174 */
175 void advanceCoverages(double tstep, double rtol=1.e-7,
176 double atol=1.e-14, double maxStepSize=0,
177 size_t maxSteps=20000, size_t maxErrTestFails=7);
178
179 //! Solve for the pseudo steady-state of the surface problem
180 /*!
181 * This is the same thing as the advanceCoverages() function,
182 * but at infinite times.
183 *
184 * Note, a direct solve is carried out under the hood here,
185 * to reduce the computational time.
186 *
187 * @param ifuncOverride One of the values defined in @ref solvesp_methods.
188 * The default is -1, which means that the program will decide.
189 * @param timeScaleOverride When a pseudo transient is selected this value
190 * can be used to override the default time scale for
191 * integration which is one. When SFLUX_TRANSIENT is used, this
192 * is equal to the time over which the equations are integrated.
193 * When SFLUX_INITIALIZE is used, this is equal to the time used
194 * in the initial transient algorithm, before the equation
195 * system is solved directly.
196 */
197 void solvePseudoSteadyStateProblem(int ifuncOverride = -1,
198 double timeScaleOverride = 1.0);
199
200 void setIOFlag(int ioFlag);
201
202 //! Update the standard state chemical potentials and species equilibrium
203 //! constant entries
204 /*!
205 * Virtual because it is overridden when dealing with experimental open
206 * circuit voltage overrides
207 */
208 virtual void updateMu0();
209
210 //! Update the equilibrium constants and stored electrochemical potentials
211 //! in molar units for all reversible reactions and for all species.
212 /*!
213 * Irreversible reactions have their equilibrium constant set
214 * to zero. For reactions involving charged species the equilibrium
215 * constant is adjusted according to the electrostatic potential.
216 */
217 void updateKc();
218
219 //! Set the existence of a phase in the reaction object
220 /*!
221 * Tell the kinetics object whether a phase in the object exists. This is
222 * actually an extrinsic specification that must be carried out on top of
223 * the intrinsic calculation of the reaction rate. The routine will also
224 * flip the IsStable boolean within the kinetics object as well.
225 *
226 * @param iphase Index of the phase. This is the order within the
227 * internal thermo vector object
228 * @param exists Boolean indicating whether the phase exists or not
229 */
230 void setPhaseExistence(const size_t iphase, const int exists);
231
232 //! Set the stability of a phase in the reaction object
233 /*!
234 * Tell the kinetics object whether a phase in the object is stable.
235 * Species in an unstable phase will not be allowed to have a positive
236 * rate of formation from this kinetics object. This is actually an
237 * extrinsic specification that must be carried out on top of the
238 * intrinsic calculation of the reaction rate.
239 *
240 * While conceptually not needed since kinetics is consistent with thermo
241 * when taken as a whole, in practice it has found to be very useful to
242 * turn off the creation of phases which shouldn't be forming. Typically
243 * this can reduce the oscillations in phase formation and destruction
244 * which are observed.
245 *
246 * @param iphase Index of the phase. This is the order within the
247 * internal thermo vector object
248 * @param isStable Flag indicating whether the phase is stable or not
249 */
250 void setPhaseStability(const size_t iphase, const int isStable);
251
252 //! Gets the phase existence int for the ith phase
253 /*!
254 * @param iphase Phase Id
255 * @return The int specifying whether the kinetics object thinks the phase
256 * exists or not. If it exists, then species in that phase can be
257 * a reactant in reactions.
258 */
259 int phaseExistence(const size_t iphase) const;
260
261 //! Gets the phase stability int for the ith phase
262 /*!
263 * @param iphase Phase Id
264 * @return The int specifying whether the kinetics object thinks the phase
265 * is stable with nonzero mole numbers. If it stable, then the
266 * kinetics object will allow for rates of production of of
267 * species in that phase that are positive.
268 */
269 int phaseStability(const size_t iphase) const;
270
271 //! Gets the interface current for the ith phase
272 /*!
273 * @param iphase Phase Id
274 * @return The double specifying the interface current. The interface current
275 * is useful when charge transfer reactions occur at an interface. It
276 * is defined here as the net positive charge entering the phase
277 * specified by the Phase Id. (Units: A/m^2 for a surface reaction,
278 * A/m for an edge reaction).
279 */
280 double interfaceCurrent(const size_t iphase);
281
282 void setDerivativeSettings(const AnyMap& settings) override;
283 void getDerivativeSettings(AnyMap& settings) const override;
284 Eigen::SparseMatrix<double> fwdRatesOfProgress_ddCi() override;
285 Eigen::SparseMatrix<double> revRatesOfProgress_ddCi() override;
286 Eigen::SparseMatrix<double> netRatesOfProgress_ddCi() override;
287
288protected:
289 //! @name Internal service methods
290 //!
291 //! @note These methods are for internal use, and seek to avoid code duplication
292 //! while evaluating terms used for rate constants, rates of progress, and
293 //! their derivatives.
294 //! @{
295
296
297 //! Multiply rate with inverse equilibrium constant
298 void applyEquilibriumConstants(double* rop);
299
300 //! Process mole fraction derivative
301 //! @param stoich stoichiometry manager
302 //! @param in rate expression used for the derivative calculation
303 //! @return a sparse matrix of derivative contributions for each reaction of
304 //! dimensions nTotalReactions by nTotalSpecies
305 Eigen::SparseMatrix<double> calculateCompositionDerivatives(StoichManagerN& stoich,
306 const vector<double>& in);
307
308 //! Helper function ensuring that all rate derivatives can be calculated
309 //! @param name method name used for error output
310 //! @throw CanteraError if coverage dependence or electrochemical reactions are
311 //! included
312 void assertDerivativesValid(const string& name);
313
314 //! @}
315
316 //! Temporary work vector of length m_kk
317 vector<double> m_grt;
318
319 bool m_redo_rates = false;
320
321 //! Array of concentrations for each species in the kinetics mechanism
322 /*!
323 * An array of generalized concentrations @f$ C_k @f$ that are defined
324 * such that @f$ a_k = C_k / C^0_k, @f$ where @f$ C^0_k @f$ is a standard
325 * concentration/ These generalized concentrations are used by this
326 * kinetics manager class to compute the forward and reverse rates of
327 * elementary reactions. The "units" for the concentrations of each phase
328 * depend upon the implementation of kinetics within that phase. The order
329 * of the species within the vector is based on the order of listed
330 * ThermoPhase objects in the class, and the order of the species within
331 * each ThermoPhase class.
332 */
333 vector<double> m_conc;
334
335 //! Array of activity concentrations for each species in the kinetics object
336 /*!
337 * An array of activity concentrations @f$ Ca_k @f$ that are defined
338 * such that @f$ a_k = Ca_k / C^0_k, @f$ where @f$ C^0_k @f$ is a standard
339 * concentration. These activity concentrations are used by this
340 * kinetics manager class to compute the forward and reverse rates of
341 * elementary reactions. The "units" for the concentrations of each phase
342 * depend upon the implementation of kinetics within that phase. The order
343 * of the species within the vector is based on the order of listed
344 * ThermoPhase objects in the class, and the order of the species within
345 * each ThermoPhase class.
346 */
347 vector<double> m_actConc;
348
349 //! Vector of standard state chemical potentials for all species
350 /*!
351 * This vector contains a temporary vector of standard state chemical
352 * potentials for all of the species in the kinetics object
353 *
354 * Length = m_kk. Units = J/kmol.
355 */
356 vector<double> m_mu0;
357
358 //! Vector of chemical potentials for all species
359 /*!
360 * This vector contains a vector of chemical potentials for all of the
361 * species in the kinetics object
362 *
363 * Length = m_kk. Units = J/kmol.
364 */
365 vector<double> m_mu;
366
367 //! Vector of standard state electrochemical potentials modified by a
368 //! standard concentration term.
369 /*!
370 * This vector contains a temporary vector of standard state electrochemical
371 * potentials + RTln(Cs) for all of the species in the kinetics object
372 *
373 * In order to get the units correct for the concentration equilibrium
374 * constant, each species needs to have an RT ln(Cs) added to its
375 * contribution to the equilibrium constant Cs is the standard concentration
376 * for the species. Frequently, for solid species, Cs is equal to 1.
377 * However, for gases Cs is P/RT. Length = m_kk. Units = J/kmol.
378 */
379 vector<double> m_mu0_Kc;
380
381 //! Vector of phase electric potentials
382 /*!
383 * Temporary vector containing the potential of each phase in the kinetics
384 * object. length = number of phases. Units = Volts.
385 */
386 vector<double> m_phi;
387
388 //! Pointer to the single surface phase
389 SurfPhase* m_surf = nullptr;
390
391 //! Pointer to the Implicit surface chemistry object
392 /*!
393 * Note this object is owned by this InterfaceKinetics object. It may only
394 * be used to solve this single InterfaceKinetics object's surface problem
395 * uncoupled from other surface phases.
396 */
398
399 bool m_ROP_ok = false;
400
401 //! Current temperature of the data
402 double m_temp = 0.0;
403
404 //! Int flag to indicate that some phases in the kinetics mechanism are
405 //! non-existent.
406 /*!
407 * We change the ROP vectors to make sure that non-existent phases are
408 * treated correctly in the kinetics operator. The value of this is equal
409 * to the number of phases which don't exist.
410 */
412
413 //! Vector of booleans indicating whether phases exist or not
414 /*!
415 * Vector of booleans indicating whether a phase exists or not. We use this
416 * to set the ROP's so that unphysical things don't happen. For example, a
417 * reaction can't go in the forwards direction if a phase in which a
418 * reactant is present doesn't exist. Because InterfaceKinetics deals with
419 * intrinsic quantities only normally, nowhere else is this extrinsic
420 * concept introduced except here.
421 *
422 * length = number of phases in the object. By default all phases exist.
423 */
424 vector<bool> m_phaseExists;
425
426 //! Vector of int indicating whether phases are stable or not
427 /*!
428 * Vector of booleans indicating whether a phase is stable or not under
429 * the current conditions. We use this to set the ROP's so that
430 * unphysical things don't happen.
431 *
432 * length = number of phases in the object. By default all phases are stable.
433 */
434 vector<int> m_phaseIsStable;
435
436 //! Vector of vector of booleans indicating whether a phase participates in
437 //! a reaction as a reactant
438 /*!
439 * m_rxnPhaseIsReactant[j][p] indicates whether a species in phase p
440 * participates in reaction j as a reactant.
441 */
442 vector<vector<bool>> m_rxnPhaseIsReactant;
443
444 //! Vector of vector of booleans indicating whether a phase participates in a
445 //! reaction as a product
446 /*!
447 * m_rxnPhaseIsReactant[j][p] indicates whether a species in phase p
448 * participates in reaction j as a product.
449 */
450 vector<vector<bool>> m_rxnPhaseIsProduct;
451
452 int m_ioFlag = 0;
453
454 //! Number of dimensions of reacting phase (2 for InterfaceKinetics, 1 for
455 //! EdgeKinetics)
456 size_t m_nDim = 2;
457
458 //! Buffers for partial rop results with length nReactions()
459 vector<double> m_rbuf0;
460 vector<double> m_rbuf1;
461
462 //! A flag used to neglect rate coefficient coverage dependence in derivative
463 //! formation
465 //! A flag used to neglect electrochemical contributions in derivative formation
467 //! Relative tolerance used in developing numerical portions of specific derivatives
468 double m_jac_rtol_delta = 1e-8;
469 //! A flag stating if the object uses electrochemistry
471 //! A flag stating if the object has coverage dependent rates
473};
474
475}
476
477#endif
Base class for kinetics managers and also contains the kineticsmgr module documentation (see Kinetics...
A map of string keys to values whose type can vary at runtime.
Definition AnyMap.h:431
Advances the surface coverages of the associated set of SurfacePhase objects in time.
A kinetics manager for heterogeneous reaction mechanisms.
bool addReaction(shared_ptr< Reaction > r, bool resize=true) override
Add a single reaction to the mechanism.
int phaseExistence(const size_t iphase) const
Gets the phase existence int for the ith phase.
double interfaceCurrent(const size_t iphase)
Gets the interface current for the ith phase.
SurfPhase * m_surf
Pointer to the single surface phase.
vector< vector< bool > > m_rxnPhaseIsReactant
Vector of vector of booleans indicating whether a phase participates in a reaction as a reactant.
string kineticsType() const override
Identifies the Kinetics manager type.
vector< int > m_phaseIsStable
Vector of int indicating whether phases are stable or not.
Eigen::SparseMatrix< double > revRatesOfProgress_ddCi() override
Calculate derivatives for forward rates-of-progress with respect to species concentration at constant...
size_t m_nDim
Number of dimensions of reacting phase (2 for InterfaceKinetics, 1 for EdgeKinetics)
void getFwdRateConstants(double *kfwd) override
Return the forward rate constants.
vector< bool > m_phaseExists
Vector of booleans indicating whether phases exist or not.
void getDeltaSSGibbs(double *deltaG) override
Return the vector of values for the reaction standard state Gibbs free energy change.
double m_temp
Current temperature of the data.
void setPhaseStability(const size_t iphase, const int isStable)
Set the stability of a phase in the reaction object.
void getDeltaGibbs(double *deltaG) override
Return the vector of values for the reaction Gibbs free energy change.
bool m_jac_skip_coverage_dependence
A flag used to neglect rate coefficient coverage dependence in derivative formation.
void _update_rates_phi()
Update properties that depend on the electric potential.
vector< double > m_phi
Vector of phase electric potentials.
void assertDerivativesValid(const string &name)
Helper function ensuring that all rate derivatives can be calculated.
double m_jac_rtol_delta
Relative tolerance used in developing numerical portions of specific derivatives.
void setMultiplier(size_t i, double f) override
Set the multiplier for reaction i to f.
void getDeltaSSEntropy(double *deltaS) override
Return the vector of values for the change in the standard state entropies for each reaction.
void advanceCoverages(double tstep, double rtol=1.e-7, double atol=1.e-14, double maxStepSize=0, size_t maxSteps=20000, size_t maxErrTestFails=7)
Advance the surface coverages in time.
InterfaceKinetics()=default
Constructor.
void getDeltaSSEnthalpy(double *deltaH) override
Return the vector of values for the change in the standard state enthalpies of reaction.
void resizeSpecies() override
Resize arrays with sizes that depend on the total number of species.
vector< double > m_grt
Temporary work vector of length m_kk.
void getRevRateConstants(double *krev, bool doIrreversible=false) override
Return the reverse rate constants.
void getEquilibriumConstants(double *kc) override
Equilibrium constant for all reactions including the voltage term.
bool m_has_electrochemistry
A flag stating if the object uses electrochemistry.
void updateKc()
Update the equilibrium constants and stored electrochemical potentials in molar units for all reversi...
void setPhaseExistence(const size_t iphase, const int exists)
Set the existence of a phase in the reaction object.
void updateROP() override
Internal routine that updates the Rates of Progress of the reactions.
void applyEquilibriumConstants(double *rop)
Multiply rate with inverse equilibrium constant.
void getDerivativeSettings(AnyMap &settings) const override
Retrieve derivative settings.
void getDeltaEnthalpy(double *deltaH) override
Return the vector of values for the reactions change in enthalpy.
Eigen::SparseMatrix< double > fwdRatesOfProgress_ddCi() override
Calculate derivatives for forward rates-of-progress with respect to species concentration at constant...
void modifyReaction(size_t i, shared_ptr< Reaction > rNew) override
Modify the rate expression associated with a reaction.
bool m_jac_skip_electrochemistry
A flag used to neglect electrochemical contributions in derivative formation.
void _update_rates_C()
Update properties that depend on the species mole fractions and/or concentration,.
vector< double > m_rbuf0
Buffers for partial rop results with length nReactions()
int phaseStability(const size_t iphase) const
Gets the phase stability int for the ith phase.
vector< double > m_mu0_Kc
Vector of standard state electrochemical potentials modified by a standard concentration term.
ImplicitSurfChem * m_integrator
Pointer to the Implicit surface chemistry object.
void _update_rates_T()
Update properties that depend on temperature.
void solvePseudoSteadyStateProblem(int ifuncOverride=-1, double timeScaleOverride=1.0)
Solve for the pseudo steady-state of the surface problem.
bool m_has_coverage_dependence
A flag stating if the object has coverage dependent rates.
virtual void updateMu0()
Update the standard state chemical potentials and species equilibrium constant entries.
void addThermo(shared_ptr< ThermoPhase > thermo) override
Add a thermo phase to the kinetics manager object.
vector< double > m_mu
Vector of chemical potentials for all species.
vector< double > m_actConc
Array of activity concentrations for each species in the kinetics object.
vector< double > m_mu0
Vector of standard state chemical potentials for all species.
void getDeltaElectrochemPotentials(double *deltaM) override
Return the vector of values for the reaction electrochemical free energy change.
void setElectricPotential(int n, double V)
Set the electric potential in the nth phase.
void init() override
Prepare the class for the addition of reactions, after all phases have been added.
void resizeReactions() override
Finalize Kinetics object and associated objects.
int m_phaseExistsCheck
Int flag to indicate that some phases in the kinetics mechanism are non-existent.
Eigen::SparseMatrix< double > calculateCompositionDerivatives(StoichManagerN &stoich, const vector< double > &in)
Process mole fraction derivative.
Eigen::SparseMatrix< double > netRatesOfProgress_ddCi() override
Calculate derivatives for net rates-of-progress with respect to species concentration at constant tem...
void getDeltaEntropy(double *deltaS) override
Return the vector of values for the reactions change in entropy.
vector< vector< bool > > m_rxnPhaseIsProduct
Vector of vector of booleans indicating whether a phase participates in a reaction as a product.
void setDerivativeSettings(const AnyMap &settings) override
Set/modify derivative settings.
vector< double > m_conc
Array of concentrations for each species in the kinetics mechanism.
Public interface for kinetics managers.
Definition Kinetics.h:126
ThermoPhase & thermo(size_t n=0)
This method returns a reference to the nth ThermoPhase object defined in this kinetics mechanism.
Definition Kinetics.h:239
This class handles operations involving the stoichiometric coefficients on one side of a reaction (re...
A simple thermodynamic model for a surface phase, assuming an ideal solution model.
Definition SurfPhase.h:114
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595