Breakthrough-Energy / PowerSimData

Simulation framework
https://breakthrough-energy.github.io/docs/
MIT License
52 stars 40 forks source link

Support hydro inflow functionality #691

Closed FabianHofmann closed 2 years ago

FabianHofmann commented 2 years ago

Purpose

Support conversion of hydro reservoirs with inflow time-series.

What the code is doing

For each storage unit with an inflow time series, an artificial bus is created. There the storage unit together with a new inflow generator is located. The new bus is linked to the network via a DC line of the output capacity of the storage unit.

Testing

Manual inspection

Time estimate

10 min

FabianHofmann commented 2 years ago

@rouille FYI, this is a initial draft, so far it seems to work fine. For the profile assignment: The artificial inflow plants are named after the storage unit with a suffix "_inflow". Missing points:

rouille commented 2 years ago

Do we still need the warnings in _get_dtorage_storagedata, _get_storage_gencost and _get_storage_gen? These are private functions called from the private method _read_network of the FromPyPSA clas using storage_units and stores as arguments. Not sure what can go wrong .

rouille commented 2 years ago

I do that:

>>> from powersimdata.network.europe_tub.model import TUB
>>> from powersimdata.input.converter.pypsa_to_grid import FromPyPSA
>>> tub = TUB("Europe", reduction=256)
Title: PyPSA-Eur: An Open Optimisation Model of the European Transmission System (Dataset)
Keywords: power system model, capacity expansion model, energy system model, electricity system model, python
Publication date: 2022-09-10
DOI: 10.5281/zenodo.6913032
Total size: 2075.6 MB

Link: https://zenodo.org/api/files/7528030f-2993-4f54-83e4-9fdd223b9ba5/networks.zip   size: 2075.6 MB
networks.zip is already downloaded correctly.
All files have been downloaded.
>>> tub.build()
INFO:pypsa.io:Imported network elec_s_256_ec.nc has buses, carriers, generators, lines, links, loads, storage_units, stores
>>> grid = FromPyPSA(tub.network)
/Users/brdo/Collaboration/TUB/powersimdata/input/converter/pypsa_to_grid.py:234: UserWarning: Substations could not be parsed.
  warnings.warn("Substations could not be parsed.")
/Users/brdo/Collaboration/TUB/powersimdata/input/converter/pypsa_to_grid.py:347: FutureWarning: Behavior when concatenating bool-dtype and numeric-dtype arrays is deprecated; in a future version these will cast to object dtype (instead of coercing bools to numeric values). To retain the old behavior, explicitly cast bool-dtype arrays to numeric dtype.
  plant = pd.concat([plant, gen_inflow])
>>> grid.plant["type"]
plant_id
AL1 0 offwind-ac      offwind-ac
AL1 0 oil                    oil
AL1 0 onwind              onwind
AL1 0 ror                    ror
AL1 0 solar                solar
                         ...    
SE2 7 hydro inflow           NaN
SE2 8 hydro inflow           NaN
SE2 9 hydro inflow           NaN
SI1 0 hydro inflow           NaN
SK1 0 hydro inflow           NaN
Name: type, Length: 1449, dtype: object

type is NaN for for generators with inflow. It needs to be set tohydro or PHS.

>>> grid.dcline.tail(300)[["Pmin", "Pmax", "from_bus_id", "to_bus_id"]]
                          Pmin  Pmax    from_bus_id     to_bus_id
dcline_id                                                        
ES1 2 battery discharger   0.0   0.0  ES1 2 battery         ES1 2
ES1 3 battery discharger   0.0   0.0  ES1 3 battery         ES1 3
ES1 4 battery discharger   0.0   0.0  ES1 4 battery         ES1 4
ES1 5 battery discharger   0.0   0.0  ES1 5 battery         ES1 5
ES1 6 battery discharger   0.0   0.0  ES1 6 battery         ES1 6
...                        ...   ...            ...           ...
SE2 7 hydro charge         NaN  -0.0          SE2 7  SE2 7 inflow
SE2 8 hydro charge         NaN  -0.0          SE2 8  SE2 8 inflow
SE2 9 hydro charge         NaN  -0.0          SE2 9  SE2 9 inflow
SI1 0 hydro charge         NaN  -0.0          SI1 0  SI1 0 inflow
SK1 0 hydro charge         NaN  -0.0          SK1 0  SK1 0 inflow

