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

Component by-passing/disabling #600

Open
TristanM-TD opened this issue Jan 23, 2025 · 5 comments
Open

Component by-passing/disabling #600

TristanM-TD opened this issue Jan 23, 2025 · 5 comments

Comments

@TristanM-TD
Copy link

Ciao Francesco,

Perhaps it would be nice to have the ability to bypass or disable components to be able to switch between different plant configurations more easily.

Bypassing:
If I wanted to investigate the effect of recuperation on the plant performance, I currently have to a) add/remove the recuperator from the network between runs or b) assign a zero duty. With the ability to set a bypassed attribute, the component could instead be treated as a node with the streams passing through unchanged.

Image

Disabling:
If I wanted to investigate the effect of only one of my heat exchangers being available as part of an off-design calculation, I would have to a) add/remove the corresponding component from the model or b) artificially assign a very small mass rate (not sure if this would necessarily work). With the ability to set a disabled attribute, the branch the component is on could be excluded from the solve.

Image

Not sure if these are the best examples but I hope they convey how this could be useful functiontionality

@fwitte
Copy link
Member

fwitte commented Jan 24, 2025

Ciao Tristan,

that is an excellent idea, I really like it (others already complained about it as well in context of district heating systems), but it is not very easy to generalize. Maybe we can make a start with you bringing up the topic here. A couple of initial thoughts:

  • For the bypassing idea, the components could just be replaced by a subsystem interface. One could check in the initialization step of the simulation, whether a component has the bypass enabled, and if so, instead of returning its own equations, the ones that would be imposed from a SubsystemInterface component. I am not sure, if it makes sense to enable this functionality for any other components than those with n-to-n inlets and outlets (e.g. HeatExchanger, SimpleHeatExchanger, Turbine etc.). This would enforce for all related connections:
    • mass flow and fluid composition equality
    • pressure and enthalpy equality
  • The disabling part might be a little bit more difficult, because setting mass flow to zero is unfortunately numerically challenging (some equations will just not work) and setting it to a very small value might have similar downsides.
    • One idea could be, that all components inside a branch could be set to bypass mode. In your second image, this would essentially force pressure equality for the merging and splitting point, which could be an issue (but one that can be handled, e.g. by implementing merging and splitting points that do not force pressure equality). The good part of this is, that potential heat exchangers inside a branch that was disabled, would also automatically handle the secondary side. The downside might be, that it creates unnecessary variables in the system (which is something not as bad, in my opinion).
    • I was thinking of two ideas before typing out the first one, but that now already sounds very promising, that I have forgotten the second one...

So, maybe we could make two concrete minimal examples to test this out? I would go with your examples, but in the second one I would actually like to see, what happens if the disabled HeatExchanger has a secondary side with incoming and outgoing connections.

Best

Francesco

@TristanM-TD
Copy link
Author

Ciao Francesco,

I agree that actually the two are quite different beasts... perhaps I should have split them up into two separate issues.

Definitions
Just to ensure we are on the same page, to me "disabling" corresponds to the flow path being blocked, whereas "bypassed" corresponds to the flow path being open, but the fluid state is unchanged in a component.

Bypassing:
I had a look at the source code last night and thought that we could implement a function similar to get_mandatory_constraints(), albeit for bypassing. As you mentioned above, this function should then set the pressure_equality_constraints and enthalpy_equality_constraints by default.

Of course this can then be overwritten at the component level, in principle, allowing all components, even those with m-to-n connections, to be "bypassed".

Disabling
I think it would be quite difficult to "mimic" the "disabled" behaviour by "bypassing" a series of components. For example, in the example below, disabling HEX-A means that the source upstream of HEX-A must also be inactive, as well as any equipment downstream of HEX-A up to the point where the branch merges with another.
Image

Would your suggestion above not result in the system being linearly dependent? As the pressure at Fout is now both defined by the pressure-equality across HEX-A and the pressure drop across HEX-B.

