Skip to content

Commit

Permalink
Merge pull request #18 from RWTH-EBC/4-add-validation-based-on-optihorst
Browse files Browse the repository at this point in the history
4 add validation based on optihorst
  • Loading branch information
FWuellhorst authored Nov 25, 2024
2 parents 0315e0e + 8a79de9 commit ca63180
Show file tree
Hide file tree
Showing 25 changed files with 1,209 additions and 398 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
- v0.1.0:
- First implementation based on prior work
- v0.1.1:
- Move plot_cycle function
- Move plot_cycle function
- v0.2.0:
- Add LMTD MovingBoundary heat exchangers
- Add VDI atlas methods for plate heat exchanger
- Add scaling factor to TenCoefficientCompressor
- Add extrapolation option to TenCoefficientCompressor
- Improve warnings and parameters in TenCoefficientCompressor (eta_mech, T_sc)
- Add T_con_out as possible Input
- Automation is now with multiprocessing
- SDF saving is optional in automation
- Improve nominal design util
- Improve C10 regression generation, add .csv support for TenCoefficientCompressor
12 changes: 6 additions & 6 deletions docs/jupyter_notebooks/e6_simple_heat_pump.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@
{
"cell_type": "markdown",
"metadata": {},
"source": "As in the other example, we can specify save-paths,\nsolver settings and inputs to vary:\n"
"source": "As in the other example, we can specify save-paths,\nsolver settings and inputs to vary:\nNote that T_con can either be inlet or outlet, depending on the setting\nof `use_condenser_inlet`. Per default, we simulate the inlet, T_con_in\n"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "save_path = r\"D:\\00_temp\\simple_heat_pump\"\nT_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]\nT_con_in_ar = [30 + 273.15, 50 + 273.15, 70 + 273.15]\nn_ar = [0.3, 0.7, 1]\n"
"source": "save_path = r\"D:\\00_temp\\simple_heat_pump\"\nT_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]\nT_con_ar = [30 + 273.15, 50 + 273.15, 70 + 273.15]\nn_ar = [0.3, 0.7, 1]\n"
},
{
"cell_type": "markdown",
Expand All @@ -63,7 +63,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "import logging\nlogging.basicConfig(level=\"INFO\")\n\nfrom vclibpy import utils\nsave_path_sdf, save_path_csv = utils.full_factorial_map_generation(\n heat_pump=heat_pump,\n save_path=save_path,\n T_con_in_ar=T_con_in_ar,\n T_eva_in_ar=T_eva_in_ar,\n n_ar=n_ar,\n use_multiprocessing=False,\n save_plots=True,\n m_flow_con=0.2,\n m_flow_eva=0.9,\n dT_eva_superheating=5,\n dT_con_subcooling=0,\n)\n"
"source": "import logging\nlogging.basicConfig(level=\"INFO\")\n\nfrom vclibpy import utils\nsave_path_sdf, save_path_csv = utils.full_factorial_map_generation(\n heat_pump=heat_pump,\n save_path=save_path,\n T_con_ar=T_con_ar,\n T_eva_in_ar=T_eva_in_ar,\n n_ar=n_ar,\n use_condenser_inlet=use_condenser_inlet,\n use_multiprocessing=False,\n save_plots=True,\n m_flow_con=0.2,\n m_flow_eva=0.9,\n dT_eva_superheating=5,\n dT_con_subcooling=0,\n)\n"
},
{
"cell_type": "markdown",
Expand Down Expand Up @@ -99,19 +99,19 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "import matplotlib.pyplot as plt\nx_name = \"n in - (Relative compressor speed)\"\ny_name = \"COP in - (Coefficient of performance)\"\nplt.scatter(df[x_name], df[y_name])\nplt.ylabel(y_name)\nplt.xlabel(x_name)\nplt.show()\n"
"source": "import matplotlib.pyplot as plt\nx_name = \"n in - (Relative compressor speed)\"\ny_name = \"COP in - (Coefficient of performance)\"\nplt.scatter(df[x_name], df[y_name], s=20)\nplt.ylabel(y_name)\nplt.xlabel(x_name)\nplt.show()\n"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "Looking at the results, we see that a higher frequency often leads to lower COP values.\nHowever, other inputs (temperatures) have a greater impact on the COP.\nWe can also use existing 3D-plotting scripts in vclibpy to analyze the\ndependencies. For this, we need the .sdf file. In the sdf, the field names are without\nthe unit and description, as those are accessible in the file-format in other columns.\n"
"source": "Looking at the results, we see that a higher frequency often leads to lower COP values.\nHowever, other inputs (temperatures) have a greater impact on the COP.\nWe can also use existing 3D-plotting scripts in vclibpy to analyze the\ndependencies. For this, we need the .sdf file. In the sdf, the field names are without\nthe unit and description, as those are accessible in the file-format in other columns.\nDepending on whether we varied the inlet or outlet, we have to specify the correct name.\n"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "from vclibpy.utils.plotting import plot_sdf_map\nplot_sdf_map(\n filepath_sdf=save_path_sdf,\n nd_data=\"COP\",\n first_dimension=\"T_eva_in\",\n second_dimension=\"T_con_in\",\n fluids=[\"Propane\"],\n flowsheets=[\"Standard\"]\n)\n"
"source": "from vclibpy.utils.plotting import plot_sdf_map\nplot_sdf_map(\n filepath_sdf=save_path_sdf,\n nd_data=\"COP\",\n first_dimension=\"T_eva_in\",\n second_dimension=\"T_con_in\" if use_condenser_inlet else \"T_con_out\",\n fluids=[\"Propane\"],\n flowsheets=[\"Standard\"]\n)\n"
}
],
"metadata": {
Expand Down
6 changes: 3 additions & 3 deletions docs/jupyter_notebooks/e7_vapor_injection.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "save_path = r\"D:\\00_temp\\vapor_injection\"\nT_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]\nT_con_in_ar = [30 + 273.15, 50 + 273.15, 60 + 273.15]\nn_ar = [0.3, 0.7, 1]\n"
"source": "save_path = r\"D:\\00_temp\\vapor_injection\"\nT_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]\nT_con_ar = [30 + 273.15, 50 + 273.15, 60 + 273.15]\nn_ar = [0.3, 0.7, 1]\n"
},
{
"cell_type": "markdown",
Expand All @@ -75,7 +75,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "import logging\nlogging.basicConfig(level=\"INFO\")\n\nfrom vclibpy import utils\nutils.full_factorial_map_generation(\n heat_pump=heat_pump,\n save_path=save_path,\n T_con_in_ar=T_con_in_ar,\n T_eva_in_ar=T_eva_in_ar,\n n_ar=n_ar,\n use_multiprocessing=False,\n save_plots=True,\n m_flow_con=0.2,\n m_flow_eva=0.9,\n dT_eva_superheating=5,\n dT_con_subcooling=0,\n)\n"
"source": "import logging\nlogging.basicConfig(level=\"INFO\")\n\nfrom vclibpy import utils\nutils.full_factorial_map_generation(\n heat_pump=heat_pump,\n save_path=save_path,\n T_con_ar=T_con_ar,\n T_eva_in_ar=T_eva_in_ar,\n n_ar=n_ar,\n use_condenser_inlet=True,\n use_multiprocessing=False,\n save_plots=True,\n m_flow_con=0.2,\n m_flow_eva=0.9,\n dT_eva_superheating=5,\n dT_con_subcooling=0,\n)\n"
},
{
"cell_type": "markdown",
Expand Down Expand Up @@ -123,7 +123,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "heat_pump = VaporInjectionEconomizer(\n evaporator=evaporator,\n condenser=condenser,\n fluid=\"Propane\",\n economizer=economizer,\n high_pressure_compressor=high_pressure_compressor,\n low_pressure_compressor=low_pressure_compressor,\n high_pressure_valve=high_pressure_valve,\n low_pressure_valve=low_pressure_valve\n)\nutils.full_factorial_map_generation(\n heat_pump=heat_pump,\n save_path=r\"D:\\00_temp\\vapor_injection_economizer\",\n T_con_in_ar=T_con_in_ar,\n T_eva_in_ar=T_eva_in_ar,\n n_ar=n_ar,\n use_multiprocessing=False,\n save_plots=True,\n m_flow_con=0.2,\n m_flow_eva=0.9,\n dT_eva_superheating=5,\n dT_con_subcooling=0,\n)\n"
"source": "heat_pump = VaporInjectionEconomizer(\n evaporator=evaporator,\n condenser=condenser,\n fluid=\"Propane\",\n economizer=economizer,\n high_pressure_compressor=high_pressure_compressor,\n low_pressure_compressor=low_pressure_compressor,\n high_pressure_valve=high_pressure_valve,\n low_pressure_valve=low_pressure_valve\n)\nutils.full_factorial_map_generation(\n heat_pump=heat_pump,\n save_path=r\"D:\\00_temp\\vapor_injection_economizer\",\n T_con_ar=T_con_ar,\n T_eva_in_ar=T_eva_in_ar,\n n_ar=n_ar,\n use_multiprocessing=False,\n save_plots=True,\n m_flow_con=0.2,\n m_flow_eva=0.9,\n dT_eva_superheating=5,\n dT_con_subcooling=0,\n)\n"
}
],
"metadata": {
Expand Down
12 changes: 8 additions & 4 deletions docs/source/examples/e6_simple_heat_pump.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,13 @@ heat_pump = StandardCycle(

As in the other example, we can specify save-paths,
solver settings and inputs to vary:
Note that T_con can either be inlet or outlet, depending on the setting
of `use_condenser_inlet`. Per default, we simulate the inlet, T_con_in

```python
save_path = r"D:\00_temp\simple_heat_pump"
T_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]
T_con_in_ar = [30 + 273.15, 50 + 273.15, 70 + 273.15]
T_con_ar = [30 + 273.15, 50 + 273.15, 70 + 273.15]
n_ar = [0.3, 0.7, 1]
```

Expand All @@ -92,9 +94,10 @@ from vclibpy import utils
save_path_sdf, save_path_csv = utils.full_factorial_map_generation(
heat_pump=heat_pump,
save_path=save_path,
T_con_in_ar=T_con_in_ar,
T_con_ar=T_con_ar,
T_eva_in_ar=T_eva_in_ar,
n_ar=n_ar,
use_condenser_inlet=use_condenser_inlet,
use_multiprocessing=False,
save_plots=True,
m_flow_con=0.2,
Expand Down Expand Up @@ -127,7 +130,7 @@ You have to know the names, which are the column headers.
import matplotlib.pyplot as plt
x_name = "n in - (Relative compressor speed)"
y_name = "COP in - (Coefficient of performance)"
plt.scatter(df[x_name], df[y_name])
plt.scatter(df[x_name], df[y_name], s=20)
plt.ylabel(y_name)
plt.xlabel(x_name)
plt.show()
Expand All @@ -138,14 +141,15 @@ However, other inputs (temperatures) have a greater impact on the COP.
We can also use existing 3D-plotting scripts in vclibpy to analyze the
dependencies. For this, we need the .sdf file. In the sdf, the field names are without
the unit and description, as those are accessible in the file-format in other columns.
Depending on whether we varied the inlet or outlet, we have to specify the correct name.

```python
from vclibpy.utils.plotting import plot_sdf_map
plot_sdf_map(
filepath_sdf=save_path_sdf,
nd_data="COP",
first_dimension="T_eva_in",
second_dimension="T_con_in",
second_dimension="T_con_in" if use_condenser_inlet else "T_con_out",
fluids=["Propane"],
flowsheets=["Standard"]
)
Expand Down
7 changes: 4 additions & 3 deletions docs/source/examples/e7_vapor_injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ solver settings and inputs to vary:
```python
save_path = r"D:\00_temp\vapor_injection"
T_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]
T_con_in_ar = [30 + 273.15, 50 + 273.15, 60 + 273.15]
T_con_ar = [30 + 273.15, 50 + 273.15, 60 + 273.15]
n_ar = [0.3, 0.7, 1]
```

Expand All @@ -102,9 +102,10 @@ from vclibpy import utils
utils.full_factorial_map_generation(
heat_pump=heat_pump,
save_path=save_path,
T_con_in_ar=T_con_in_ar,
T_con_ar=T_con_ar,
T_eva_in_ar=T_eva_in_ar,
n_ar=n_ar,
use_condenser_inlet=True,
use_multiprocessing=False,
save_plots=True,
m_flow_con=0.2,
Expand Down Expand Up @@ -161,7 +162,7 @@ heat_pump = VaporInjectionEconomizer(
utils.full_factorial_map_generation(
heat_pump=heat_pump,
save_path=r"D:\00_temp\vapor_injection_economizer",
T_con_in_ar=T_con_in_ar,
T_con_ar=T_con_ar,
T_eva_in_ar=T_eva_in_ar,
n_ar=n_ar,
use_multiprocessing=False,
Expand Down
16 changes: 10 additions & 6 deletions examples/e6_simple_heat_pump.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# # Example for a heat pump with a standard cycle

def main():
def main(use_condenser_inlet: bool = True):
# Let's start the complete cycle simulation with the
# most basic flowsheet, the standard-cycle. As all flowsheets
# contain a condenser and an evaporator, we defined a common BaseCycle
Expand Down Expand Up @@ -61,9 +61,11 @@ def main():
)
# As in the other example, we can specify save-paths,
# solver settings and inputs to vary:
# Note that T_con can either be inlet or outlet, depending on the setting
# of `use_condenser_inlet`. Per default, we simulate the inlet, T_con_in
save_path = r"D:\00_temp\simple_heat_pump"
T_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]
T_con_in_ar = [30 + 273.15, 50 + 273.15, 70 + 273.15]
T_con_ar = [30 + 273.15, 50 + 273.15, 70 + 273.15]
n_ar = [0.3, 0.7, 1]

# Now, we can generate the full-factorial performance map
Expand All @@ -77,9 +79,10 @@ def main():
save_path_sdf, save_path_csv = utils.full_factorial_map_generation(
heat_pump=heat_pump,
save_path=save_path,
T_con_in_ar=T_con_in_ar,
T_con_ar=T_con_ar,
T_eva_in_ar=T_eva_in_ar,
n_ar=n_ar,
use_condenser_inlet=use_condenser_inlet,
use_multiprocessing=False,
save_plots=True,
m_flow_con=0.2,
Expand All @@ -101,7 +104,7 @@ def main():
import matplotlib.pyplot as plt
x_name = "n in - (Relative compressor speed)"
y_name = "COP in - (Coefficient of performance)"
plt.scatter(df[x_name], df[y_name])
plt.scatter(df[x_name], df[y_name], s=20)
plt.ylabel(y_name)
plt.xlabel(x_name)
plt.show()
Expand All @@ -110,16 +113,17 @@ def main():
# We can also use existing 3D-plotting scripts in vclibpy to analyze the
# dependencies. For this, we need the .sdf file. In the sdf, the field names are without
# the unit and description, as those are accessible in the file-format in other columns.
# Depending on whether we varied the inlet or outlet, we have to specify the correct name.
from vclibpy.utils.plotting import plot_sdf_map
plot_sdf_map(
filepath_sdf=save_path_sdf,
nd_data="COP",
first_dimension="T_eva_in",
second_dimension="T_con_in",
second_dimension="T_con_in" if use_condenser_inlet else "T_con_out",
fluids=["Propane"],
flowsheets=["Standard"]
)


if __name__ == "__main__":
main()
main(use_condenser_inlet=False)
7 changes: 4 additions & 3 deletions examples/e7_vapor_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def main():
# solver settings and inputs to vary:
save_path = r"D:\00_temp\vapor_injection"
T_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]
T_con_in_ar = [30 + 273.15, 50 + 273.15, 60 + 273.15]
T_con_ar = [30 + 273.15, 50 + 273.15, 60 + 273.15]
n_ar = [0.3, 0.7, 1]

# Now, we can generate the full-factorial performance map
Expand All @@ -83,9 +83,10 @@ def main():
utils.full_factorial_map_generation(
heat_pump=heat_pump,
save_path=save_path,
T_con_in_ar=T_con_in_ar,
T_con_ar=T_con_ar,
T_eva_in_ar=T_eva_in_ar,
n_ar=n_ar,
use_condenser_inlet=True,
use_multiprocessing=False,
save_plots=True,
m_flow_con=0.2,
Expand Down Expand Up @@ -127,7 +128,7 @@ def main():
utils.full_factorial_map_generation(
heat_pump=heat_pump,
save_path=r"D:\00_temp\vapor_injection_economizer",
T_con_in_ar=T_con_in_ar,
T_con_ar=T_con_ar,
T_eva_in_ar=T_eva_in_ar,
n_ar=n_ar,
use_multiprocessing=False,
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
numpy>=1.20.0
numpy<=2.0
matplotlib>=3.3.4
coolprop>=6.4.1
sdf>=0.3.5
Expand Down
7 changes: 5 additions & 2 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ class TestExamples(unittest.TestCase):
def setUp(self) -> None:
self.timeout = 100 # Seconds which the script is allowed to run

def _run_example(self, example, timeout=None):
def _run_example(self, example, timeout=None, **kwargs):
ex_py = pathlib.Path(__file__).absolute().parents[1].joinpath("examples", example)
sys.path.insert(0, str(ex_py.parent))
module = importlib.import_module(ex_py.stem)
example_main = getattr(module, "main")
example_main()
example_main(**kwargs)

def test_e1_refrigerant_data(self):
self._run_example(example="e1_refrigerant_data.py")
Expand All @@ -38,6 +38,9 @@ def test_e5_expansion_valve(self):
def test_e6_simple_heat_pump(self):
self._run_example(example="e6_simple_heat_pump.py")

def test_e6_simple_heat_pump_outlet(self):
self._run_example(example="e6_simple_heat_pump.py", use_condenser_inlet=False)

def test_e7_vapor_injection(self):
self._run_example(example="e7_vapor_injection.py")

Expand Down
7 changes: 4 additions & 3 deletions tests/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def _regression_of_examples(self, flowsheet, fluid):

# Just for quick study: Specify concrete points:
T_eva_in_ar = [-10 + 273.15, 273.15]
T_con_in_ar = [30 + 273.15, 70 + 273.15]
T_con_ar = [30 + 273.15, 70 + 273.15]
n_ar = [0.3, 1]

os.makedirs(self.working_dir, exist_ok=True)
Expand All @@ -146,7 +146,7 @@ def _regression_of_examples(self, flowsheet, fluid):
_, path_csv = utils.full_factorial_map_generation(
heat_pump=heat_pump,
save_path=self.working_dir,
T_con_in_ar=T_con_in_ar,
T_con_ar=T_con_ar,
T_eva_in_ar=T_eva_in_ar,
n_ar=n_ar,
use_multiprocessing=False,
Expand All @@ -155,6 +155,7 @@ def _regression_of_examples(self, flowsheet, fluid):
m_flow_eva=0.9,
dT_eva_superheating=5,
dT_con_subcooling=0,
**kwargs
)
path_csv_regression = pathlib.Path(__file__).parent.joinpath(
"regression_data", "reference_results", f"{flowsheet}_{fluid}.csv"
Expand All @@ -171,7 +172,7 @@ def test_vi_ps_propane(self):
self._regression_of_examples("VaporInjectionPhaseSeparator", "Propane")

def test_evi_propane(self):
self.skipTest("EVI works locally, only CI fails.")
#self.skipTest("EVI works locally, only CI fails.")
self._regression_of_examples("VaporInjectionEconomizer", "Propane")

@unittest.skip("not implemented")
Expand Down
2 changes: 1 addition & 1 deletion vclibpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

from vclibpy.datamodels import FlowsheetState, Inputs

__version__ = "0.1.2"
__version__ = "0.2.0"
4 changes: 2 additions & 2 deletions vclibpy/components/compressors/compressor.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def calc_state_outlet(self, p_outlet: float, inputs: Inputs, fs_state: Flowsheet
self.state_inlet.h + (state_outlet_isentropic.h - self.state_inlet.h) /
eta_is
)
fs_state.set(name="eta_is", value=eta_is, unit="%", description="Isentropic efficiency")
fs_state.set(name="eta_is", value=eta_is, unit="-", description="Isentropic efficiency")
self.state_outlet = self.med_prop.calc_state("PH", p_outlet, h_outlet)

def calc_m_flow(self, inputs: Inputs, fs_state: FlowsheetState) -> float:
Expand All @@ -148,7 +148,7 @@ def calc_m_flow(self, inputs: Inputs, fs_state: FlowsheetState) -> float:
self.get_n_absolute(inputs.n)
)
self.m_flow = self.state_inlet.d * V_flow_ref
fs_state.set(name="lambda_h", value=lambda_h, unit="%", description="Volumetric efficiency")
fs_state.set(name="lambda_h", value=lambda_h, unit="-", description="Volumetric efficiency")
fs_state.set(name="V_flow_ref", value=V_flow_ref, unit="m3/s", description="Refrigerant volume flow rate")
fs_state.set(name="m_flow_ref", value=self.m_flow, unit="kg/s", description="Refrigerant mass flow rate")
return self.m_flow
Expand Down
Loading

0 comments on commit ca63180

Please sign in to comment.