Skip to content

StoreΒΆ

The Store component connects to a single bus and provides fundamental inter-temporal storage functionality of the carrier of the Bus it attaches to. It is not limited in charging or discharging power.

To control charging and discharging power, separate Link components must be connected to the Bus to which the Store attaches. This decoupled approach enables independent optimization of power and energy capacities as well as asymmetric power ratings for charging and discharging.

Hydrogen storage system with a Store and two Link components

graph LR
    ElectricityBus["Electricity Bus"]:::bus
    HydrogenBus["Hydrogen Bus"]:::bus
    SteelTank["Steel Tank Store"]:::store

    ElectricityBus -->|Electrolyser Link| HydrogenBus
    HydrogenBus -->|Hydrogen Turbine Link| ElectricityBus
    HydrogenBus --> SteelTank

    classDef bus fill:#f9f,stroke:#333,stroke-width:2,shape:circle;
    classDef store fill:#bbf,stroke:#333,stroke-width:2,shape:rect;

The marginal_cost attribute applies equally to both charging and discharging operations, representing the cost per unit of energy stored or released. This differs from StorageUnit components where marginal costs apply only to the discharging power. For instance, the marginal_cost of the Store component can represent trading in external energy markets where the stored carrier can be bought or sold at fixed market prices.

When to use StorageUnit instead?

Use StorageUnit when power and energy capacities have a fixed relationship and you need integrated dispatch control within a single component. For example, this is recommended for a storage device where the power-to-energy ratio is predetermined by the manufacturer. The StorageUnit also has attributes for hydro-electric inflow and spillage. See this example for implementation differences.

attribute type unit default description status
name string nan nan Unique name Input (required)
bus string nan nan Name of bus to which store is attached. Input (required)
type string nan nan Placeholder for store type. Not yet implemented. Input (optional)
carrier string nan nan Carrier of the store. Input (optional)
e_nom float MWh 0 Nominal energy capacity (i.e. limit on e). Ignored if e_nom_extendable=True. Input (optional)
e_nom_mod float MWh 0 Nominal energy capacity of the store module. Introduces integer variables if set. Input (optional)
e_nom_extendable boolean nan False Switch to allow capacity e_nom to be extended in optimisation. Input (optional)
e_nom_min float MWh 0 If e_nom_extendable=True, set the minimum value of e_nom_opt. Input (optional)
e_nom_max float MWh inf If e_nom_extendable=True, set the maximum value of e_nom_opt. Input (optional)
e_nom_set float MWh nan If e_nom_extendable=True, set the value of e_nom_opt. Input (optional)
e_min_pu static or series per unit 0 Minimal value of e relative to e_nom for the optimisation. Input (optional)
e_max_pu static or series per unit 1 Maximal value of e relative to e_nom for the optimisation. Input (optional)
e_initial float MWh 0 Energy before the snapshots in the optimisation. Input (optional)
e_initial_per_period boolean nan False Switch: if True, then at the beginning of each investment period e is set to e_initial. Input (optional)
e_cyclic boolean nan False Switch: if True, then e_initial is ignored and the initial energy is set to the final energy for the group of snapshots in the optimisation. Input (optional)
e_cyclic_per_period boolean nan False Switch: if True, then the cyclic constraints are applied to each investment period separately. Input (optional)
p_set static or series MW nan Active power set point (for optimisation and power flow) Input (optional)
q_set static or series MVar 0 Reactive power set point (for power flow only) Input (optional)
e_set static or series MWh nan Fixed energy filling level set point (for optimisation only) Input (optional)
sign float nan 1 Sign denoting orientation of the energy variable (e). Input (optional)
marginal_cost static or series currency/MWh 0 Marginal cost applied to both charging and discharging of 1 MWh. Input (optional)
marginal_cost_quadratic static or series currency/MWh 0 Quadratic marginal cost of applied to charging and discharging of 1 MWh. Input (optional)
marginal_cost_storage static or series currency/MWh/h 0 Marginal cost of energy storage of 1 MWh for one hour. Input (optional)
capital_cost float currency/MWh 0 Fixed period costs of extending e_nom by 1 MWh (e.g. annuitized investment costs). Used directly unless overnight_cost is specified. Input (optional)
overnight_cost float currency/MWh nan Overnight (upfront) investment cost per MWh. If specified, PyPSA calculates annuity using discount_rate and lifetime. Takes precedence over capital_cost. Input (optional)
discount_rate float per unit nan Discount rate for annuity calculation when using overnight_cost. Supports 0% rate (simple depreciation). Input (optional)
fom_cost float currency/MWh 0 Fixed period operation and maintenance costs per MWh, added to annuitized investment cost. Input (optional)
standing_loss static or series per unit 0 Losses per hour to energy level. Input (optional)
active boolean nan True Whether to consider the component in optimisation or not Input (optional)
build_year int year 0 Build year Input (optional)
lifetime float years inf Lifetime Input (optional)
p series MW 0 Power at bus (positive if net supply) Output
q series MVar 0 Reactive power (positive if net supply) Output
e series MWh 0 Energy level of store as calculated by the optimisation. Output
e_nom_opt float MWh 0 Optimised nominal energy capacity outputed by optimisation. Output
mu_upper series currency/MWh nan Shadow price of upper e_nom limit Output
mu_lower series currency/MWh nan Shadow price of lower e_nom limit Output
mu_energy_balance series currency/MWh nan Shadow price of storage consistency equations (i.e. water values) Output