-
Notifications
You must be signed in to change notification settings - Fork 453
Conversation
(operational for hard-coded layers, dummy heat transfer coef and resistive boosting)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a layered PTES (Pit Thermal Energy Storage) model by precomputing PTES operational parameters into a single dataset, wiring per-layer PTES components into the sector network, and adding custom solver constraints for layered PTES behavior.
Changes:
- Replace multiple PTES profile outputs with a unified
ptes_operationsdataset built via a newPtesApproximator. - Extend sector-network building to create per-layer PTES buses/stores/charger-discharger links and inter-layer links.
- Add layered-PTES constraints in
solve_network.pyand propagate the new PTES operations input through Snakemake rules.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/solve_network.py | Excludes layered PTES from generic TES constraints; adds layered PTES custom constraints and loads ptes_operations in extra_functionality. |
| scripts/prepare_sector_network.py | Builds layered PTES components from ptes_operations and adjusts PTES boosting/HP handling. |
| scripts/definitions/heat_system.py | Extends heat pump cost mapping for PTES layers and updates waste-heat enum member references. |
| scripts/definitions/heat_source.py | Adds PTES layer heat sources and treats them as STORAGE across helper logic. |
| scripts/build_ptes_operations/run.py | Switches PTES operational profile building to the new PtesApproximator and writes unified dataset. |
| scripts/build_ptes_operations/ptes_temperature_approximator.py | Removes legacy PTES temperature/profile approximator implementation. |
| scripts/build_ptes_operations/ptes_approximator.py | Adds new approximator producing layered parameters (weights, availability, boost ratios, interlayer coefficients). |
| scripts/build_heat_source_utilisation_profiles.py | Uses ptes_operations for PTES(-layer) temperatures and cooling assumptions; closes dataset when enabled. |
| scripts/build_cop_profiles/run.py | Uses ptes_operations for PTES(-layer) source temperatures; closes dataset when enabled. |
| rules/solve_perfect.smk | Adds conditional PTES operations input to solve rule. |
| rules/solve_overnight.smk | Adds conditional PTES operations input to solve rule. |
| rules/solve_myopic.smk | Adds conditional PTES operations input to solve rule. |
| rules/build_sector.smk | Replaces PTES temp/bottom inputs with unified PTES operations input; wires through dependent rules. |
| data/custom_costs.csv | Adjusts PTES charger marginal cost and adds PTES discharger marginal cost entry. |
| config/config.default.yaml | Adds layered PTES config stanza (num_layers, heat_transfer_coefficient). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
top_temperature/bottom_temperature are cast to float, but config validation allows the literals 'forward'/'return'. With such a config this will crash before any helpful error is raised. Either keep support for these string options, or validate early and raise a clear error if only constant temperatures are supported now.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ptes_ds is opened but never closed in this code path, which can leak file handles (especially when add_heat is called repeatedly). Use a context manager (with xr.open_dataset(...) as ptes_ds:) or ensure ptes_ds.close() is called once all PTES-related components (including resistive boosting) are added.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The interlayer flow docstring states p = -Ψ · e but the implementation constrains Link-p - Ψ·Store-e == 0 (no minus sign). Please align the sign convention (either update the constraint or correct the documentation) so that the interlayer link direction matches the intended heat diffusion direction.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HeatSource members for waste heat were renamed to *_WASTE, but other parts of the codebase still reference the old names (e.g. scripts/lib/validation/config/sector.py uses HeatSource.ELECTROLYSIS_waste, etc.). This will raise AttributeError when loading config validation. Please update those remaining references (or provide backwards-compatible aliases) as part of this PR to avoid breaking imports.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message in get_heat_pump_cooling says "PTES heat source" but the condition is now heat_source.source_type == STORAGE, so it will also trigger for ptes layer *. Consider making the message generic (e.g. "Storage heat source requires return_temperature...") to avoid confusion when debugging layered PTES configs.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PtesApproximator is instantiated without the required interlayer_heat_transfer_coefficient argument, which will raise a TypeError at runtime. Either pass the value from sector.district_heating.ptes.layered.heat_transfer_coefficient (or similar) or make the constructor parameter optional with a default and document the default.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layer discharge is wired to heat_source.resource_bus(...) where heat_source is ptes layer X, creating buses like <node> urban central ptes layer 0 heat. Unless those layer heat sources are also included in params.heat_sources (and have utilisation/COP profiles built), these buses will be disconnected from the main <node> urban central heat bus. Either keep all PTES layer discharge on the aggregate ptes resource bus, or ensure the config/params and profile-building rules automatically include the per-layer PTES heat sources when num_layers > 1.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The special-casing for layered PTES heat pump capital_cost only covers PTES_LAYER_0..2, but the enum defines PTES_LAYER_3 and PTES_LAYER_4 as well. If num_layers > 3, the extra layers will incorrectly receive full heat pump capex. Consider handling all ptes layer * sources (or all HeatSourceType.STORAGE except the aggregate PTES) consistently.
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
heat_pump_costs_name special-cases PTES layers only up to PTES_LAYER_2, but HeatSource now defines PTES_LAYER_3 and PTES_LAYER_4 as well. If additional layers are configured, they will fall through to the non-excess-heat heat pump cost category. Extend the list (or use heat_source.source_type == HeatSourceType.STORAGE/string matching) so all PTES layers map consistently.
1 utilisation link distributes to UCH and HP input
Closes # (if applicable).
Changes proposed in this Pull Request
Checklist
Required:
doc/release_notes.rst.If applicable:
scripts/lib/validation.doc/*.rstfiles.