Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Reaction factory #745

Closed
wants to merge 9 commits into from
Closed

Conversation

ischoegl
Copy link
Member

@ischoegl ischoegl commented Nov 9, 2019

Changes proposed in this pull request

  • Add ReactionFactory in C++
  • Replace hard-coded instantiation and setup in C++ and Python
  • Remove magic numbers from Python interface

Approach

The main philosophy is to replace hard-coded reaction instantiation by an extendable ReactionFactory approach. None of this affects calculated outcomes. I.e. this PR repackages what's already there, with the difference that it becomes very simple to add additional reaction types.

Example: GasKinetics becomes fully flexible, i.e. someone can define a new reaction type externally and link it against cantera (ctwrap approach, where new C++ lambda functions are registered for an existing cantera factory object).

Implementation

  • Replace magic number referenced function calls by name-mapped C++ lambda functions calls (which are mainly used for setup; actual kinetics calculations involve templated functions, i.e. there is no change from the current implementation whatsoever)
  • C++ lambda functions recycle existing code directly

@codecov
Copy link

codecov bot commented Nov 9, 2019

Codecov Report

Merging #745 into master will increase coverage by 0.04%.
The diff coverage is 92.64%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #745      +/-   ##
==========================================
+ Coverage   71.54%   71.59%   +0.04%     
==========================================
  Files         372      374       +2     
  Lines       44348    44457     +109     
==========================================
+ Hits        31730    31829      +99     
- Misses      12618    12628      +10
Impacted Files Coverage Δ
src/kinetics/KineticsFactory.cpp 95% <ø> (ø) ⬆️
src/kinetics/importKinetics.cpp 97.6% <ø> (ø) ⬆️
test/kinetics/kineticsFromYaml.cpp 97.64% <ø> (ø) ⬆️
src/kinetics/Reaction.cpp 84.52% <ø> (-1.62%) ⬇️
include/cantera/kinetics/GasKinetics.h 100% <100%> (ø) ⬆️
include/cantera/kinetics/ReactionFactory.h 81.81% <81.81%> (ø)
src/kinetics/GasKinetics.cpp 96.9% <88.88%> (-1.57%) ⬇️
include/cantera/kinetics/Reaction.h 93.93% <88.88%> (-6.07%) ⬇️
src/kinetics/ReactionFactory.cpp 96.24% <96.24%> (ø)
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b74f11b...2c57527. Read the comment docs.

@ischoegl
Copy link
Member Author

ischoegl commented Nov 12, 2019

Stopping here as any additional changes would depend on #747 and #748 (and #749). PR is ready for feedback/review.

@decaluwe
Copy link
Member

@ischoegl Could you provide a brief bit of discussion here on what the approach/philosophy is, and how it differs from what is done (or is this already discussed, elsewhere)?

I see some changes in the ElectrochemicalReaction in 76d82a3, for instance, that don't exactly make sense to me, but I'd like to get a better sense of your overall approach here, and what the current approach is, before commenting. This obviously also relates to #749, so I'd like to get a handle on your recommended approach, here.

@ischoegl
Copy link
Member Author

ischoegl commented Nov 12, 2019

@decaluwe ... no problem. The main philosophy is to replace hard-coded reaction instantiation by an extendable ReactionFactory approach. None of this affects calculated outcomes. I.e. I'm just repackaging what's already there, with the difference that it becomes very simple to add additional reaction types.

  • GasKinetics is one case in point: it is now fully flexible, i.e. someone can define a new reaction type externally and link it against cantera (ctwrap approach, where new C++ lambda functions are registered for an existing cantera factory object). Same could be done for InterfaceKinetics & co. (although the existing code is more convoluted / harder to untangle).
  • Approach:
    • Replace magic number referenced function calls by name-mapped C++ lambda functions calls (which are mainly used for setup; actual kinetics calculations involve templated functions, i.e. there is no change from the current implementation whatsoever)
    • I ended up using C++ lambda functions to recycle existing code directly (instead of the first commit that used new virtual member functions)
    • Ideally, the reaction list should be non-hierarchical (i.e. no nested definitions like falloff)
  • The three things I came across are now YAML: consistently clarify reaction type #747, Refactor implementation of falloff reactions #748, and Discuss deprecating Butler-Volmer reaction types #749, where a minor update to the existing YAML syntax could simplify things quite a bit (i.e. making the implementation simpler to maintain/understand and also more future-proof regarding possible extensions)

PS: any existing XML files for additional electrochemical reaction definitions would be beneficial. From what I can tell, there are at least three different behaviors implemented (and accessible via XML), some of which are currently not reachable via YAML.

//! Vector of Reactions which follow the Butler-Volmer methodology for specifying the
//! exchange current density first. Then, the other forms are specified based on this form.
/*!
* Length is equal to the number of reactions with charge transfer coefficients, m_ctrxn[]
*
* m_ctrxn_BVform[i] = 0; This means that the irxn reaction is calculated via the standard forward
* and reverse reaction rates
* m_ctrxn_BVform[i] = 1; This means that the irxn reaction is calculated via the BV format
* directly.
* m_ctrxn_BVform[i] = 2; this means that the irxn reaction is calculated via the BV format
* directly, using concentrations instead of activity concentrations.
*/
std::vector<size_t> m_ctrxn_BVform;
//! Vector of booleans indicating whether the charge transfer reaction rate constant
//! is described by an exchange current density rate constant expression
/*!
* Length is equal to the number of reactions with charge transfer coefficients, m_ctrxn[]
*
* m_ctrxn_ecdf[irxn] = 0 This means that the rate coefficient calculator will calculate
* the rate constant as a chemical forward rate constant, a standard format.
* m_ctrxn_ecdf[irxn] = 1 this means that the rate coefficient calculator will calculate
* the rate constant as an exchange current density rate constant expression.
*/
vector_int m_ctrxn_ecdf;

@ischoegl
Copy link
Member Author

ischoegl commented Nov 14, 2019

After looking at this some more, I think this PR is ready for review as it stands.

Other comments that go beyond this PR:

@speth
Copy link
Member

speth commented Nov 18, 2019

One question I have is: Is there a good reason to implement a FalloffFactory? (it appears to be highly specialized.) I can see the point of factory classes to break things out for Python access, but it may make more sense to do this at a more generic RxnRatesFactory level?

Eliminating FalloffFactory sounds plausible to me. I doubt anyone is going to come up with an alternative falloff function without wanting more flexibility than this functional form provides. Making the reaction rate functions properly generic and more customizable is a bit more involved, given that there are at least perceived performance reasons for the less flexible way things are currently implemented using the Rate1 template class.

@ischoegl
Copy link
Member Author

@speth ... thanks for the comment: this is what I thought. I am aware of speed benefits of templates used for reaction rates (the dynamic classes appear to be used almost exclusively for setup).

Will most certainly not include anything else in this PR: I'd like to untangle the Python front end first (which is done), before anything else can get resolved in C++.

@ischoegl
Copy link
Member Author

@speth ... not sure whether you're considering this for 2.5, but the PR would be ready for review.

@ischoegl
Copy link
Member Author

@speth ... not sure whether this has legs or not (there may be other considerations that I’m not aware of). If this is a dead end, I’ll simply close this.

@ischoegl
Copy link
Member Author

Closing as this has been open and pending review for more than 6 months.

@ischoegl
Copy link
Member Author

A rebased branch remains on my fork on ischoegl:reaction-factories

@ischoegl
Copy link
Member Author

ischoegl commented Feb 20, 2021

Reopened as #982 (cannot reopen here as I rebased the branch after closing the PR).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants