From 51f419fbadef27d318f249c447400a1618a6d151 Mon Sep 17 00:00:00 2001 From: Steven DeCaluwe Date: Mon, 13 Feb 2017 09:53:41 -0700 Subject: [PATCH] Enabling charge-transfer/electrochemical surface reactions The previous formulation will only consider a rection as electrochemical if a beta value is supplied for that reaction *and* the reaction is an 'edge_reaction.' This is problematic for two reasons: (1) many/most charge-transfer reactions of interest occur at two-phase boundaries (see, for example, Li-ion batteries and PEM fuel cells), not the three-phase- boundary-like edges (which are most relevant for SOFCs). (2) determining whether a reaction is electrochemical or not should not rely at all upon user input - the program itself should check to see whether charge is transferred between phases, and the appropriate steps should be taken during rate-of-progress calcuations. This commit addresses the former issue. Currently, if a charge-transfer reaction is written as a surface_reaction, the code does not apply the voltage correction to the forward rate. By default, then, the entire voltage correction is applied to the reverse reaction, which is the same as setting beta = 0; not a good 'default' behavior (beta = 0.5 is a more appropriate default). With this change, surface reactions can now be supplied with a beta value in cti or xml formats, and will be recognized as a charge transfer reaction. Longer term, it would be better to change the constructor routines such that charge transfer is automatically detected and handled, rather than relying upon user-specified flags. --- interfaces/cython/cantera/ctml_writer.py | 12 ++++++++++-- src/kinetics/Reaction.cpp | 7 ++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/interfaces/cython/cantera/ctml_writer.py b/interfaces/cython/cantera/ctml_writer.py index 6ff2c327d..d9a9da365 100644 --- a/interfaces/cython/cantera/ctml_writer.py +++ b/interfaces/cython/cantera/ctml_writer.py @@ -1296,7 +1296,7 @@ class reaction(object): elif self._type == 'chebyshev': self._kf = [] - if self._type == 'edge': + if self._type == 'edge' or self._type == 'surface': if self._beta > 0: electro = kfnode.addChild('electrochem') electro['beta'] = repr(self._beta) @@ -1605,7 +1605,8 @@ class surface_reaction(reaction): A heterogeneous chemical reaction with pressure-independent rate coefficient and mass-action kinetics. """ - def __init__(self, equation='', kf=None, id='', order='', options=[]): + def __init__(self, equation='', kf=None, id='', order='', beta = 0.0, + options=[]): """ :param equation: A string specifying the chemical equation. @@ -1625,9 +1626,16 @@ class surface_reaction(reaction): reaction in the file. :param options: Processing options, as described in :ref:`sec-reaction-options`. + :param beta: + Charge transfer coefficient: A number between 0 and 1 which, for a + charge transfer reaction, determines how much of the electric + potential difference between two phases is applied to the + activiation energy of the fwd reaction. The remainder is applied to + the reverse reaction. """ reaction.__init__(self, equation, kf, id, order, options) self._type = 'surface' + self._beta = beta class edge_reaction(reaction): diff --git a/src/kinetics/Reaction.cpp b/src/kinetics/Reaction.cpp index 0410a1dcf..470e4de3e 100644 --- a/src/kinetics/Reaction.cpp +++ b/src/kinetics/Reaction.cpp @@ -605,9 +605,10 @@ shared_ptr newReaction(const XML_Node& rxn_node) { std::string type = ba::to_lower_copy(rxn_node["type"]); - // Modify the reaction type for edge reactions which contain electrochemical - // reaction data - if (rxn_node.child("rateCoeff").hasChild("electrochem") && type == "edge") { + // Modify the reaction type for interface reactions which contain + // electrochemical reaction data + if (rxn_node.child("rateCoeff").hasChild("electrochem") + && (type == "edge" || type == "surface")) { type = "electrochemical"; }