diff --git a/docs/conf.py b/docs/conf.py index 574b0c293..a8cf752fb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -148,4 +148,5 @@ r'https://doi.org/20.500.12738/6561', # 08.01.2023: does not resolve anymore r'https://doi.org/10.1021/ie4033999', # 28.02.2023: does not resolve anymore for some reason r'https://doi.org/10.1002/bbpc.19900940121', # 13.03.2023 ...? + r' http://www.coolprop.org/fluid_properties/Incompressibles.html', # 02.12.2023 ...? ] diff --git a/docs/whats_new.rst b/docs/whats_new.rst index 835278fa1..f03b829f0 100644 --- a/docs/whats_new.rst +++ b/docs/whats_new.rst @@ -3,6 +3,7 @@ What's New Discover noteable new features and improvements in each release +.. include:: whats_new/v0-7-1.rst .. include:: whats_new/v0-7-0.rst .. include:: whats_new/v0-6-3.rst .. include:: whats_new/v0-6-2.rst diff --git a/docs/whats_new/v0-7-1.rst b/docs/whats_new/v0-7-1.rst new file mode 100644 index 000000000..fa008fff8 --- /dev/null +++ b/docs/whats_new/v0-7-1.rst @@ -0,0 +1,14 @@ +v0.7.1 - Newton's Nature (December, 2, 2023) +++++++++++++++++++++++++++++++++++++++++++++ + +Bug Fixes +######### +- Several bugs introduced by the restructuring of the package in version 0.7.0 + have been fixed: + + - `PR #451 `__ + - `PR #453 `__ + +Contributors +############ +- Francesco Witte (`@fwitte `__) diff --git a/pyproject.toml b/pyproject.toml index 82aaf725a..eb184e992 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ exclude = ["docs/_build"] [project] name = "tespy" -version = "0.7.1" +version = "0.7.1.post1" description = "Thermal Engineering Systems in Python (TESPy)" readme = "README.rst" authors = [ diff --git a/src/tespy/__init__.py b/src/tespy/__init__.py index 049be2a61..fde368697 100644 --- a/src/tespy/__init__.py +++ b/src/tespy/__init__.py @@ -3,7 +3,7 @@ import os __datapath__ = os.path.join(importlib.resources.files("tespy"), "data") -__version__ = '0.7.1 - Newton\'s Nature' +__version__ = '0.7.1.post1 - Newton\'s Nature' # tespy data and connections import from . import connections # noqa: F401 diff --git a/src/tespy/components/heat_exchangers/desuperheater.py b/src/tespy/components/heat_exchangers/desuperheater.py index dc3a60601..f69db8eb5 100644 --- a/src/tespy/components/heat_exchangers/desuperheater.py +++ b/src/tespy/components/heat_exchangers/desuperheater.py @@ -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 diff --git a/src/tespy/components/nodes/drum.py b/src/tespy/components/nodes/drum.py index d32c47b42..dc48d5397 100644 --- a/src/tespy/components/nodes/drum.py +++ b/src/tespy/components/nodes/drum.py @@ -170,6 +170,7 @@ def outlets(): return ['out1', 'out2'] def get_mandatory_constraints(self): + num_mass_eq = 1 if self.inl[1].m == self.outl[0].m: num_mass_eq = 0 return { @@ -217,6 +218,7 @@ def mass_flow_func(self): if self.inl[1].m == self.outl[0].m: return self.inl[0].m.val_SI - self.outl[1].m.val_SI else: + res = 0 for i in self.inl: res += i.m.val_SI for o in self.outl: diff --git a/src/tespy/networks/network.py b/src/tespy/networks/network.py index 405c0b2eb..9f699dd08 100644 --- a/src/tespy/networks/network.py +++ b/src/tespy/networks/network.py @@ -847,6 +847,21 @@ def initialise(self): self.num_conn_vars = 0 self.variables_dict = {} + # 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() self.propagate_fluid_wrappers() self.presolve_massflow_topology() self.presolve_fluid_topology() diff --git a/src/tespy/tools/fluid_properties/wrappers.py b/src/tespy/tools/fluid_properties/wrappers.py index 97ce00647..bc2f84df7 100644 --- a/src/tespy/tools/fluid_properties/wrappers.py +++ b/src/tespy/tools/fluid_properties/wrappers.py @@ -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: @@ -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): diff --git a/tests/test_components/test_combustion.py b/tests/test_components/test_combustion.py index b26bcbafa..7912781fb 100644 --- a/tests/test_components/test_combustion.py +++ b/tests/test_components/test_combustion.py @@ -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 diff --git a/tests/test_components/test_drum.py b/tests/test_components/test_drum.py new file mode 100644 index 000000000..5c673dcef --- /dev/null +++ b/tests/test_components/test_drum.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 + +"""Module for testing components of type merge. +This file is part of project TESPy (github.com/oemof/tespy). It's copyrighted +by the contributors recorded in the version control history of the file, +available from its original location +tests/test_components/test_merge.py +SPDX-License-Identifier: MIT +""" +from pytest import approx +from pytest import fixture + +from tespy.components import Drum +from tespy.components import SimpleHeatExchanger +from tespy.components import Sink +from tespy.components import Source +from tespy.components import Splitter +from tespy.connections import Connection +from tespy.networks import Network + + +@fixture() +def drum_network_setup(): + nw = Network(T_unit="C", p_unit="bar") + dr = Drum("drum") + so = Source("liquid") + si = Sink("vapor") + c1 = Connection(so, "out1", dr, "in1", label="1") + c2 = Connection(dr, "out2", si, "in1", label="2") + nw.add_conns(c1, c2) + c1.set_attr(fluid={"R290": 1}, m=10, Td_bp=-10, T=50) + yield nw + + +def test_drum_with_blowdown(drum_network_setup): + nw = drum_network_setup + sp = Splitter("blowdown splitter") + si = Sink("blowdown sink") + eva = SimpleHeatExchanger("evaporator") + dr = nw.get_comp("drum") + c3 = Connection(dr, "out1", sp, "in1", label="3") + c4 = Connection(sp, "out1", si, "in1", label="4") + c5 = Connection(sp, "out2", eva, "in1", label="5") + c6 = Connection(eva, "out1", dr, "in2", label="6") + + c6.set_attr(x=0.7, m=15) + + nw.add_conns(c3, c4, c5, c6) + + nw.solve("design") + + assert 0.72728 == approx(c4.m.val_SI) diff --git a/tests/test_components/test_merge.py b/tests/test_components/test_merge.py index fcc6065f2..5b15783e6 100644 --- a/tests/test_components/test_merge.py +++ b/tests/test_components/test_merge.py @@ -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() diff --git a/tests/test_components/test_reactors.py b/tests/test_components/test_reactors.py index e20d1c8d0..ffdaae146 100644 --- a/tests/test_components/test_reactors.py +++ b/tests/test_components/test_reactors.py @@ -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 diff --git a/tutorial/advanced/optimization_example.py b/tutorial/advanced/optimization_example.py index ee1bbe336..064c5a71d 100644 --- a/tutorial/advanced/optimization_example.py +++ b/tutorial/advanced/optimization_example.py @@ -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 @@ -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") @@ -108,8 +104,6 @@ def __init__(self): self.nw.add_busses(self.power, self.heat) - # parametrization - # components hpt.set_attr(eta_s=0.9) mpt.set_attr(eta_s=0.9) lpt.set_attr(eta_s=0.9) @@ -129,13 +123,16 @@ def __init__(self): 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) + # parametrization + # components self.nw.solve("design") self.stable = "_stable" self.nw.save(self.stable) self.solved = True + self.nw.print_results() # %%[sec_2]