Skip to content

Commit

Permalink
Fix the mass flow and fluid topology simplification for multiprocessing
Browse files Browse the repository at this point in the history
  • Loading branch information
fwitte committed Dec 2, 2023
1 parent b254960 commit bbb285e
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/tespy/components/heat_exchangers/desuperheater.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,6 @@ def saturated_gas_deriv(self, increment_filter, k):
"""
o = self.outl[0]
if self.is_variable(o.p):
self.jacobian[k, o.p.J_col] = -dh_mix_dpQ(o, 1, o.fluid_data)
self.jacobian[k, o.p.J_col] = -dh_mix_dpQ(o.p.val_SI, 1, o.fluid_data)
if self.is_variable(o.h):
self.jacobian[k, o.h.J_col] = 1
21 changes: 19 additions & 2 deletions src/tespy/networks/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,8 +690,6 @@ def check_network(self):
self.check_conns()
self.init_components()
self.check_components()
self.create_massflow_and_fluid_branches()
self.create_fluid_wrapper_branches()

# network checked
self.checked = True
Expand Down Expand Up @@ -847,6 +845,25 @@ def initialise(self):
self.num_conn_vars = 0
self.variables_dict = {}

if hasattr(self, "massflow_branches"):
# in multiprocessing copies are made of all connections
# the mass flow branches and fluid branches hold references to
# connections from the original run (where network.checked is False)
# The assignment of variable spaces etc. is however made on the
# copies of the connections which do not correspond to the mass flow
# branches and fluid branches anymore. So the topology simplification
# does not actually apply to the copied network, therefore the
# branches have to be recreated for this case. We can detect that by
# checking whether a network holds a massflow branch with some
# connections and compare that with the connection object actually
# present in the network
first_conn = self.massflow_branches[0]["connections"][0]
if self.conns.loc[first_conn.label, "object"] != first_conn:
self.create_massflow_and_fluid_branches()
self.create_fluid_wrapper_branches()
else:
self.create_massflow_and_fluid_branches()
self.create_fluid_wrapper_branches()
self.propagate_fluid_wrappers()
self.presolve_massflow_topology()
self.presolve_fluid_topology()
Expand Down
12 changes: 11 additions & 1 deletion src/tespy/tools/fluid_properties/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@
from tespy.tools.global_vars import ERR


class SerializableAbstractState(CP.AbstractState):

def __init__(self, back_end, fluid_name):
self.back_end = back_end
self.fluid_name = fluid_name

def __reduce__(self):
return (self.__class__, (self.back_end, self.fluid_name))


class FluidPropertyWrapper:

def __init__(self, fluid, back_end=None) -> None:
Expand Down Expand Up @@ -112,7 +122,7 @@ def __init__(self, fluid, back_end=None) -> None:
back_end = "HEOS"

super().__init__(fluid, back_end)
self.AS = CP.CoolProp.AbstractState(self.back_end, self.fluid)
self.AS = SerializableAbstractState(self.back_end, self.fluid)
self._set_constants()

def _set_constants(self):
Expand Down
2 changes: 0 additions & 2 deletions tests/test_components/test_combustion.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

import shutil

import numpy as np

from tespy.components import CombustionChamber
from tespy.components import CombustionEngine
from tespy.components import DiabaticCombustionChamber
Expand Down
14 changes: 0 additions & 14 deletions tests/test_components/test_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,3 @@ def test_two_fluid_setup(self):
target = c1.m.val_SI
msg = f"Target value for mass flow at connection 3 is {target}"
assert c6.m.val_SI == approx(target), msg


test = TestMerge()
test.setup_method()
test.test_single_fluid_at_outlet()
test.setup_method()
test.test_massflows_from_two_fluid_fractions()


test2 = TestCyclicMerging()
test2.setup_method()
test2.test_single_fluid_setup()
test2.setup_method()
test2.test_two_fluid_setup()
2 changes: 0 additions & 2 deletions tests/test_components/test_reactors.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

import shutil

import numpy as np

from tespy.components import Sink
from tespy.components import Source
from tespy.components import WaterElectrolyzer
Expand Down
27 changes: 16 additions & 11 deletions tutorial/advanced/optimization_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from tespy.components import SimpleHeatExchanger
from tespy.components import Merge
from tespy.components import Splitter
from tespy.components import Valve
from tespy.components import Pump
from tespy.components import Turbine
from tespy.connections import Bus
Expand Down Expand Up @@ -82,10 +81,7 @@ def __init__(self):
c32 = Connection(fwh1, "out1", pu3, "in1", label="32")
c33 = Connection(pu3, "out1", me, "in2", label="33")

self.nw.add_conns(
c21, c22, c23, c24,
c31, c32, c33
)
self.nw.add_conns(c21, c22, c23, c24, c31, c32, c33)

# cooling water
c41 = Connection(cwi, "out1", con, "in2", label="41")
Expand All @@ -108,34 +104,43 @@ def __init__(self):

self.nw.add_busses(self.power, self.heat)

self.set_design_values()
# parametrization
# components
self.nw.solve("design")
self.stable = "_stable"
self.nw.save(self.stable)
self.solved = True
self.nw.print_results()

def set_design_values(self):
hpt, mpt, lpt = self.nw.get_comp(["high pressure turbine", "mid pressure turbine", "low pressure turbine"])
hpt.set_attr(eta_s=0.9)
mpt.set_attr(eta_s=0.9)
lpt.set_attr(eta_s=0.9)

pu1, pu2, pu3 = self.nw.get_comp(["feed water pump", "feed water pump 2", "feed water pump 3"])
pu1.set_attr(eta_s=0.8)
pu2.set_attr(eta_s=0.8)
pu3.set_attr(eta_s=0.8)

sg = self.nw.get_comp("steam generator")
sg.set_attr(pr=0.92)

con, fwh1, fwh2, dsh = self.nw.get_comp(["condenser", "feed water preheater 1", "feed water preheater 2", "desuperheater"])
con.set_attr(pr1=1, pr2=0.99, ttd_u=5)
fwh1.set_attr(pr1=1, pr2=0.99, ttd_u=5)
fwh2.set_attr(pr1=1, pr2=0.99, ttd_u=5)
dsh.set_attr(pr1=0.99, pr2=0.99)

c1, c2, c4, c41, c42 = self.nw.get_conn(["1", "2", "4", "41", "42"])
c1.set_attr(m=200, T=650, p=100, fluid={"water": 1})
c2.set_attr(p=20)
c4.set_attr(p=3)

c41.set_attr(T=20, p=3, fluid={"water": 1})
c42.set_attr(T=28)
c41.set_attr(T=20, p=3, fluid={"INCOMP::Water": 1})
c42.set_attr(T=28, p0=3, h0=100)

self.nw.solve("design")
self.stable = "_stable"
self.nw.save(self.stable)
self.solved = True

# %%[sec_2]

Expand Down

0 comments on commit bbb285e

Please sign in to comment.