-
-
Notifications
You must be signed in to change notification settings - Fork 348
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
Create SolutionBase object in C++ #696
Conversation
Codecov Report
@@ Coverage Diff @@
## master #696 +/- ##
==========================================
- Coverage 70.63% 70.61% -0.02%
==========================================
Files 372 374 +2
Lines 43567 43590 +23
==========================================
+ Hits 30773 30783 +10
- Misses 12794 12807 +13
Continue to review full report at Codecov.
|
2157d79
to
5dbaca2
Compare
037f2d0
to
8066333
Compare
0c51834
to
cb6ec03
Compare
cb6ec03
to
28de738
Compare
I had some some high-level comments on this, which it might be worth discussing before going further on the implementation of this. I'll provide a more detailed review once we work out the big picture. I'm coming around to the idea that a class of this sort would be useful, especially for the second capability you mentioned, where it would serve as the thing that can be serialized to a YAML phase definition. Regarding the name / ID / phase attributes: Despite the description of this in I don't quite understand why the Why is this new class
Perhaps I'm missing something, but I don't think C++ copy constructors are useful for parallel processing. They only provide a way of copying an object within the memory space of a single process, which doesn't help with transmitting objects to other parallel processes (but of course, YAML
I'm not sure I follow - in Python, the creation of all the underlying C++ objects is done in |
@speth ... thanks for your comments! I agree that a high-level discussion is warranted before it makes sense to start a detailed review.
👍 Really happy to hear!
My opinion on this is that within the context of serialization,
It's the last: defer until later. In the current implementation, there isn't a need, as I mainly looked into the plumbing from Python back to C++. I am anticipating that the object could become important in C++ as a one-stop shop access point for various managers, where this type of access would become essential.
My main rationale here was to directly map python nomenclature back to C++. Honestly, I have thought about (ultimately) renaming
Could be, but we don't know how users may deploy the Cantera code in custom applications. At some point, I had started looking into wrapping Cantera into |
PS: ad C++ ramifications. If this object were to be adopted for use within the C++ layer, additional thought needs to go into factories, etc.. I didn't want to go there with this PR (and doubt that it needs to be added immediately). Ultimately, I think that an almost exact replication of object structures in Python and C++ would benefit maintenance and simplify overall understanding (figuring out where managers are actually instantiated took a while). |
There's no file in Cantera named
I think the challenge in figuring out where things are in the C++ layer is more an indication that how Cantera objects are created in C++ is currently a bit of a mess. While some general correspondence of C++ and Python features is useful, I think we shouldn't expect one language interface to be just a transliteration of the other. Doing that just ends up with each interface being the worst of both worlds based on the limitations of each language and fitting in as part of an idiomatic Python or C++ application. And this quickly becomes unmanageable if you consider additional language interfaces. |
My bad 🤦♂️ : it's been a while since I submitted the PR. The (potential) renaming conflict I was recalling was
🤣 Well, I would have called it 'challenging'. It works well, but it is not straight-forward.
I do agree on your comments about exact replications, but as far as PS: Cython currently not supporting diamond inheritance (I believe this is still true) is one good example where exact replication is limiting. In this context, I also don't think it to be necessary (nor useful) to replicate the diamond structure in |
@speth ... Thought about it some and am 👍 with defining PS: an alternative would be to just call those objects |
* Add Base.h/Base.cpp with definition of SolutionBase * Link C++ object into Cython interface * Add unique_name and type attributes to Cython _SolutionBase
* Resolve conflation of gas.ID and gas.name in unit tests * Also fixes Cantera#691
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned before, I'm satisfied that a composite class of some sort will provide a useful interface for serialization, as well as a few other purposes.
I think I'd like to defer the resolution of these issues relating to the multiple name-like attributes and whether they need to be unique until we start to flesh out the serialization interface.
I was trying to avoid dragging this into this PR, but I was reminded of this capability while reviewing your earlier PR on enabling case sensitivity in species names. I believe that these latter two methods are not actually in use within Cantera, and I'm really not sure that we need or want them. For multiphase mixtures (C++ class |
@speth ... thanks for the prompt review! I think most of your comments are addressed, but I left things that may need further discussions unresolved.
This makes sense. I wasn't really questioning the use, just trying not to break anything 😉 ... it certainly affects the PR, as both |
Hi @ischoegl... sorry to jump in late (again), I just wanted to add my 2 cents on the distinction between
To me, |
@bryanwweber ... from /*! @name Name and ID
* Class Phase contains two strings that identify a phase. The ID is the
* value of the ID attribute of the XML phase node that is used to
* initialize a phase when it is read. The name field is also initialized
* to the value of the ID attribute of the XML phase node.
*
* However, the name field may be changed to another value during the
* course of a calculation. For example, if a phase is located in two
* places, but has the same constitutive input, the IDs of the two phases
* will be the same, but the names of the two phases may be different.
*
* It is an error to have two phases in a single problem with the same name
* and ID (or the name from one phase being the same as the id of
* another phase). Thus, it is expected that there is a 1-1 correspondence
* between names and unique phases within a Cantera problem.
*/
This is the current (intended) behavior of this PR 😉 ... |
The option --phase is consistent with the resulting yaml entry in 'phases'. The --id option is still supported, with a warning being issued.
6c85968
to
5932a24
Compare
@bryanwweber ... copying some thoughts over here: I view the Finally, I believe the differentiation suggested by this PR is consistent with other Cantera interfaces (i.e. there is a long tradition of the keyword argument |
Ugh. It looks like I force-pushed a stale branch, losing most of my updates over the last couple of days. I don't think that I have the work elsewhere, so I'll have to retrace. |
🎉 retraced all changes that were lost in a force-push. |
* rename C++ object to 'Solution' (from 'SolutionBase') * remove 'phaseID' from 'Solution' ('id' remains assigned to 'Phase') * remove 'type' from C++ object (no polymorphism anticipated) * assign 'name' to 'Solution' (link back from 'Phase' until deprecated) * clarify 'phase' as 'phase_id' in Python interface * address various feedback in review comments
a5b6c8e
to
02175a3
Compare
To add an alternative approach (following a discussion with @bryanwweber): instead of trying to enforce I.e. use I guess I am finally coming around. I still would like to use this opportunity to ensure that the naming convention is being used consistently. The change is not overly complicated ... |
* 'name' corresponds to the YAML entry * rename Solution keyword 'phaseid' to 'name' (instead of 'phase_id') * rename ck2yaml argument '--id' to '--name' (instead of '--phase-id') * ensure that C++ Phase::m_id is always the same as Phase::m_name
I went ahead as the change was quick and straight-forward. Getting rid of ID altogether certainly feels more consistent. I'll wait for a re-review before adjusting #724 (which will be switched to a - much less intrusive - deprecation of |
* Merge usage of 'id' and 'name' in the context of Phase objects * Raise deprecation warnings for Phase::id and Phase::setID
I added deprecation of I cannot think of anything else at this point, so this PR is ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making these updates. I think converging on name
as the sole phase identifier and removal of the extra phase_name:species_name
access are both useful simplifications to the user interface, and make the introduction of the Solution
class simpler.
I think there are just a few minor points left to address before this can be merged.
def __set__(self, name): | ||
self.base.setName(stringify(name)) | ||
|
||
property composite: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I suggest something along the lines of composite_type
or composite_model
for this property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a tuple of types/models, so I'd prefer to leave it as is (an alternate would be composite_composition
, which sounds redundant).
To clarify, composite_type
(or composite_model
) to me would indicate Solution
, Interface
, etc. (e.g. a duplicate of type(gas)
, with gas
being a composite object). I wanted to differentiate (and used the name of the declaring module as a guide). I'm open to alternatives though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I see your point on that being a bit misleading. Just composite
feels somehow incomplete to me, but I don't have a better suggestion, so we can leave this as is for now.
Please fill in the issue number this pull request is fixing:
Fixes #695, fixes #691 .
Changes proposed in this pull request:
_SolutionBase
object in C++ layer (namedSolution
)ReplaceID
by more meaningfulphase_id
attribute. The changed attribute is PEP8 compliant and corresponds to the YAML entryPhase::id
andPhase::setID
Solution
object is defined inSolution.h
/Solution.cpp
ThermoPhase
,Kinetics
andTransport
managersPreserves information how managers were constructed astype
(e.g.Solution
,Interface
)name
attribute fromPhase
to_SolutionBase
and ensure unique default names generated in Cython (anticipates uses for serialization)ID
Illustration
There are only minor additions to the user interface; changes mostly benefit "work under the hood".
Comments
The following advantages are anticipated:
Solution
and associated managers via YAML, which would be useful for true parallel processing._SolutionBase
objects as envisioned by Pickle serialization of Solution objects #692Beyond this PR ... moving creation of objects from
Phase
/ThermoPhase
toSolution
would enable switching of thermo models on the fly (similar to transport) and thus eliminate the need for multiple entries in yaml for multiple thermo models (e.g.nDodecane_RK
andnDodecane_IG
differ in exactly one entry, i.e.thermo
, which is eitherideal-gas
orRedlich-Kwong
)