[300 rows x 4 columns]

Should discharger be discharge? I guess this won't matter if we use bi-directional HVDC (see @BainanXia comment)

FabianHofmann commented 2 years ago

@rouille I changed the generator type to "inflow" as this is more specific.

rouille commented 2 years ago

@rouille I changed the generator type to "inflow" as this is more specific.

Ok. We will have to modify the model immutables to reflect that.

rouille commented 2 years ago

@FabianHofmann, i find the indexing a little bit confusing/inconsistent. Just pulled your latest commits and did that

>>> from powersimdata.network.europe_tub.model import TUB
>>> from powersimdata.input.converter.pypsa_to_grid import FromPyPSA
>>> tub = TUB("Europe", reduction=256)
Title: PyPSA-Eur: An Open Optimisation Model of the European Transmission System (Dataset)
Keywords: power system model, capacity expansion model, energy system model, electricity system model, python
Publication date: 2022-09-10
DOI: 10.5281/zenodo.6913032
Total size: 2075.6 MB

Link: https://zenodo.org/api/files/7528030f-2993-4f54-83e4-9fdd223b9ba5/networks.zip   size: 2075.6 MB
networks.zip is already downloaded correctly.
All files have been downloaded.
>>> tub.build()
INFO:pypsa.io:Imported network elec_s_256_ec.nc has buses, carriers, generators, lines, links, loads, storage_units, stores
>>> grid = FromPyPSA(tub.network)
/Users/brdo/Collaboration/TUB/powersimdata/input/converter/pypsa_to_grid.py:232: UserWarning: Substations could not be parsed.
  warnings.warn("Substations could not be parsed.")
>>> grid.dcline
              from_bus_id to_bus_id  status  Pf  Pt  ...  pypsa_marginal_cost  pypsa_terrain_factor  pypsa_ramp_limit_up  pypsa_ramp_limit_down  pypsa_p_nom_opt
dcline_id                                            ...                                                                                                        
14811              IT1 16     GR1 0     NaN NaN NaN  ...                  0.0                   1.0                  NaN                    NaN              0.0
5640                ES4 0     ES1 3     NaN NaN NaN  ...                  0.0                   1.0                  NaN                    NaN              0.0
13589               IT1 7     IT3 0     NaN NaN NaN  ...                  0.0                   1.0                  NaN                    NaN              0.0
14802              IT1 15     ME1 0     NaN NaN NaN  ...                  0.0                   1.0                  NaN                    NaN              0.0
14825              FR1 38     ES1 1     NaN NaN NaN  ...                  0.0                   1.0                  NaN                    NaN              0.0
...                   ...       ...     ...  ..  ..  ...                  ...                   ...                  ...                    ...              ...
SE2 7 hydro  SE2 7 inflow     SE2 7     NaN NaN NaN  ...                  NaN                   NaN                  NaN                    NaN              NaN
SE2 8 hydro  SE2 8 inflow     SE2 8     NaN NaN NaN  ...                  NaN                   NaN                  NaN                    NaN              NaN
SE2 9 hydro  SE2 9 inflow     SE2 9     NaN NaN NaN  ...                  NaN                   NaN                  NaN                    NaN              NaN
SI1 0 hydro  SI1 0 inflow     SI1 0     NaN NaN NaN  ...                  NaN                   NaN                  NaN                    NaN              NaN
SK1 0 hydro  SK1 0 inflow     SK1 0     NaN NaN NaN  ...                  NaN                   NaN                  NaN                    NaN              NaN

[1189 rows x 51 columns]
>>> grid.bus
              type  Pd  Qd  Gs  Bs  zone_id  ...  pypsa_type  pypsa_unit  pypsa_v_mag_pu_set  pypsa_v_mag_pu_min  pypsa_v_mag_pu_max  pypsa_sub_network
