openego / powerd-data

GNU Affero General Public License v3.0
1 stars 0 forks source link

High AC peak loads in Germany #139

Closed ClaraBuettner closed 2 months ago

ClaraBuettner commented 8 months ago

Compared to the entsoe-data, our peaks in the AC loads in Germany seem to be too high, it is 108 GW. According to the entsoe, the peak load was about 80GW in 2019. We should check if we just overestimate the peak load or if also our annual sum is too high.

ClaraBuettner commented 8 months ago

@IsGut Could you post the diagram you showed us here?

IsGut commented 8 months ago

DE_month_12 Total Load DE DE_month_1 DE_month_2 DE_month_3 DE_month_4 DE_month_5 DE_month_6 DE_month_7 DE_month_8 DE_month_9 DE_month_10 DE_month_11

CarlosEpia commented 7 months ago

To start the analysis the total load was divided into the 4 different components it is composed of: Demand_by_sector Demand_by_sector_areas

CarlosEpia commented 7 months ago

The problem with the peak is likely related to the households or CTS demands. The hh demands were disaggregated by type of load profile: hh_demand_by_type hh_demand_by_type_area

CarlosEpia commented 7 months ago

In general it look like the profiles make sense. The total sum of the loads matches the annual consumption, but the peaks are too high. The code is working according to the described methodology proposed in https://energyinformatics.springeropen.com/articles/10.1186/s42162-022-00201-y/figures/4. Therefore, it will be necessary to implement something in addition to match also the expected peak loads.

CarlosEpia commented 7 months ago

According to IEE the load curve for Germany for a working day in January 2019 looks like: image But our load profile looks like this: image

Our smallest demand is 13GW lower than the measured data. Our max peak is around 35 GW higher. Additionally, the temporal allocation of the peaks differs.

CarlosEpia commented 7 months ago

The industry demand data is reliable to a certain extent. Therefore I would propose to keep the industry demand, while scaling the sum of CTS and HH to match the measured hourly demand provided by entso-e or IEA. What do you think @ClaraBuettner and @ulfmueller ?

CarlosEpia commented 7 months ago

Since Demand Regio is already installed in powerD-data, it is an option to use it for status and future scenarios.

CarlosEpia commented 7 months ago

The default scenario is 2015. Using the code below, demand for each of the nuts3 zones is created every 15 minutes. df_CTS = temporal.disagg_temporal_power_CTS(detailed=False, use_nuts3code=True) df_hh = temporal.disagg_temporal_power_housholds_slp(by= "population") df_ind = temporal.disagg_temporal_industry(source = "power")

Total demand CTS= 154.6 TWh Total demand hh= 132.0 TWh Total demand industry= 239.7 TWh

CarlosEpia commented 7 months ago

The demand per sector the first days of 2015 looks like this: demand_per_sector_2015

CarlosEpia commented 7 months ago

The total demand for the first days if 2015 looks like this: total_demand_2015

According to IEA the demand on a weekday that week was: image

CarlosEpia commented 7 months ago

The peaks are significantly different 88 GW vs 54 GW. On the other hand, the lowest consumptions are similar: 34 GW vs 38 GW.

CarlosEpia commented 7 months ago

Demand Regio allows the generation of demand data till 2035. For that year, it is possible to generate CTS (136.8 TWh) and Industrial demand (247.6 TWh). There is a problem when executing temporal.disagg_temporal_power_housholds_slp(by= "population")

File "/tmp/ipykernel_5537/1952142773.py", line 1, in <cell line: 1> df_hh = temporal.disagg_temporal_power_housholds_slp(by= "population")

File "/home/carlos/powerd-data-exc-new-air/demandregio-disaggregator/disaggregator/disaggregator/temporal.py", line 545, in disagg_temporal_power_housholds_slp sv_yearly = ((disagg_households_power(by=by,

File "/home/carlos/powerd-data-exc-new-air/demandregio-disaggregator/disaggregator/disaggregator/spatial.py", line 66, in disagg_households_power power_nuts0 = elc_consumption_HH(year=year) / 1e3

File "/home/carlos/powerd-data-exc-new-air/demandregio-disaggregator/disaggregator/disaggregator/data.py", line 85, in elc_consumption_HH df = float(database_get('spatial', table_id=cfg[key]['table_id'],

File "/home/carlos/powerd-data-exc-new-air/demandregio-disaggregator/disaggregator/disaggregator/data.py", line 1998, in database_get return database_raw(query, force_update=force_update)

File "/home/carlos/powerd-data-exc-new-air/demandregio-disaggregator/disaggregator/disaggregator/config.py", line 109, in database_raw raise ValueError('The returned pd.DataFrame is empty!')

ValueError: The returned pd.DataFrame is empty!

CarlosEpia commented 7 months ago

When using the alternative temporal.disagg_temporal_power_housholds_slp(by= "households")

File "/tmp/ipykernel_5537/61527220.py", line 1, in <cell line: 1> df_hh = temporal.disagg_temporal_power_housholds_slp(by= "households")

File "/home/carlos/powerd-data-exc-new-air/demandregio-disaggregator/disaggregator/disaggregator/temporal.py", line 545, in disagg_temporal_power_housholds_slp sv_yearly = ((disagg_households_power(by=by,

File "/home/carlos/env/powerD/lib/python3.8/site-packages/pandas/core/generic.py", line 5989, in getattr return object.getattribute(self, name)

AttributeError: 'DataFrame' object has no attribute 'to_frame'