From d86b7af8ca431a887e34ed94b65ea2cd194a67e3 Mon Sep 17 00:00:00 2001 From: Francesco Witte Date: Sun, 17 May 2026 09:51:50 +0200 Subject: [PATCH] Implement example of bulk setting pressure drops --- docs/integration/workflows.ipynb | 74 ++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/docs/integration/workflows.ipynb b/docs/integration/workflows.ipynb index 82d60a1f..46ef9750 100644 --- a/docs/integration/workflows.ipynb +++ b/docs/integration/workflows.ipynb @@ -126,7 +126,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4f9138b2", + "id": "409f7de1", "metadata": {}, "outputs": [], "source": [ @@ -135,9 +135,16 @@ " PowerBus, PowerSink, Pump, Sink, Source, Turbine,\n", ")\n", "from tespy.connections import Connection, PowerConnection\n", - "from tespy.models import ModelTemplate\n", - "\n", - "\n", + "from tespy.models import ModelTemplate" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4f9138b2", + "metadata": {}, + "outputs": [], + "source": [ "class ORCModel(ModelTemplate):\n", "\n", " def _parameter_lookup(self) -> dict:\n", @@ -344,10 +351,14 @@ "\n", "- `[\"Components\", ...]` and `[\"Connections\", ...]` for standard network\n", " attributes,\n", - "- `{\"get\": callable}` for the read-only computed COP,\n", - "- `{\"get\": ..., \"set\": ...}` for a COP target - reading it returns the current\n", - " target, writing it activates a `UserDefinedEquation` that enforces the target\n", - " value. Passing `None` deactivates it and restores the degree of freedom.\n", + "- `{\"get\": callable}` for a read-only derived quantity - here the computed COP,\n", + "- `{\"get\": ..., \"set\": ...}` for a read/write custom quantity - here a COP\n", + " target that reads back the current target value and, when written, activates a\n", + " `UserDefinedEquation` that enforces it. Passing `None` deactivates the\n", + " constraint and restores the degree of freedom,\n", + "- `{\"set\": callable}` for a write-only parameter with arbitrary setter logic -\n", + " here used to assign a pressure drop to all heat exchanger working-fluid sides\n", + " in one call.\n", "\n", "See the API docs of\n", "{py:class}`ModelTemplate ` for more\n", @@ -357,7 +368,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1dd39c8a", + "id": "37742ede", "metadata": {}, "outputs": [], "source": [ @@ -374,9 +385,16 @@ "from tespy.connections import Connection\n", "from tespy.connections import PowerConnection\n", "from tespy.models import ModelTemplate\n", - "from tespy.tools import UserDefinedEquation\n", - "\n", - "\n", + "from tespy.tools import UserDefinedEquation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1dd39c8a", + "metadata": {}, + "outputs": [], + "source": [ "class HeatPumpModel(ModelTemplate):\n", "\n", " def _parameter_lookup(self):\n", @@ -388,6 +406,7 @@ " \"lower cycle mass flow\": [\"Connections\", \"a1\", \"m\"],\n", " \"lower cycle condensation temperature\": [\"Connections\", \"a3\", \"T_bubble\"],\n", " \"cop\": {\"get\": self.calc_cop, \"set\": self.set_cop},\n", + " \"heat_exchangers_all_dp\": {\"set\": self.set_all_hx_dp},\n", " }\n", "\n", " def calc_cop(self):\n", @@ -426,6 +445,11 @@ " ude.is_set = True\n", " ude.params[\"cop\"] = value\n", "\n", + " def set_all_hx_dp(self, value):\n", + " self.nw.get_comp(\"internal heat exchanger\").set_attr(dp1=value, dp2=value)\n", + " self.nw.get_comp(\"evaporator low\").set_attr(dp2=value)\n", + " self.nw.get_comp(\"condenser high\").set_attr(dp=value)\n", + "\n", " def _create_network(self):\n", " super()._create_network()\n", "\n", @@ -611,6 +635,32 @@ "model.get_parameter(\"lower cycle condensation temperature\")" ] }, + { + "cell_type": "markdown", + "id": "9a425d97", + "metadata": {}, + "source": [ + "#### Bulk pressure-drop assignment\n", + "\n", + "`\"heat_exchangers_all_dp\"` uses the write-only `{\"set\": callable}` form. The\n", + "callable receives the requested value and distributes it to every working-fluid\n", + "side of every heat exchanger: `dp1` and `dp2` on the internal heat exchanger\n", + "(both sides carry refrigerant), `dp2` on the evaporator (the air side `dp1` is\n", + "left untouched), and `dp` on the high-side condenser." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9e81dcb", + "metadata": {}, + "outputs": [], + "source": [ + "model.set_parameters(**{\"heat_exchangers_all_dp\": 0.05})\n", + "model.solve_model_design()\n", + "model.get_parameter(\"lower cycle condensation temperature\")" + ] + }, { "cell_type": "markdown", "id": "41c2cc8a",