bus_id                                       ...                                                                                                       
AL1 0            3 NaN NaN NaN NaN      NaN  ...                    None                 1.0                 0.0                 inf                   
AT1 0            1 NaN NaN NaN NaN      NaN  ...                    None                 1.0                 0.0                 inf                   
AT1 1            1 NaN NaN NaN NaN      NaN  ...                    None                 1.0                 0.0                 inf                   
AT1 2            1 NaN NaN NaN NaN      NaN  ...                    None                 1.0                 0.0                 inf                   
AT1 3            1 NaN NaN NaN NaN      NaN  ...                    None                 1.0                 0.0                 inf                   
...            ...  ..  ..  ..  ..      ...  ...         ...         ...                 ...                 ...                 ...                ...
SE2 7 inflow     1 NaN NaN NaN NaN      NaN  ...         NaN         NaN                 NaN                 NaN                 NaN                NaN
SE2 8 inflow     1 NaN NaN NaN NaN      NaN  ...         NaN         NaN                 NaN                 NaN                 NaN                NaN
SE2 9 inflow     1 NaN NaN NaN NaN      NaN  ...         NaN         NaN                 NaN                 NaN                 NaN                NaN
SI1 0 inflow     1 NaN NaN NaN NaN      NaN  ...         NaN         NaN                 NaN                 NaN                 NaN                NaN
SK1 0 inflow     1 NaN NaN NaN NaN      NaN  ...         NaN         NaN                 NaN                 NaN                 NaN                NaN

[892 rows x 32 columns]
>>> grid.plant
                   bus_id  Pg  Qg  Qmax  ...  pypsa_ramp_limit_up  pypsa_ramp_limit_down  pypsa_ramp_limit_start_up  pypsa_ramp_limit_shut_down
plant_id                                 ...                                                                                                   
AL1 0 offwind-ac    AL1 0 NaN NaN   NaN  ...                  NaN                    NaN                        1.0                         1.0
AL1 0 oil           AL1 0 NaN NaN   NaN  ...                  NaN                    NaN                        1.0                         1.0
AL1 0 onwind        AL1 0 NaN NaN   NaN  ...                  NaN                    NaN                        1.0                         1.0
AL1 0 ror           AL1 0 NaN NaN   NaN  ...                  NaN                    NaN                        1.0                         1.0
AL1 0 solar         AL1 0 NaN NaN   NaN  ...                  NaN                    NaN                        1.0                         1.0
...                   ...  ..  ..   ...  ...                  ...                    ...                        ...                         ...
SE2 7 hydro inflow  SE2 7 NaN NaN   NaN  ...                  NaN                    NaN                        NaN                         NaN
SE2 8 hydro inflow  SE2 8 NaN NaN   NaN  ...                  NaN                    NaN                        NaN                         NaN
SE2 9 hydro inflow  SE2 9 NaN NaN   NaN  ...                  NaN                    NaN                        NaN                         NaN
SI1 0 hydro inflow  SI1 0 NaN NaN   NaN  ...                  NaN                    NaN                        NaN                         NaN
SK1 0 hydro inflow  SK1 0 NaN NaN   NaN  ...                  NaN                    NaN                        NaN                         NaN

[1449 rows x 63 columns]

dcline_id just has hydro appended, bus_id just has inflow appended and plant_id has both. What do you think? Should we just us inflow for all three?

FabianHofmann commented 2 years ago

Hey @rouille, indeed this seems a bit inconsistent. To explain why this appears like this:

So I'd propose to set the bus names according to the storage units.

rouille commented 2 years ago

@FabianHofmann, can you rebase your branch onto ben/import (target branch). Thanks.

FabianHofmann commented 2 years ago

@rouille had some problems with rebase, but I think now everything is set up properly. Somehow the CI is not activated for this PR. Do you know why?

rouille commented 2 years ago

@rouille had some problems with rebase, but I think now everything is set up properly. Somehow the CI is not activated for this PR. Do you know why?

it looks like the tests/lint are triggered for PR where the target branch is develop (see .github/workflows/test.yml). I ran the tests locally and it is all good.