Cantera  4.0.0a2
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 ReactorNet;
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 ~InterfaceKinetics() override;
60
61 void resizeReactions() override;
62
63 string kineticsType() const override {
64 return "surface";
65 }
66
67 //! Set the electric potential in the nth phase
68 /*!
69 * @param n phase Index in this kinetics object.
70 * @param V Electric potential (volts)
71 */
72 void setElectricPotential(int n, double V);
73
74 //! @name Reaction Rates Of Progress
75 //! @{
76
77 void getEquilibriumConstants(span<double> kc) override;
78 void getDeltaGibbs(span<double> deltaG) override;
79
80 void getDeltaElectrochemPotentials(span<double> deltaM) override;
81 void getDeltaEnthalpy(span<double> deltaH) override;
82 void getDeltaEntropy(span<double> deltaS) override;
83
84 void getDeltaSSGibbs(span<double> deltaG) override;
85 void getDeltaSSEnthalpy(span<double> deltaH) override;
86 void getDeltaSSEntropy(span<double> deltaS) override;
87
88 //! @}
89 //! @name Reaction Mechanism Informational Query Routines
90 //! @{
91
92 void getFwdRateConstants(span<double> kfwd) override;
93 void getRevRateConstants(span<double> krev, bool doIrreversible=false) override;
94
95 //! @}
96 //! @name Reaction Mechanism Construction
97 //! @{
98
99 //! Add a thermo phase to the kinetics manager object.
100 /*!
101 * This must be done before the function init() is called or
102 * before any reactions are input. The lowest dimensional phase, where reactions
103 * occur, must be added first.
104 *
105 * This function calls Kinetics::addThermo). It also sets the following
106 * fields:
107 *
108 * m_phaseExists[]
109 *
110 * @param thermo Reference to the ThermoPhase to be added.
111 */
112 void addThermo(shared_ptr<ThermoPhase> thermo) override;
113
114 void init() override;
115 void resizeSpecies() override;
116 bool addReaction(shared_ptr<Reaction> r, bool resize=true) override;
117 void modifyReaction(size_t i, shared_ptr<Reaction> rNew) override;
118 void setMultiplier(size_t i, double f) override;
119 //! @}
120
121 //! Internal routine that updates the Rates of Progress of the reactions
122 /*!
123 * This is actually the guts of the functionality of the object
124 */
125 void updateROP() override;
126
127 //! Update properties that depend on temperature
128 /*!
129 * Current objects that this function updates:
130 * m_kdata->m_rfn
131 * updateKc();
132 */
133 void _update_rates_T();
134
135 //! Update properties that depend on the electric potential
136 void _update_rates_phi();
137
138 //! Update properties that depend on the species mole fractions and/or
139 //! concentration,
140 /*!
141 * This method fills out the array of generalized concentrations by calling
142 * method getActivityConcentrations for each phase, which classes
143 * representing phases should overload to return the appropriate quantities.
144 */
145 void _update_rates_C();
146
147 //! Advance the surface coverages in time
148 /*!
149 * This method carries out a time-accurate advancement of the
150 * surface coverages for a specified amount of time.
151 *
152 * @f[
153 * \dot {\theta}_k = \dot s_k (\sigma_k / s_0)
154 * @f]
155 *
156 * For the purpose of this integration, the temperature and pressure of the adjacent
157 * bulk phases set equal to those of the surface phase, and the composition of the
158 * bulk phases is held fixed.
159 *
160 * @param tstep Time value to advance the surface coverages
161 * @param rtol The relative tolerance for the integrator
162 * @param atol The absolute tolerance for the integrator
163 * @param maxStepSize The maximum step-size the integrator is allowed to take.
164 * If zero, this option is disabled.
165 * @param maxSteps The maximum number of time-steps the integrator can take.
166 * If not supplied, uses the default value in CVodeIntegrator (20000).
167 * @param maxErrTestFails the maximum permissible number of error test failures
168 * If not supplied, uses the default value in CVODES (7).
169 */
170 void advanceCoverages(double tstep, double rtol=1.e-7,
171 double atol=1.e-14, double maxStepSize=0,
172 size_t maxSteps=20000, size_t maxErrTestFails=7);
173
174 //! Solve for the pseudo steady-state of the surface problem
175 /*!
176 * This is the same thing as the advanceCoverages() function,
177 * but at infinite times. Carries out a direct solution of the nonlinear
178 * algebraic system using SteadyReactorSolver.
179 *
180 * @param loglevel Log level argument passed to SteadyReactorSolver
181 * @since In %Cantera 4.0, the previous arguments were replaced with `loglevel`.
182 */
183 void solvePseudoSteadyStateProblem(int loglevel=0);
184
185 //! Update the standard state chemical potentials and species equilibrium
186 //! constant entries
187 /*!
188 * Virtual because it is overridden when dealing with experimental open
189 * circuit voltage overrides
190 */
191 virtual void updateMu0();
192
193 //! Update the equilibrium constants and stored electrochemical potentials
194 //! in molar units for all reversible reactions and for all species.
195 /*!
196 * Irreversible reactions have their equilibrium constant set
197 * to zero. For reactions involving charged species the equilibrium
198 * constant is adjusted according to the electrostatic potential.
199 */
200 void updateKc();
201
202 //! Set the existence of a phase in the reaction object
203 /*!
204 * Tell the kinetics object whether a phase in the object exists. This is
205 * actually an extrinsic specification that must be carried out on top of
206 * the intrinsic calculation of the reaction rate. The routine will also
207 * flip the IsStable boolean within the kinetics object as well.
208 *
209 * @param iphase Index of the phase. This is the order within the
210 * internal thermo vector object
211 * @param exists Boolean indicating whether the phase exists or not
212 */
213 void setPhaseExistence(const size_t iphase, const int exists);
214
215 //! Set the stability of a phase in the reaction object
216 /*!
217 * Tell the kinetics object whether a phase in the object is stable.
218 * Species in an unstable phase will not be allowed to have a positive
219 * rate of formation from this kinetics object. This is actually an
220 * extrinsic specification that must be carried out on top of the
221 * intrinsic calculation of the reaction rate.
222 *
223 * While conceptually not needed since kinetics is consistent with thermo
224 * when taken as a whole, in practice it has found to be very useful to
225 * turn off the creation of phases which shouldn't be forming. Typically
226 * this can reduce the oscillations in phase formation and destruction
227 * which are observed.
228 *
229 * @param iphase Index of the phase. This is the order within the
230 * internal thermo vector object
231 * @param isStable Flag indicating whether the phase is stable or not
232 */
233 void setPhaseStability(const size_t iphase, const int isStable);
234
235 //! Gets the phase existence int for the ith phase
236 /*!
237 * @param iphase Phase Id
238 * @return The int specifying whether the kinetics object thinks the phase
239 * exists or not. If it exists, then species in that phase can be
240 * a reactant in reactions.
241 */
242 int phaseExistence(const size_t iphase) const;
243
244 //! Gets the phase stability int for the ith phase
245 /*!
246 * @param iphase Phase Id
247 * @return The int specifying whether the kinetics object thinks the phase
248 * is stable with nonzero mole numbers. If it stable, then the
249 * kinetics object will allow for rates of production of of
250 * species in that phase that are positive.
251 */
252 int phaseStability(const size_t iphase) const;
253
254 //! Gets the interface current for the ith phase
255 /*!
256 * @param iphase Phase Id
257 * @return The double specifying the interface current. The interface current
258 * is useful when charge transfer reactions occur at an interface. It
259 * is defined here as the net positive charge entering the phase
260 * specified by the Phase Id. (Units: A/m^2 for a surface reaction,
261 * A/m for an edge reaction).
262 */
263 double interfaceCurrent(const size_t iphase);
264
265 void setDerivativeSettings(const AnyMap& settings) override;
266 void getDerivativeSettings(AnyMap& settings) const override;
267 Eigen::SparseMatrix<double> fwdRatesOfProgress_ddCi() override;
268 Eigen::SparseMatrix<double> revRatesOfProgress_ddCi() override;
269 Eigen::SparseMatrix<double> netRatesOfProgress_ddCi() override;
270
271protected:
272 //! @name Internal service methods
273 //!
274 //! @note These methods are for internal use, and seek to avoid code duplication
275 //! while evaluating terms used for rate constants, rates of progress, and
276 //! their derivatives.
277 //! @{
278
279
280 //! Multiply rate with inverse equilibrium constant
281 void applyEquilibriumConstants(span<double> rop);
282
283 //! Process mole fraction derivative
284 //! @param stoich stoichiometry manager
285 //! @param in rate expression used for the derivative calculation
286 //! @return a sparse matrix of derivative contributions for each reaction of
287 //! dimensions nTotalReactions by nTotalSpecies
288 Eigen::SparseMatrix<double> calculateCompositionDerivatives(
289 StoichManagerN& stoich, span<const double> in);
290
291 //! Helper function ensuring that all rate derivatives can be calculated
292 //! @param name method name used for error output
293 //! @throw CanteraError if coverage dependence or electrochemical reactions are
294 //! included
295 void assertDerivativesValid(const string& name);
296
297 //! Create a ReactorNet where only the surface species are active, for use with
298 //! advanceCoverages() and solvePseudoSteadyStateProblem().
299 void buildNetwork();
300
301 //! @}
302
303 //! Temporary work vector of length m_kk
304 vector<double> m_grt;
305
306 bool m_redo_rates = false;
307
308 //! Array of concentrations for each species in the kinetics mechanism
309 /*!
310 * An array of generalized concentrations @f$ C_k @f$ that are defined
311 * such that @f$ a_k = C_k / C^0_k, @f$ where @f$ C^0_k @f$ is a standard
312 * concentration/ These generalized concentrations are used by this
313 * kinetics manager class to compute the forward and reverse rates of
314 * elementary reactions. The "units" for the concentrations of each phase
315 * depend upon the implementation of kinetics within that phase. The order
316 * of the species within the vector is based on the order of listed
317 * ThermoPhase objects in the class, and the order of the species within
318 * each ThermoPhase class.
319 */
320 vector<double> m_conc;
321
322 //! Array of activity concentrations for each species in the kinetics object
323 /*!
324 * An array of activity concentrations @f$ Ca_k @f$ that are defined
325 * such that @f$ a_k = Ca_k / C^0_k, @f$ where @f$ C^0_k @f$ is a standard
326 * concentration. These activity concentrations are used by this
327 * kinetics manager class to compute the forward and reverse rates of
328 * elementary reactions. The "units" for the concentrations of each phase
329 * depend upon the implementation of kinetics within that phase. The order
330 * of the species within the vector is based on the order of listed
331 * ThermoPhase objects in the class, and the order of the species within
332 * each ThermoPhase class.
333 */
334 vector<double> m_actConc;
335
336 //! Vector of standard state chemical potentials for all species
337 /*!
338 * This vector contains a temporary vector of standard state chemical
339 * potentials for all of the species in the kinetics object
340 *
341 * Length = m_kk. Units = J/kmol.
342 */
343 vector<double> m_mu0;
344
345 //! Vector of chemical potentials for all species
346 /*!
347 * This vector contains a vector of chemical potentials for all of the
348 * species in the kinetics object
349 *
350 * Length = m_kk. Units = J/kmol.
351 */
352 vector<double> m_mu;
353
354 //! Vector of standard state electrochemical potentials modified by a
355 //! standard concentration term.
356 /*!
357 * This vector contains a temporary vector of standard state electrochemical
358 * potentials + RTln(Cs) for all of the species in the kinetics object
359 *
360 * In order to get the units correct for the concentration equilibrium
361 * constant, each species needs to have an RT ln(Cs) added to its
362 * contribution to the equilibrium constant Cs is the standard concentration
363 * for the species. Frequently, for solid species, Cs is equal to 1.
364 * However, for gases Cs is P/RT. Length = m_kk. Units = J/kmol.
365 */
366 vector<double> m_mu0_Kc;
367
368 //! Vector of phase electric potentials
369 /*!
370 * Temporary vector containing the potential of each phase in the kinetics
371 * object. length = number of phases. Units = Volts.
372 */
373 vector<double> m_phi;
374
375 //! Pointer to the single surface phase
376 SurfPhase* m_surf = nullptr;
377
378 //! Pointer to the Implicit surface chemistry object
379 /*!
380 * Note this object is owned by this InterfaceKinetics object. It may only
381 * be used to solve this single InterfaceKinetics object's surface problem
382 * uncoupled from other surface phases.
383 */
385
386 bool m_ROP_ok = false;
387
388 //! Current temperature of the data
389 double m_temp = 0.0;
390
391 //! Int flag to indicate that some phases in the kinetics mechanism are
392 //! non-existent.
393 /*!
394 * We change the ROP vectors to make sure that non-existent phases are
395 * treated correctly in the kinetics operator. The value of this is equal
396 * to the number of phases which don't exist.
397 */
399
400 //! Vector of booleans indicating whether phases exist or not
401 /*!
402 * Vector of booleans indicating whether a phase exists or not. We use this
403 * to set the ROP's so that unphysical things don't happen. For example, a
404 * reaction can't go in the forwards direction if a phase in which a
405 * reactant is present doesn't exist. Because InterfaceKinetics deals with
406 * intrinsic quantities only normally, nowhere else is this extrinsic
407 * concept introduced except here.
408 *
409 * length = number of phases in the object. By default all phases exist.
410 */
411 vector<bool> m_phaseExists;
412
413 //! Vector of int indicating whether phases are stable or not
414 /*!
415 * Vector of booleans indicating whether a phase is stable or not under
416 * the current conditions. We use this to set the ROP's so that
417 * unphysical things don't happen.
418 *
419 * length = number of phases in the object. By default all phases are stable.
420 */
421 vector<int> m_phaseIsStable;
422
423 //! Vector of vector of booleans indicating whether a phase participates in
424 //! a reaction as a reactant
425 /*!
426 * m_rxnPhaseIsReactant[j][p] indicates whether a species in phase p
427 * participates in reaction j as a reactant.
428 */
429 vector<vector<bool>> m_rxnPhaseIsReactant;
430
431 //! Vector of vector of booleans indicating whether a phase participates in a
432 //! reaction as a product
433 /*!
434 * m_rxnPhaseIsReactant[j][p] indicates whether a species in phase p
435 * participates in reaction j as a product.
436 */
437 vector<vector<bool>> m_rxnPhaseIsProduct;
438
439 //! Number of dimensions of reacting phase (2 for InterfaceKinetics, 1 for
440 //! EdgeKinetics)
441 size_t m_nDim = 2;
442
443 //! Buffers for partial rop results with length nReactions()
444 vector<double> m_rbuf0;
445 vector<double> m_rbuf1;
446
447 //! A flag used to neglect rate coefficient coverage dependence in derivative
448 //! formation
450 //! A flag used to neglect electrochemical contributions in derivative formation
452 //! Relative tolerance used in developing numerical portions of specific derivatives
453 double m_jac_rtol_delta = 1e-8;
454 //! A flag stating if the object uses electrochemistry
456 //! A flag stating if the object has coverage dependent rates
458};
459
460}
461
462#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
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.
void getDeltaElectrochemPotentials(span< double > deltaM) override
Return the vector of values for the reaction electrochemical free energy change.
void applyEquilibriumConstants(span< double > rop)
Multiply rate with inverse equilibrium constant.
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)
vector< bool > m_phaseExists
Vector of booleans indicating whether phases exist or not.
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 getDeltaEnthalpy(span< double > deltaH) override
Return the vector of values for the reactions change in enthalpy.
void getEquilibriumConstants(span< double > kc) override
Get the vector of equilibrium constants in concentration units.
void solvePseudoSteadyStateProblem(int loglevel=0)
Solve for the pseudo steady-state of the surface problem.
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 getFwdRateConstants(span< double > kfwd) override
Return the forward rate constants.
ReactorNet * m_integrator
Pointer to the Implicit surface chemistry object.
void buildNetwork()
Create a ReactorNet where only the surface species are active, for use with advanceCoverages() and so...
void setMultiplier(size_t i, double f) override
Set the multiplier for reaction i to f.
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.
void getDeltaSSGibbs(span< double > deltaG) override
Return the vector of values for the reaction standard state Gibbs free energy change.
InterfaceKinetics()=default
Constructor.
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.
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 getDerivativeSettings(AnyMap &settings) const override
Retrieve derivative settings.
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.
void getRevRateConstants(span< double > krev, bool doIrreversible=false) override
Return the reverse rate constants.
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.
void getDeltaSSEnthalpy(span< double > deltaH) override
Return the vector of values for the change in the standard state enthalpies of reaction.
Eigen::SparseMatrix< double > calculateCompositionDerivatives(StoichManagerN &stoich, span< const double > in)
Process mole fraction derivative.
vector< double > m_mu0_Kc
Vector of standard state electrochemical potentials modified by a standard concentration term.
void _update_rates_T()
Update properties that depend on temperature.
void getDeltaEntropy(span< double > deltaS) override
Return the vector of values for the reactions change in entropy.
void getDeltaSSEntropy(span< double > deltaS) override
Return the vector of values for the change in the standard state entropies for each reaction.
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 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 > netRatesOfProgress_ddCi() override
Calculate derivatives for net rates-of-progress with respect to species concentration at constant tem...
vector< vector< bool > > m_rxnPhaseIsProduct
Vector of vector of booleans indicating whether a phase participates in a reaction as a product.
void getDeltaGibbs(span< double > deltaG) override
Return the vector of values for the reaction Gibbs free energy change.
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:124
ThermoPhase & thermo(size_t n=0)
This method returns a reference to the nth ThermoPhase object defined in this kinetics mechanism.
Definition Kinetics.h:237
A class representing a network of connected reactors.
Definition ReactorNet.h:30
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