Vibrational-relaxation from plasma treatment enhancements#2145
Vibrational-relaxation from plasma treatment enhancements#2145Gaetanosaure wants to merge 27 commits into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2145 +/- ##
==========================================
- Coverage 77.80% 77.62% -0.19%
==========================================
Files 452 455 +3
Lines 54332 55838 +1506
Branches 9111 9174 +63
==========================================
+ Hits 42275 43343 +1068
- Misses 9016 9443 +427
- Partials 3041 3052 +11 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@Gaetanosaure - before you go any further on making changes in this branch, let's get this rebased onto the current |
|
@speth ok let me try and do the rebase now, if I struggle too much I'll let you know! |
Add the VibrationalRelaxationRate class for vibrational relaxation reactions,
registered under the `vibrational-relaxation` rate type. It supports four
models: `multi-state-resolved` (detailed V-V/V-T relaxation with an SSH
harmonic-oscillator scaling of a base rate constant) and the
mean-vibrational-energy V-T relaxation models `constant`, `castela`, and
`starikovskiy`. See the class documentation for the governing rate expression
and references.
Also generalize TwoTempPlasmaRate with an optional gas-temperature exponent
`b-gas` (default 0, which recovers the Kossyi form); a non-zero value applies
the generalized k_f = A T^{b_g} T_e^b exp(-Ea_g/RT) exp(Ea_e(Te-T)/(R T Te))
expression.
…ional reservoir species Detect fictive vibrational-reservoir species (named "X(v)") and warn when the corresponding base species "X" is missing, or when the reservoir mole fraction grows into a non-negligible fraction of the base species -- a sign that the chosen reservoir energy is too low and is perturbing the chemistry.
9d525fc to
54d996b
Compare
|
@speth the rebase should be clean now. Let me know if you notice anything strange but I think i managed to do it properly. |
…pression completely. The minus sign will be born by YAML coefficients directly.
…iny declaration error
|
Hi @speth , after going through your comments on the code of the previous PR I tried to imagine the comments you would have done on the code of the present PR, and thus tried to enhance it as much as possible. Hopefully that will reduce your workload while processing this part of the integration (although it is very likely far from perfect). I believe I have gone as far as possible without your input, please tell me if you have any questions and let me know if I should do any further code modifications. I would just like to emphasise that I have thought of this class as a container for all possible vibration models that could be later included in addition to the four already present. This is the reason for the parameter vibration-model: avoiding declaring a new reaction class every time a new vibration relaxation implementation is required. I thus tried to make it as modular as possible in the way it is organised. The 'constant' option is redundant with a simple Arrhenius, but I find it interesting for the user to still be able to classify it as vibrational relaxation. If you think it should not be included we can get rid of it. |
|
@Gaetanosaure This looks clean and easier to review! Can you clarify if number 5. Implemented a new format for the YAML files ... is still in this PR or will be in this PR? |
|
Hi @BangShiuh ! Thanks for going through this bit of code as well. Yes it will be but for more clarity and to make the review process easier we broke down the first big pull request (#2121) into three smaller ones. The first chunk was chunk integrated last week: #2144 The second chunk is the present one on vibrational treatment, and then the last points (the main being taking into account the effective / elastic difference and changing the YAML format) will be done on a third one not yet opened because it depends on the prior implementation of the two other PRs. |
…spellings and added getParameters function
|
Hi @speth and @BangShiuh , I added a second extension to the TwoTemperaturePlasmaRate class that allows to take into account more plasma reactions via the parameter T-inv. This can serve for example in the case of R40 (Capitelli book Table 10.7): |
|
@Gaetanosaure Extending the TwoTemperaturePlasmaRate class is fine to me. I prefer a separate PR for it because this is a distinguish change. The better we document the change the less problems in the future. Also I see you use images showing the code / format in the PR description. This is not idea because it can hinder finding / maintaining the information. (also AI read text better.) I don't see code change for 5. so I assume you will do something about it? |
|
Hi @BangShiuh , yes indeed as I said in my answer to your first message point 5 will be integrated in a later PR separate from the present one. If you are interested in this point specifically I can notify you once it is open (that I, once the present one will be resolved). I think there was a slight mix up between the commit splitting @speth did and the way I understood them, as a result the description of this PR is misleading in the sense that we are actually integrating the changed to the kinetics classes here: vibrational relaxation and TwoTempPlasmaRate. Handling of effective/elastic cross sections and accompaniying changes will be handled in the next PR building on this one. |
|
I have updated the PR description to make it match the changes actually in the commits |
speth
left a comment
There was a problem hiding this comment.
Thanks for splitting this off, from the other changes, @Gaetanosaure. I have a number of suggestions for improving this implementation. Besides the specific in-line comments, to broader notes:
-
The main description of the new rates (formulas, concept, references) should be added in
doc/sphinx/reference/kinetics/rate-constants.md. I'd suggest that much of what's in the C++ class documentation would be more accessible as part of this scientific reference documentation than buried in the Doxygen documentation, with the focus for Doxygen more on any implementation details. The YAML documentation indoc/sphinx/yaml/reactions.mdshould link to the section in the "reference" docs and focus on just describing the input fields, though repeating the equation is okay. -
The major missing piece in this PR currently is any tests whatsoever. I'm not quite sure how this interacts with the other upcoming changes to the input format for electron collisions, but rather than deferring this, I think it would be worth adding some bare-bones inputs that can be used now in
test/data. To parallel the existing test structure for reaction rates, there should be new tests of both pure-C++ construction (kineticsFromScratch.cpp), YAML-based construction (kineticsFromYaml.cpp) and the Python-based pathways (test_reaction.py). If you have any issues with the tests (the Python suite can be a bit tricky to debug) just give me a shout.
| (sec-vibrational-relaxation-constant-rate)= | ||
|
|
||
| ### Vibrational relaxation: constant | ||
|
|
||
| The `constant` vibrational relaxation rate expression is |
There was a problem hiding this comment.
I think it would be better to describe all of these variants further down, with the vibrational-relaxation reaction type. The Arrhenius and Blowers-Masel description were separated out because those parameterizations can be used in multiple different reaction types, whereas this is only used for the one reaction type. Probably having the two-temperature plasma rate expression explained up here is also a bit of organizational mistake.
| No other rate parameters are allowed for this model. In particular, `b`, `n`, `B`, | ||
| `C`, `D`, `m`, `E`, `z`, and `scaling` are not permitted. |
There was a problem hiding this comment.
I think the second statement here is unnecessary. Besides the redundancy, none of these other parameters have been introduced, so there's really nothing that would lead a user to imagining that they could be used. Likewise the corresponding statements for the other model options.
| `scaling` | ||
| : Dimensionless multiplicative scaling factor applied to the rate coefficient. | ||
| Defaults to 1.0. |
There was a problem hiding this comment.
I don't understand the purpose of this parameter, if we already have A.
| + C T^{-1/3} | ||
| + D T^{-2/3} | ||
| \right) | ||
| $$ |
There was a problem hiding this comment.
This is a bit excessive for splitting an equation onto multiple lines.
|
|
||
| ### Vibrational relaxation: castela | ||
|
|
||
| The `castela` vibrational relaxation rate expression is based on the relaxation time |
There was a problem hiding this comment.
We capitalize proper nouns in YAML names:
| The `castela` vibrational relaxation rate expression is based on the relaxation time | |
| The `Castela` vibrational relaxation rate expression is based on the relaxation time |
(so, likewise for Starikovskiy)
| const string ModelConstant = "constant"; | ||
| const string ModelMultiState = "multi-state-resolved"; | ||
| const string ModelStarikovskiy = "starikovskiy"; | ||
| const string ModelCastela = "castela"; |
There was a problem hiding this comment.
This is less clear than just writing these names in the handful of places where they are used.
| enum class VibModel { | ||
| Constant, | ||
| MultiStateResolved, | ||
| Starikovskiy, | ||
| Castela | ||
| }; |
There was a problem hiding this comment.
The pattern where this enum is used is needlessly complex. Since it's not in the hot path of the reaction rate evaluation, you would be better off just having the sequential
if (model == "constant") {
...
} else if (model == "multi-state-resolved") {
...
} ...block in each case. The only one that needs to handle the exceptional case of an undefined model is setParameters.
| const AnyMap& getRateConstantMap(const AnyMap& node) | ||
| { | ||
| if (!node.hasKey("rate-constant")) { | ||
| throw InputFileError(WhereSetParameters, node, | ||
| "A vibrational-relaxation reaction requires a 'rate-constant' " | ||
| "mapping."); | ||
| } | ||
|
|
||
| const auto& rate = node["rate-constant"]; | ||
|
|
||
| if (!rate.is<AnyMap>()) { | ||
| throw InputFileError(WhereSetParameters, node, | ||
| "The 'rate-constant' field must be a mapping."); | ||
| } | ||
|
|
||
| return rate.as<AnyMap>(); | ||
| } | ||
|
|
There was a problem hiding this comment.
What's the exception message given if the rate-constant node is missing normally? I'm not sure it's so bad that all this extra checking is worthwhile.
| switch (parseVibrationModel(m_vibration_model, node, WhereGetParameters)) { | ||
| case VibModel::Constant: | ||
| getConstantParameters(node, rateNode); | ||
| break; | ||
| case VibModel::MultiStateResolved: | ||
| getMultiStateParameters(rateNode); | ||
| break; | ||
| case VibModel::Starikovskiy: | ||
| getStarikovskiyParameters(rateNode); | ||
| break; | ||
| case VibModel::Castela: | ||
| getCastelaParameters(node, rateNode); | ||
| break; | ||
| } |
There was a problem hiding this comment.
These hidden helper functions for different variations on the reaction type are telling me that this should probably be implemented as a family of four different derived classes, using just a single type string to distinguish each one, instead of having both a type and vibration-model as a "sub-type". If this was only true in one place, I'd say we could leave it, but this pattern repeats several times -- here for getParameters, then again for setParameters and setContext (validation). You can leave all the common infrastructure implemented in the intermediate VibrationalRelaxationRate class, at which point the specific classes should just have implementations of these few specific methods.
| if (std::abs(m_b - 1.0) > VibTolerance | ||
| || std::abs(m_D) > VibTolerance | ||
| || std::abs(m_E) > VibTolerance | ||
| || std::abs(m_scaling - 1.0) > VibTolerance) | ||
| { | ||
| throw InputFileError(WhereGetParameters, node, | ||
| "Cannot serialize this rate as 'castela': the internal " | ||
| "parameters are not consistent with the Castela form. " | ||
| "Expected b = 1, D = 0, E = 0, and scaling = 1."); | ||
| } |
There was a problem hiding this comment.
It really shouldn't be necessary to do validation at the output stage -- there shouldn't be a code path by which these parameters take on invalid values. If these parameters had incorrect values before this, then there must have been rate calculations that were being done incorrectly.
Changes proposed in this pull request
This PR proposes to implement the point 6 from the former pull request plasma treatment enhancements. I write it here again for reference:
However, depending on the chosen model, all parameters are not required and some default values are applied.
This PR also incorporates some modifications to TwoTempPlasmaRate that were done in the previous PR without having a particular number.
Closes #2144
AI Statement (required)
Standard or boilerplate code snippets were generated with AI and manually reviewed;
all design, logic, and implementation decisions were made by the contributor.
Examples: IDE code-completions or brief LLM queries for common patterns.