Make rate constant calculation consistent with Kee, et al.#1084
Make rate constant calculation consistent with Kee, et al.#1084speth merged 8 commits intoCantera:mainfrom
Conversation
Codecov Report
@@ Coverage Diff @@
## main #1084 +/- ##
=======================================
Coverage 73.45% 73.45%
=======================================
Files 362 364 +2
Lines 47554 47611 +57
=======================================
+ Hits 34929 34972 +43
- Misses 12625 12639 +14
Continue to review full report at Codecov.
|
|
I guess this needs to be expanded to |
73517f1 to
7003ffa
Compare
The previous implementation does not follow textbook definitions (e.g. Kee/Coltrin/Glarborg, Chemically Reacting Flow, Eqs. 9.73 and 9.75). The revised implementation is consistent with Eq. 9.75 and multiplies the effective third-body concentration only for the calculation of rates-of-progress. Falloff reactions are a separate case as they use a modified rate constant, which does include third-body concentrations.
4902800 to
8203c3d
Compare
There was a problem hiding this comment.
Thanks for putting this together, @ischoegl. I agree that, even if few are likely to run into it, having the reported rate constants match the established convention is a better outcome. Certainly we've run into a few users just in the past few months, trying to verify Cantera's approaches, compared to literature approaches, so I don't think this is just academic.
Anyway, from your report, the implementation looks pretty straightforward, and you seem to have a good method in place (via the use_legacy methods and flags) to handle the transition. Just so I'm sure I understand:
-Is the idea to switch the default for use_legacy_rate_constants to true, starting with Cantera 2.6?
- Do you intend for the
use_legacy_ratesfunctionality to be a permanent feature? - in
base/global, you haveboolvalues defined foruse_legacy_rate_constantsandlegacy_rate_constants_used--do I understand correctly that the former is the "set" method, whereas the latter is the "get?"
Anyway, I'm generally in favor of this change. The only thing I'd like to see is a simple unit test demonstrating the switching back and forth between legacy and non-legacy, as you have in your PR message, and confirming that they each match theory.
The one comment from @bryanwweber's original reply that hasn't really yet been addressed: can you point to any other theory or textbook, besides Kee, which says this is the authoritative approach? I tend to agree that the approach you suggest is more intuitive, but it is not that black and white, for me - I would not be surprised if others came down on the other side of the fence. I'd certainly like to have a better picture of how this theory has, historically been implemented.
03b9b5f to
950952d
Compare
|
@decaluwe ... thanks for your positive feedback. Regarding literature: Kee just happens to have an equation that is most clear-cut, but other texts are pretty consistent in treating
So, I believe Cantera's inclusion of Fwiw, CHEMKIN is consistent with Kee (perhaps not suprisingly): "When a third body is needed, the concentration of the effective third body must appear in the expression for the rate-of-progress variable. ", see Eq. 3-18 (Chemkin 17.0). Regarding other questions:
It would be
I think the feature can remain, as it's pretty simple to switch. If there's a consensus to remove (after Cantera 2.7/3.0), that would be fine also.
This is correct. I used the same terminology as the preexisting PS: beyond, I compiled the MATLAB extension in the meantime and fixed a minor glitch. PPS: just saw that you commented also @bryanwweber ... at this point, I believe it's up to @speth to weigh in. Fwiw, this plays into Cantera/enhancements#87, where the status of |
|
Thanks, @ingmar - note that I accidentally wrote @bryanwweber, can we discuss your reservations a bit more? I'm not really keen on steamrolling over your concerns. To consolidate the convo, you listed:
Agree with @ischoegl, though -- I'd like to hear @speth weigh in, since there is still disagreement. |
😆 ... to me personally, this always looked like a bug, and - at least to me - it looks wrong enough to be worth fixing; it's not the first time I stumbled across this implementation. Looking over references today confirmed that my recollections square with what I believe the theory says. There may be some other references, but what I listed in my previous post corresponds to my go-to references on my bookshelf. Unfortunately, I don't have Gardiner on hand, but I'd frankly be surprised if it said anything different (lumping the Now, there may be one addition that may facilitate a decision to adopt what I believe is the correct implementation: at the moment, there is no interface to query third-body concentrations outside of C++ (which makes it rather hard to calculate anything based on collision efficiencies). I'd be happy to add this feature to this PR ... |
|
Thanks @decaluwe and @ischoegl. I can provide some more thoughts, as they've evolved over the last few days of thinking about this:
One last thought I had in terms of the why is that it may simplify calculations for other phase types where |
|
@bryanwweber ... thanks for your additional comments.
I respectfully disagree here. I believe at this point we can all agree that Cantera output goes against accepted standards. I simply don't see a reason why we should cling to a 'feature' (aka bug) that can be fixed. I believe that the proposed deprecation would take care of it once and for all, instead of assuming that users will read the 'fine print' (which they usually don't). To @decaluwe's point, I believe most people don't even realize that the output is not what they would expect. Regarding virtual vs concrete: the current implementation of |
Thanks @ischoegl, I'm happy to respectfully agree to disagree, at least until we figure out why this is the way it is (if we ever do) 😄 I certainly see all your points, and I think you're making a strong argument. I'm just personally balancing it a little different way, which is why we have a team to work on this! |
speth
left a comment
There was a problem hiding this comment.
Thanks all, for the thorough discussion of the issues at hand here.
My initial take on this discrepancy was that the simplest fix would be to just define the rate constant for a three-body reaction as including the effective third body concentration. However, it seems that this is not a quantity of much particular interest, and doing so would be at odds with quite a few textbook descriptions of three-body reactions.
I sort of expect that most use of the get_forward_rate_constants function is done in a way where either the users are expecting the textbook definition and currently getting the wrong answer, or doing something where it doesn't really matter whether the third body concentration is included, like plotting them as a function of temperature. In any case, making the current behavior the default for the next version, with copious documentation of the upcoming change (as implemented in this PR) and then still having the flag to keep the old behavior in the following version is about the best we can do. I don't think history is enough of a reason not to change this. And there's something to be said for aligning the breaking change here with the 3.0 release, from a semantic versioning standpoint.
One wrinkle, related to Cantera/enhancements#87, is that if we kept the third-body term as part of the rate constant, that calculation could be folded into a particular ReactionRate class, such that there would eventually be no special behavior associated with the GasKinetics class and BulkKinetics would just be the generic Kinetics manager for all bulk phases. I don't know if there's a way to still achieve this while still making the rate constant definition textbook-consistent.
In any case, I'm 👍 on this change in general, and only had a few minor suggestions on the implementation.
|
Thanks @speth! My concerns are resolved then. |
|
Thank you @speth, @decaluwe and @bryanwweber for your inputs on this, even if we couldn't find complete consensus. Based on @speth's review, I edited all docstrings as well as the warning message, which now reads: Among the interfaces, Fortran is the only one where the switch isn't available: I haven't coded in Fortran since the mid 90's (last millenium!), so I probably shouldn't try. @bryanwweber ... I hope I hit the mark in my deprecation message and docstring phrasing (I may not be the best word-smith). If you (or anyone else) should have suggestions for improvement, I'd be happy to incorporate. |
171baf7 to
0766a35
Compare
|
Thanks @ischoegl the message looks good to me. Will this be produced every time One other comment, and I suppose this applies to all the |
|
@bryanwweber ... thanks for looking over the messages: this is much appreciated! Per your questions:
No, only the first time after each launch of Cantera. For subsequent calls, the deprecation warnings are suppressed.
That's a really interesting question, and yes, this would go well beyond this PR. It would be great to establish this interface (for any warning), but I don't think that this is a simple endeavor as C++ doesn't come with a warning framework like Python (from what I understand, there are some C++ loggers out there to differentiate exception levels, but that's not the issue I believe). In terms of translating warnings to Python, I am not entirely sure how this would work: as no exceptions are raised that can be caught, any Cython call into C++ would probably have to trigger a query whether there are some buffered logging messages (?) ... I am mostly speculating here as details go well beyond my level of familiarity. @speth has probably more insights here ... |
I think this would require something a bit like how we interface with Python for writing messages to |
|
@speth - thanks for the feedback/review!
I actually pre-empted this by a discussion here: Cantera/enhancements#112. Good to hear that there may be an easier route! |
Changes proposed in this pull request
The current implementation of
GasKinetics::getFwdRateConstantsis not consistent with textbook definitions (see Eq. 9.75 in Kee, Coltrin and Glarborg, Chemically Reacting Flow). An implementation consistent with Eq. 9.75 multiplies the effective third-body concentration only for the calculation of rates-of-progress. Falloff reactions are a separate case as they use a modified rate constant, which does include third-body concentrations.As implemented, the calculation is separate from
updateROP(i.e. no change from previous approach). The affected methods mainly serve informational purposes (see comment inBulkKinetics::getRevRateConstants), so there is no expected impact on performance.The deprecation uses a global flag to make a transition minimally intrusive. This is important, as rate constants are used extensively in the test suite.
If applicable, fill in the issue number this pull request is fixing
Closes #1083
If applicable, provide an example illustrating new features this pull request is introducing
The proposed change deprecates the old behavior and includes a global switch to facilitate the transition:
This change further clarifies a current discrepancy between outputs of
ReactionRateandforward_rate_constantsfor three-body reactions, e.g.Checklist
scons build&scons test) and unit tests address code coverageAdditional thoughts
The default behavior would presumably switch to the standard definition with Cantera 3.0. There is no reason to remove the flag at that point in case there should be concerns about back-ward compatibility of existing scripts.
Further context
The current definition affects temperature derivatives for the calculation of Jacobians (e.g. #1081), where a spurious dependency is created due to the inclusion of
Mconcentrations in the rate constant calculation.