-
-
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
Non-empty Reactor and Connector Objects #1788
base: main
Are you sure you want to change the base?
Conversation
b3dd2d1
to
d295959
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1788 +/- ##
==========================================
+ Coverage 73.23% 73.33% +0.09%
==========================================
Files 381 389 +8
Lines 54376 54459 +83
Branches 9253 9270 +17
==========================================
+ Hits 39824 39935 +111
+ Misses 11579 11551 -28
Partials 2973 2973 ☔ View full report in Codecov by Sentry. |
6fcbd68
to
7ae226a
Compare
@speth ... while there are likely more paper cuts, I don't necessarily want to go beyond 2k lines. Among the things that could be tackled are lowercase/hyphenated type names to be consistent with what we do with |
I just realized that there are some connections to Cantera/enhancements#201 and Cantera/enhancements#202. While this PR doesn't address either directly, it does ensure that a resolution will become easier. Without trying to pre-empt any eventual resolution, my personal take would be:
|
a05281f
to
706861f
Compare
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.
I think the changes to have Reactor
objects always contain a valid Solution
object make sense, and I agree that this will help with Cantera/enhancements#201. I also like the idea of always providing the Reactor
objects to the constructor for the connector objects and bringing that feature of the Python API to all the interfaces.
However, it's not quite clear to me what the benefit is of making all Reactor
and connector objects into mandatory shared_ptr
s. Currently, the ownership model is simple: none of the Reactor
/ReactorNet
/FlowDevice
/etc. objects take ownership of anything they are connected to; the lifetimes of all these objects are managed by the caller. Within this set of objects, we need connections in all directions. Avoiding reference cycles will require the use of weak_ptr
for many of the connections, with the associated overhead of "upgrading" those to shared_ptr
where they are used. And you will still be left with the situation where it's possible to hold on to some element of the network but not be able to use it because the rest of the network has been deleted, though at least that would be checked and generate an exception rather than undefined behavior. My apologies for not thinking this through earlier and discussing it on Cantera/enhancements#213 before you put the time into implementing it.
Regarding the extension of the graph idiom, I think there's a simplification that may be worth considering. Instead of seeing just Reactor
and ReactorSurface
objects as nodes in the graph, you could also see valves and flow devices as nodes, with the edges of the graph just being the abstract connections among all of the entities that make up the reactor network. This way, there's only the need for one new base class, and no need for anything to sit between a Reactor
and a ReactorSurface
. This also gets closer to the original intent of Cantera/enhancements#212, and may work better as the amount of information you might want to display about a connector increases, given some of the limitations of how Graphviz handles (or doesn't) text associated with edges. That said, I do like the Connector
class as a generalization combining walls and flow devices, and there's probably some further room to adjust this idea.
//! Set the Solution specifying the ReactorBase content. | ||
//! @param sol Solution object to be set. | ||
//! @since New in %Cantera 3.1. | ||
//! @deprecated To be removed after %Cantera 3.1. Superseded by instantiation of | ||
//! ReactorBase with Solution object. | ||
void setSolution(shared_ptr<Solution> sol); |
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.
Now that I think about this more, my preferred resolution to Cantera/enhancements#201 will require allowing ReactorNet
to replace Solution
objects in Reactors
.
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.
Could you expand? My thinking was a strict hierarchy where the ReactorNet
is responsible for Reactor
, which themselves are responsible for Solution
. I am not sure that I see why we should give ReactorNet
the ability to muddle with reactor contents?
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.
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.
I responded in Cantera/enhancements#201 (comment). Irrespective of the logic we go with eventually, the detection of previously used Solution
objects should be handled by ReactorNode
and not ReactorNet
.
@@ -123,7 +100,7 @@ extern "C" { | |||
double reactor_mass(int i) | |||
{ | |||
try { | |||
return ReactorCabinet::at(i)->mass(); | |||
return ReactorCabinet::as<ReactorBase>(i)->mass(); |
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.
The fact that almost all usage of ReactorNode
objects requires downcasting to ReactorBase
, ReactorSurface
, or Reactor
suggests to me that we shouldn't be defining our interface in terms of ReactorNode
objects (which is not to say that the base class isn't useful for implementing some features like the automatic name generation).
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.
Once the API is fixed, ReactorBase
methods should be either shifted to ReactorNode
or Reactor
, with ReactorBase
eventually being removed. From that perspective, this is transitional behavior.
Adding the following to ReactorBase.h
:
* @todo After completion of the %Cantera 3.1 deprecation cycle, all methods should be
* either moved to ReactorNode or Reactor, with ReactorBase entering its own
* deprecation cycle in %Cantera 3.2.
The newReactor function with contents was only introduced in 3.1 and thus can be modified without deprecations.
1749566
to
e51053c
Compare
e51053c
to
c17b309
Compare
@speth ... thank you again for your feedback. After further consideration, I decided to move ahead with revisions on this PR after all, as some of the API changes are necessary to tackle updates envisioned by various enhancement requests. I adopted most of your suggestions, specifically:
Beyond, I tried to clarify future plans that motivated API changes, see various comments in the contexts of Cantera/enhancements#201, Cantera/enhancements#202 and Cantera/enhancements#213. |
(moving out of a specific line-by-line comment to prevent GitHub from hiding this higher-level discussion) I think this gets to my main concern with the API changes that this PR creates. Right now, there's a bit too much importance being placed on the idea of the reactor network as a graph -- most users don't care about this, but it now becomes the most important thing about a reactor and represents almost the only set of directly accessible functionality when using I'd like to explore whether we can directly skip over creating the I'd rather do this than leave users with an unnecessarily difficult-to-use interface for a full Cantera version. |
Thanks for your response, @speth.
Interesting thought - my attempt to simplify was definitely influenced by viewing 'reactor networks as a graph', although my objective was to simplify/generalize rather than making things more complicated.
I agree that we have one superfluous layer, which needs to be addressed. I was thinking along the lines of differentiating between bulk and surface reactors. I still think that nodes and edges make sense overall, so my introduction of a new base class was a move to phase out
I think at this point it makes sense to defer to 3.2. I will change the project planner accordingly. |
Changes proposed in this pull request
This PR ensures that the Reactor/zeroD API uses shared pointers consistently. After removing raw pointers/references from various methods, it becomes possible to update the underlying code base, which at this point is a mix of shared pointers, raw pointers, and references. Details are:
ReactorNode
andConnector
, which are bases for all 0D objects (which from the perspective of a graph are either nodes or edges); all objects are captured in updated factories.ReactorBase
andReactorSurface
are now derived fromReactorNode
.Wall
andFlowDevice
are both derived fromConnector
.AllReactorNode
andConnector
objects require contents to be available to the constructor (other than deprecated versions)with new convenience methods creating objects accessed by shared pointers (examples:... Edit: constructors are accessed vianewReservoir
andnewValve
). The old constructors (without arguments) are deprecated. The implementation loosely followsnewSolution
.Reservoir::create
,Valve::create
etc..SharedFactory
factory variant stores shared pointers rather than raw pointers.shared_from_this
when connecting aReactorNet
.Add wall names toEdit: Moved to Graphviz tweaks #1792ReactorNet
graphviz illustrations.If applicable, fill in the issue number this pull request is fixing
Closes Cantera/enhancements#213
If applicable, provide an example illustrating new features this pull request is introducing
Checklist
scons build
&scons test
) and unit tests address code coverage