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

Improve handling of transport_model="None" #1131

Closed
ischoegl opened this issue Oct 23, 2021 · 4 comments · Fixed by #1129
Closed

Improve handling of transport_model="None" #1131

ischoegl opened this issue Oct 23, 2021 · 4 comments · Fixed by #1129

Comments

@ischoegl
Copy link
Member

ischoegl commented Oct 23, 2021

Problem description

In the current implementation, specifying a transport model of "None" (C++) or None (Python) prevents the instantiation of a transport manager object, with various internal pointers being set to NULL. At least in Python, there is a band-aid in place to make handling safe (using a newDefaultTransportMgr), but this sometimes fails - see example below. Also, it is not ideal to display transport_model = ‘Transport’, where the meaning is not clear to a user.

A safer implementation would use an empty Transport object (similar to a Kinetics object with zero reactions added). A Solution object with no Transport created in C++ is unsafe as it contains NULL as the Transport reference.

Steps to reproduce

The following should create equivalent objects (using mock_ion.xml, which does not include reactions):

In [5]: _ = ct.ThermoPhase("mock_ion.xml")

In [6]: _ = ct.Solution("mock_ion.xml", transport_model=None)
---------------------------------------------------------------------------
CanteraError                              Traceback (most recent call last)
<ipython-input-6-5d233d73507d> in <module>()
----> 1 _ = ct.Solution("mock_ion.xml", transport_model="None")

/src/interfaces/cython/cantera/thermo.pyx in cantera._cantera.ThermoPhase.__init__()
    301     # The signature of this function causes warnings for Sphinx documentation
    302     def __init__(self, *args, **kwargs):
--> 303         super().__init__(*args, **kwargs)
    304         if 'source' not in kwargs:
    305             self.thermo_basis = mass_basis

/src/interfaces/cython/cantera/transport.pyx in cantera._cantera.Transport.__init__()
    175                 if not model:
    176                     model = 'None'
--> 177                 self.transport = newTransportMgr(stringify(model), self.thermo)
    178             self._transport.reset(self.transport)
    179 

CanteraError: 
*******************************************************************************
CanteraError thrown by IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions:
neutral molecule calc error - anion
*******************************************************************************

Behavior

While the former will prevent Kinetics and Transport methods from being called, the second command should result in an equivalent object with appropriate error handling if a user attempts to access transport properties.

System information

  • Cantera version: 2.6
  • OS: any
  • Python/MATLAB/other software versions: Python 3.6.9

Other thoughts

  • Prior to the implementation of Solution.h, there was no central object managing Transport (making this less of an issue)
  • KineticsFactory does include an empty object, but there is no obvious way to reach it
  • The issue surfaced in Read YAML using C++ newSolution in Python / access root level data #1129: the same complication becomes apparent in the C++ interface
@ischoegl
Copy link
Member Author

ischoegl commented Oct 24, 2021

A secondary observation is the following:

In [1]: import cantera as ct

In [2]: gas = ct.Solution("h2o2.yaml", transport_model=None)

In [3]: gas.input_data
Out[3]: 
{'elements': ['O', 'H', 'Ar', 'N'],
 'kinetics': 'gas',
 'name': 'ohmech',
 'species': ['H2', 'H', 'O', 'O2', 'OH', 'H2O', 'HO2', 'H2O2', 'AR', 'N2'],
 'state': {'T': 300.0, 'Y': {'H2': 1.0}, 'density': 0.08189392763801234},
 'thermo': 'ideal-gas',
 'transport': 'mixture-averaged'}

Here, the expectation would be to see transport being either None or omitted. Further, the following is not what is expected:

In [6]: gas.transport_model
Out[6]: 'Multi'

In [7]: gas.input_data
Out[7]: 
{'elements': ['O', 'H', 'Ar', 'N'],
 'kinetics': 'gas',
 'name': 'ohmech',
 'species': ['H2', 'H', 'O', 'O2', 'OH', 'H2O', 'HO2', 'H2O2', 'AR', 'N2'],
 'state': {'T': 300.0, 'Y': {'H2': 1.0}, 'density': 0.08189392763801234},
 'thermo': 'ideal-gas',
 'transport': 'mixture-averaged'}

@bryanwweber
Copy link
Member

Further, the following is not what is expected:

In [6]: gas.transport_model
Out[6]: 'Multi'

In [7]: gas.input_data
Out[7]: 
{...
 'transport': 'mixture-averaged'}

I'm not sure I agree that this is unexpected. Depending on your definition of "input", you might expect it to remain 'mixture-averged' which was set by the input file (presuming that that case was working properly 😛 ).

@ischoegl
Copy link
Member Author

ischoegl commented Oct 25, 2021

Based on the docstring, it is unexpected, as it refers to the current state 😉

property input_data:
"""
Get input data corresponding to the current state of this Solution,
along with any user-specified data provided with its input (YAML)
definition.
"""

The way it is currently implemented, this isn't meant to guarantee round-trip conversion. The method name is probably a bit ambiguous, as discussed in #984 (and documented in #1053).

@bryanwweber
Copy link
Member

Based on the docstring, it is unexpected, as it refers to the current state 😉

Ha! Fair enough 😄 I thought we had discussed this before, I just couldn't remember where. Thanks for the links!

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

Successfully merging a pull request may close this issue.

2 participants