Closed ischoegl closed 4 years ago
Spent parts of three days debugging this... man, this was tricky. The intermediate cause appears to be because the thermo phases are stored in a different order inside the kinetics object for YAML vs. CTI files. This means that the order of species in the internal arrays is different, which results in a different rates of production. This cause can be verified by changing the order of the ThermoPhase
arrays in the _SolutionBase.__cinit__()
method:
if isinstance(self, Kinetics):
for phase in adjacent:
# adjacent bulk phases for a surface phase
v.push_back(phase.thermo)
v.push_back(self.thermo) # Move this after the adjacent phases to fix the example
With that change, both surf_pfr.py
and catalytic_combustor.py
work again.
I don't believe this is the root cause, or the appropriate fix, because the underlying calculation of the rates of production is intended to be independent of the order that phases are added. More digging is required to find where this assumption is violated in the current code.
Debugging details follow, just in case anyone finds it interesting, and also because I'm so frustrated at how long this took that I want to write it all out!
ThermoPhases
stored within each of the surface kinetics objects were in different orders. I verified this by accessing the `Interface._phase_indices` property in Python, which showed that the `Surf` and `IdealGas` phases indeed had different internal indices.
Actually, I found that the `_phase_indices` property was different between the two input files by writing a loop in Python to assert that each property of the `Interface` instance was equal.
The last debugging step so far was to check the change I mentioned earlier, and put the `Surf` phase second, to match how the CTI file is initialized. Interestingly, even though the CTI initializer in Python has the same code that the YAML file does, the C++ code re-runs the loop, since the XML definition must list the associated phases, see:
https://github.com/Cantera/cantera/blob/cf1c0816e7d535a1fc385063aebb8b8e93a85233/src/kinetics/importKinetics.cpp#L155-L160
:+1: whoa ... that indeed sounds like a tricky one to track down! It’s really surprising that this hadn’t come up thus far, and it was curious to find that switching things back to CTI appeared to ‘fix’ things ... anyhow, kudos.
Problem description
The switch from
methane_pox_on_pt.cti
tomethane_pox_on_pt.yaml
input apparently broke the Python examplesurf_pfr.py
(see original issue report #877).Edit: The example
catalytic_combustion.py
is affected by a closely related issue (see #873).Steps to reproduce
A run of the Python example
surf_pfr.py
currently fails (see #877). Switching from YAML back to CTI input restores the old behavior. It can be easily verified that re-creating YAML usingcti2yaml
does not fix the issue. The same issue also arises if the original file is converted from XML (viactml_writer
andctml2yaml
).Behavior
Time integration reduces CO levels to negative values until the density itself becomes negative and an error is raised (see #877), which appears to be either due to a faulty
cti2yaml
/ctml2yaml
conversion of reaction parameters, or a faulty initialization of a cantera object from YAML. The context points at an issue with surface reactions.System information
Additional context
877 (superseded by this issue report)
873 (superseded by this issue report)
The behavior became apparent after 1866e35 which switched example input files to YAML.