With the above in mind, I would suggest something like resolving the disabling at the point of checking the network and setting up the branches. Effectively, when a branch is created, a check should be performed to ensure that all components in the branch are "active" or "bypassed" - if not, i.e. a component is disabled, the entire branch should be excluded from the solve.

Perhaps my alter-ego will have some fun with a something for the bypassing on the weekend :)

Buon fine settimana,
Tristan

@fwitte
Copy link
Member

fwitte commented Jan 26, 2025

Ciao Tristan,

thank you for clarifying, I think we are on the same page!

Would your suggestion above not result in the system being linearly dependent? As the pressure at Fout is now both defined by the pressure-equality across HEX-A and the pressure drop across HEX-B.

This would actually be the only issue when mimicing a disabled branch by bypassing, which would essentially set mass flow to 0 and could make up any fluid composition, enthalpy and pressure value because those would not matter anyways, when merging to somewhere else again. To get the pressure equality tackled at a merge point, that could be achieved by changing the equations in the merge point depending on whether or not a mass flow is coming from a disabled branch. What is interesting about this is, that it may be realized without too many changes in the current architecture, but then it somehow feels like a "hacky" solution.

With the above in mind, I would suggest something like resolving the disabling at the point of checking the network and setting up the branches. Effectively, when a branch is created, a check should be performed to ensure that all components in the branch are "active" or "bypassed" - if not, i.e. a component is disabled, the entire branch should be excluded from the solve.

I like this solution more, the question here is how to implement it. I think it should be possible to let the solver ignore some connections (and components). The bigger challenge lies in the fact, that some components have to be altered (maybe). I'll try to make a couple of example, which may serve as tests, which a solution needs to cover (or maybe not, we can discuss this):

  • Heat exchanger with the hot side being part of a disabled branch, cold side is not affected.
  • A two-stage turbine with intermediate extraction. The extraction goes to a heating condenser, meaning the pressure level of extraction is imposed indirectly from the cold side of the condenser via pinch temperature difference. What happens, if the extraction is closed completely? What value of pressure is assigned to the extraction point?
  • Two branches like in your drawings: How to alter the merge point equations?

@TristanM-TD
Copy link
Author

@fwitte

Regarding the "test" cases for defining the intended behaviour:

Heat exchanger with the hot side being part of a disabled branch, cold side is not affected.
Here, I think the effect on the cold-side should be equivalent to bypassing.

Perhaps it is important to also differentiate between the degree of disabling, i.e. whether a component has been disabled directly (the disabling flag is set on a given component), indirectly via an upstream or downstream component (the disabling flag is set on an upstream or downstream component), or partial, where a component has multiple fluid conduits, one or more of which can be indirectly disabled.

A two-stage turbine with intermediate extraction. The extraction goes to a heating condenser, meaning the pressure level of extraction is imposed indirectly from the cold side of the condenser via pinch temperature difference. What happens, if the extraction is closed completely? What value of pressure is assigned to the extraction point?

My take would be that not all problems are valid :P But this should soon be picked up by the network solver so at least the user would get a warning, and can then impose other parameters, such as turbine pr

Two branches like in your drawings: How to alter the merge point equations?

I feel like this would be similar to the case with the heat exchanger, in that the Merge is effectively bypassed. That being said, if there were more streams entering the Merge and more than one are active, bypassing does not yield the correct result.

@TristanM-TD
Copy link
Author

With the above in mind,

My original suggestion to "trim" the branches could work well for all cases where a component is directly disabled or for all components with 0-to-1 (i.e. Source), 1-to-1 (e.g. Pump, Turbine, Valve) or 1-0 (i.e. Sink) components.

However, to handle components with m-to-n connections I fear that this would have to be managed at the point when the equations are set... For example, in the case of the Merge you mentioned above, a check would need to be done to ensure that the pressure equality equation etc. are only set for "active connections".

Another, but rather intrusive, alternative would be to parse the network to a simplified architecture and to then just solve that network with the regular solver, passing back any results to the original network.

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

No branches or pull requests

2 participants