oemof / tespy

Thermal Engineering Systems in Python (TESPy). This package provides a powerful simulation toolkit for thermal engineering plants such as power plants, district heating systems or heat pumps.
https://tespy.readthedocs.io
MIT License
256 stars 80 forks source link

Infinite looping in fluid propagation #424

Closed 5venNi closed 11 months ago

5venNi commented 1 year ago

I think I found an issue with the fluid propagation in the initialisation of a network with Splitters and Merges. With the minimum working example (MWE) below, I get

RecursionError: maximum recursion depth exceeded while calling a Python object

in the fluid propagation. As far as I can tell from running it in debug mode, this is due to infinite looping trough the Splitter and the Merge even though this should be prevented with the start argument in the propagate_fluid_to_target functions according to the descriptions.

The code below leads to the described error. The error would not occur if the fluid declaration was placed right after the source in this MWE. However, I have a more complicated network that requires me to generate stable starting values according to this tutorial (first replace certain attributes with others and solve this more stable system, followed by solving it again with the correct attributes). In this case, a fluid propagation with the initial values for the fluid composition is attempted from after the merge in the second calculation. This behaviour can be seen by uncommenting the commented part in the code below and declaring the fluid composition after the source.

from tespy.networks import Network
from tespy.components import Source, Sink, Merge, Splitter, HeatExchangerSimple
from tespy.connections import Connection

network = Network(fluids=['R134a', 'Water'])

network.set_attr(T_unit='C', p_unit='bar', h_unit='kJ / kg')

source = Source('source')
merge = Merge('merge')
component1 = HeatExchangerSimple('comp1', pr=1)
splitter = Splitter('splitter')
component2 = HeatExchangerSimple('comp2')
sink = Sink('sink')

c1 = Connection(source, 'out1', merge, 'in1', p=1, h=200, m=10)
c2 = Connection(merge, 'out1', component1, 'in1', fluid={'R134a': 1, 'Water': 0})
c3 = Connection(component1, 'out1', splitter, 'in1', h=180)
c4 = Connection(splitter, 'out1', component2, 'in1', m=1)
c5 = Connection(component2, 'out1', merge, 'in2', h=170)
c6 = Connection(splitter, 'out2', sink, 'in1')

network.add_conns(c1, c2, c3, c4, c5, c6)

network.solve('design')
network.print_results()

# c3.set_attr(h=None)
# c5.set_attr(h=None)
# component1.set_attr(Q=-1000)
# component2.set_attr(Q=-500)
#
# network.solve('design')
# network.print_results()

system

fwitte commented 11 months ago

@5venNi,

thank you for reporting the issue. I have implemented a fix in #427, if you want to try it, you can install the developer version and use the update directly. I would like to add one or two more tests to prevent this specific issue from happening in the future, so I will merge it later this week and then soon create a new release to make the bugfix available for installation from PyPI.

Best

Francesco

P.S.: If you need support to set up a developer installation you can check out this page: https://tespy.readthedocs.io/en/main/development/how.html In case you want to give it a try and something does not work, please let me know. I'll try to help you directly then and maybe adjust that page correspondingly.

5venNi commented 11 months ago

Thanks @fwitte for fixing it that quickly. It seems to work properly for the MWE above as well as my real use case.

fwitte commented 11 months ago

Quick update: I will not implement more tests for now and merge #427 without them. The reason for that is #384, where I do a full restructuring of the TESPy back-end which also includes an improved fluid vector propagation. I have included your test case in the development of that. If you are interested, the restructuring will

Have a good weekend!

Best

fwitte commented 8 months ago

@5venNi, quick update, in case you are still working with TESPy:

I merged #384 and published version 0.7.0. The new version changes a lot on the fluid properties side (you do not need to state fluid={"R134a": 1, "water": 0} anymore, just fluid={"R134a": 1} does the job now. The propagation has changed again a bit, but it should be more robust than before, so I hope it also deals with your real application. On top of that I added the test case to the testing pipeline. On top of that, the changes simplify further development with respect to implementing refrigerant mixtures in general, if that is still of relevance for you.

Best

Francesco