288 water to water heat pump bypass mode#344
Conversation
… in heattransfer solver asset.
There was a problem hiding this comment.
Pull request overview
This PR introduces a bypass mode for the water-to-water heat pump / heat transfer asset and propagates related sign/setpoint and controller-path/factor changes through the controller layer, solver asset equations, and unit/integration tests.
Changes:
- Add
bypass_modesupport to the solverHeatTransferAsset, with separate “normal” vs “bypass” equation generation. - Extend heat pump/controller setpoints to support bypass and primary-side mass-flow/pressure control, and adjust network factor/path handling.
- Update a broad set of unit/integration tests to reflect new sign conventions, setpoint keys, and solver behavior.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| unit_test/solver/network/assets/test_heat_transfer_asset.py | Updates expectations for equation selection/call counts and mass-flow setup in solver-level tests. |
| unit_test/integration/test_heat_transfer_asset.py | Adjusts integration scenarios for updated mass-flow initialization and new prescribe flags. |
| unit_test/entities/test_production_cluster.py | Adapts convergence test to new sign convention behavior. |
| unit_test/entities/test_heat_pump.py | Updates heat pump tests for new sign conventions and additional solver state; currently misaligned with new required setpoint keys. |
| unit_test/entities/test_heat_exchanger.py | Updates mass-flow setup and expected output sign. |
| unit_test/entities/test_ates_cluster.py | Adjusts expected well temperatures due to changed ATES behavior. |
| unit_test/entities/controller/test_controller_new_class.py | Updates expectations for factor_to_first_network now being a list of factors. |
| unit_test/entities/controller/test_controller_network.py | Updates factor representation and storage setpoint expectations; adapts pressure-setting behavior. |
| src/omotes_simulator_core/solver/network/assets/heat_transfer_asset.py | Implements bypass mode and refactors equation generation; changes flow-direction handling and electric power computation. |
| src/omotes_simulator_core/infrastructure/app.py | Changes default simulation window/timestep and hardcodes a bypass test run + CSV export in __main__. |
| src/omotes_simulator_core/entities/network_controller.py | Refactors factor/path application, storage charge/discharge logic, heat-transfer setpoints, and pressure-setting key selection. |
| src/omotes_simulator_core/entities/assets/utils.py | Changes heat-demand↔mass-flow conversion to use internal energy difference instead of heat capacity approximation. |
| src/omotes_simulator_core/entities/assets/production_cluster.py | Adjusts mass-flow calculation sign and convergence criterion. |
| src/omotes_simulator_core/entities/assets/heat_pump.py | Adds bypass setpoint support, primary-side control flag, and updates setpoint parsing/sign conventions. |
| src/omotes_simulator_core/entities/assets/heat_exchanger.py | Adjusts heat-loss sign convention in outputs. |
| src/omotes_simulator_core/entities/assets/demand_cluster.py | Updates convergence check sign usage (now sensitive to negative allocations). |
| src/omotes_simulator_core/entities/assets/controller/controller_network.py | Changes factor tracking to list-of-factors and uses a product; extends storage setpoints; updates pressure-setting API. |
| src/omotes_simulator_core/entities/assets/controller/controller_heat_transfer.py | Adds bypass option and updates how primary/secondary heat demand is set (factor vs bypass behavior). |
| src/omotes_simulator_core/entities/assets/ates_cluster.py | Updates temperature assignment and convergence logic; tweaks ROSIM initialization/run cadence; adds heat supplied computation. |
| src/omotes_simulator_core/entities/assets/asset_defaults.py | Adds PROPERTY_BYPASS constant. |
| src/omotes_simulator_core/entities/assets/asset_abstract.py | Removes solver_asset type annotation from the base abstract asset. |
| src/omotes_simulator_core/adapter/transforms/controller_mapper.py | Changes “root network” selection for path computation and updates how paths are generated. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
src/omotes_simulator_core/entities/assets/controller/controller_network.py
Show resolved
Hide resolved
src/omotes_simulator_core/solver/network/assets/heat_transfer_asset.py
Outdated
Show resolved
Hide resolved
vanmeerkerk
left a comment
There was a problem hiding this comment.
Er is erg veel gewijzgd waarvan sommige onderdelen naar mijn mening een apart issue hadden moeten worden. Over het algemeen ziet het er oké uit nog wat docstring opmerkingen.
Ik vermoed wel dat er nu een fout wordt gemaakt in het heat_transfer asset met de huidige implementatie.
| SECONDARY + PROPERTY_TEMPERATURE_OUT: 273.15 + 80, | ||
| SECONDARY + PROPERTY_TEMPERATURE_IN: 273.15 + 50, | ||
| PROPERTY_SET_PRESSURE: False, | ||
| if bypass: |
There was a problem hiding this comment.
Ik heb hier wel een vraag over. Zetten we nu standaard temperaturen in dit asset met set_asset of is dit alleen een initialisatie stap?
There was a problem hiding this comment.
Klopt de volgorder van de temperaturen; ik zou verwachtten dat PRIM_OUT gleijk moet zijn aan SEC_IN. Dit lijkt nu niet het geval?
There was a problem hiding this comment.
Ja temepraturen worden nu hard gezet,
Voor Bypass mode maakt het niet uit, want dan worden ze niet gebruikt.
In normale modus moeten we eigenlijk nog de waardes ophalen uit de carrier en die gebruiken.
Maar dit zat in de vorige implementatie ook nog niet
src/omotes_simulator_core/entities/assets/controller/controller_network.py
Show resolved
Hide resolved
| for storage in self.storages: | ||
| storage_settings[storage.id] = { | ||
| PROPERTY_HEAT_DEMAND: +1 * storage.effective_max_charge_power * factor, | ||
| PROPERTY_TEMPERATURE_OUT: storage.temperature_out, |
There was a problem hiding this comment.
Waarom heb je de temperatuur nodig voor een storage? Deze wordt toch niet geset maar gebasseerd op de internal state?
There was a problem hiding this comment.
ATES gebruikt ze om mass flow uit te rekenen. en ideal storage zal dat ook doen. In iede geval voor initiele gok
| @@ -270,7 +281,7 @@ def get_equations(self) -> list[EquationObject]: | |||
| ) = self.get_ordered_connection_point_list() | |||
|
|
|||
| if np.all(np.abs(self.prev_sol[0:-1:3]) < MASSFLOW_ZERO_LIMIT): | |||
There was a problem hiding this comment.
Klopt het nu dat we alleen de richting zetten op basis van de vorige oplossing als de stroming 0 was (< MASSFLOW_ZERO_LIMIT); ik vraag mij af of dit goed gaat.
There was a problem hiding this comment.
Nee niet helemaal, want anders zetten wegebruiken we flow_direction_rpimary en die heb ik nu ook gezet op mass flow richting van vorige iteratie
| if iteration_flow_direction_secondary == FlowDirection.ZERO: | ||
| mset = 0.0 | ||
| if self.iteration_flow_direction_secondary == FlowDirection.ZERO: | ||
| mset = self.mass_flow_rate_rate_set_point_secondary |
There was a problem hiding this comment.
Dus als 0 forceren we niet langer 0 maar gaan we terug naar het setpoint; dit kan niet juist zijn?
There was a problem hiding this comment.
Als je dit doet kan je net zo goed deze if loop weghalen en altijd het setpoint zetten. Ik denk dat je hier een fout maakt om het te laten werken. Ik herinner mij dat het zetten van mset=0.0 resulteerde in een matrix fout maar dat zit eerder in hoe je je setpoints zet op basis van een vorige oplossing.
There was a problem hiding this comment.
Het lijkt nu allemaal te werekn, ook zero flow. Misschien overgang niet, maar denk dat het ook goed gaat omdat je telkens met nul als vorige oplossing begint
| if (self.iteration_flow_direction_primary != FlowDirection.ZERO) or ( | ||
| self.iteration_flow_direction_secondary != FlowDirection.ZERO | ||
| ): | ||
| equations.append( |
There was a problem hiding this comment.
Hier gaat echt iets fout met het zetten vvan m=0.0
There was a problem hiding this comment.
Nee want dat gaat goed, je kunt gewoon nul zetten en dan zal het ook nog werekn
src/omotes_simulator_core/solver/network/assets/heat_transfer_asset.py
Outdated
Show resolved
Hide resolved
|
@vanmeerkerk ik heb alles bijgewerkt. Implementatie is iets verandert waardoor sommige zaken net iets anders gaan, dus misschien goed om even samen te zitten om door te lopen. |
Unit test are not yet working but code seems to be working