[FEATURE] Aggregating heat pump and resistive heater discards their individual characteristics
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 35/100
Direzione di ricerca
Start with aggregate_district_heating_components in edisgo/tools/tools.py and cop_oedb in edisgo/io/timeseries_import.py, then trace constraint_hp_operation and the heatpumps and heat_storage dictionaries in powermodels_io.py. Read how the existing heat balance handles PtH units before changing it. Done means the two units retain their own power, COP, bus and dispatch through the handover and contribute jointly to district heating demand.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
edisgo/tools/tools.py::aggregate_district_heating_components merges the central heat
pump and the central resistive heater of a district heating area into a single load
component. Rated powers are added, a harmonic-mean COP is synthesised, and the resistive
heater is deleted from loads_df, cop_df and heat_demand_df.
The two components have fundamentally different characteristics — a heat pump with a
time-varying COP of ~2-4, and a resistive heater with a COP of ~1. Merging them discards
that distinction and, with it, the possibility of dispatching them optimally. The split
between the two is no longer an outcome of the optimisation; it is fixed by a rule before
the optimiser sees the problem.
What is lost
1. The dispatch decision. The merge hard-codes a merit order: the heat pump runs up to
its rated power, the resistive heater covers the remainder.
el_demand = (heat_demand_df[district_hp] / cop_df[district_hp]).clip(lower=0)
hp_p_set = loads_df.at[district_hp, "p_set"]
df = pd.concat([
(el_demand.clip(upper=hp_p_set) / el_demand).fillna(1).to_frame(district_hp),
((el_demand - el_demand.clip(upper=hp_p_set)) / el_demand).fillna(0).to_frame(district_rh),
], axis=1)
This is a reasonable heuristic for a cost-minimising dispatch, but it is only a heuristic.
It cannot represent a resistive heater running while the heat pump has headroom — which is
exactly what a system-level optimisation does when electricity is abundant, and what
eTraGo actually produces (see below).
2. The two COP time series. They are collapsed into one synthetic series:
new_cop = 1 / (df / cop_df[district_hps.index]).sum(axis=1)
The harmonic mean is the correct way to preserve total electricity demand for the assumed
split — but it is only correct for that split. Once the aggregated component exists, no
other split can be evaluated, because the individual COPs are gone.
3. The grid location of each unit. new_p_set is the sum of both rated powers and is
assigned to the heat pump's bus; the resistive heater's load is dropped. Where the two
units sit at different busbars, the electrical load appears entirely at one of them.
4. Both units currently receive a heat-pump COP. timeseries_import.py::cop_oedb
fetches COP per weather cell for every PtH unit, so the resistive heater's cop_df column
holds a heat-pump COP of ~2-4 rather than ~1. The harmonic mean is therefore computed from
a wrong input for one of its two terms. This is a defect in its own right, but it only
becomes visible once the components are treated individually.
eTraGo dispatches them separately
The aggregation assumption is contradicted by the upstream data it is meant to represent.
Grid 30885, area 2544, scenario eGon2035 (results_dg_1606_fullflex_nodg):
| carrier | p_nom (MW) | annual electrical (MWh) | hours dispatched |
|---|---|---|---|
| central_heat_pump | 0.329 | 842.4 | 2750 |
| central_resistive_heater | 0.420 | 441.1 | 1248 |
Two distinct dispatch patterns. eGo currently sums them to a single 1283.5 MWh series
(see openego/eGo — companion issue on the interface side), and eDisGo then merges the two
components as well, so the distinction is destroyed twice over.
Where it happens
edisgo/tools/tools.py::aggregate_district_heating_components(~line 1124 onwards) —
the merge, the synthetic COP, and the deletion of the resistive heater.edisgo/io/timeseries_import.py::cop_oedb— assigns a heat-pump COP to resistive
heaters.
Proposed direction
Keep the heat pump and the resistive heater as separate components throughout, each with
its own p_set, its own COP series (~1 for the resistive heater) and its own bus, and let
the heat balance be satisfied by the two of them jointly rather than by a pre-merged
surrogate. In the Julia OPF this means several PtH units contributing to one district
heating area's heat balance instead of exactly one, which is a change to
constraint_hp_operation and the heatpumps/heat_storage dictionaries built in
powermodels_io.py.
Where eTraGo dispatch is handed down, the per-component electrical time series should be
adopted directly rather than re-derived from an aggregate.
Related
- Companion issue in openego/eGo:
interface.py::central_heatsumscentral_heat_pump
andcentral_resistive_heaterinto oneheat_pump_central_active_powerseries and one
heat_pump_central_p_nomscalar. Both sides have to change for the per-component
information to survive the handover. ISSUE_edisgo_dh_demand_scaling.md— same function, separate defect.
- Lingua principale
- Python
- Stelle
- 48
- Fork
- 22
- Merge medio
- 1g 8h
- PR unite (30g)
- 37
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di openego/eDisGo
-
area: database bug priority: low
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
bug correctness priority: medium
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
I maintainer di solito rispondono entro 1 giorno
-
[BUG] Spatial complexity reduction merges MV and LV buses when an LV grid has the ID of the MV gridApertabug correctness priority: high
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
bug correctness priority: medium
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
OPF docs: explain where the curtailment request comes from and how versions 3 and 4 handle itApertaarea: opf documentation priority: low
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di openego/eDisGo
Issue simili
-
bug good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
graphql-python/graphql-core#304 ·
I maintainer di solito rispondono entro 1 giorno
-
docs size:S
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
Gathin23/cleanyourtv#3464 ·
I maintainer di solito rispondono entro 1 giorno
-
documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno