Limiting the number of times a link can be used

91 views
Skip to first unread message

Jessica Guichard

unread,
Nov 1, 2022, 5:56:32 AM11/1/22
to pypsa
Hi,

I would like to model a storage solution which can only be emptied or filled a certain number of times in a year (geological storage). I can imagine that implementing this in PyPSA is probably not straightforward. 

If anyone else has had the need for this and found a solution, that would be great.

Thanks

Fabian Neumann

unread,
Nov 1, 2022, 6:06:05 AM11/1/22
to pypsa
Hi Jessica,

the allowed number of cycles of a storage is not a configurable parameter of the PyPSA components, but if you can come up with a linear constraint that would model this behaviour, you can implement it within an `extra_functionality`.


Best wishes,

Fabian N

Pim Doodkorte

unread,
Feb 13, 2024, 10:39:23 AMFeb 13
to pypsa
Any solution to this already? I would be interested!

Op dinsdag 1 november 2022 om 11:06:05 UTC+1 schreef fn...@mail.tu-berlin.de:

Pim Doodkorte

unread,
Feb 14, 2024, 3:17:31 AMFeb 14
to pypsa
For future people stumbling across the same problem. I found a sub-optimal solution, that seems to work. See the code below.

I add a Store to my network with two links (control-to-battery for charging and battery-to-control for discharging). Since the control-to-battery link is always used for charging, you can calculate the total influx into the battery using: p_link * hours in MWh. In my example I use a 15m resolution, so 0,25 hours. This means that you can calculate the total charging of MWh into the a battery. Subsequently, you know the total storage capacity of the battery. With that information you can create a constraint that limits the total amount of cycles. You might have to modify a bit of the constraint by including efficiencies etc..

Below the code I use:
    def add_battery(self,p_battery:float, t_battery:float) -> None:
        """
        Add a battery to the system.
        - p_battery: maximum power of the battery
        - t_battery: total amount of time the battery can deliver power p.
        """
        ### ADD BATTERY ###
        self.p_battery = p_battery
        self.t_battery = t_battery
        # Add battery
        self.network.add("Store",
                    "Battery",
                    bus="BatteryBus",
                    e_nom = self.p_battery * t_battery)

        # Charging link
        self.network.add("Link",
                    "ControlToBatteryLink",
                    bus0="ControlBus",
                    bus1="BatteryBus",
                    p_nom=self.p_battery,               #The maximum capacity of charge/discharge of the battery.
                    marginal_cost = self.storage_cost,  #Add cost for storing energy, otherwise it stores for low prices.
                    efficiency = 0.95
                    )

        # Discharging link;
        self.network.add("Link",
                    "BatteryToControl",
                    bus0="BatteryBus",
                    bus1="ControlBus",
                    p_nom=self.p_battery,              #The maximum capacity of charge/discharge of the battery.
                    marginal_cost = 0,
                    efficiency = 0.95
                    )

Constraint:
cycles = [INSERT CYCLES]
cycles_con = (m.variables["Link-p"].loc[:,"ControlToBatteryLink"]*0.25).sum()<=cycles * (n.p_battery * n.t_battery)
n.network.model.add_constraints(cycles_con, name="cycles_constraint")

Op dinsdag 13 februari 2024 om 16:39:23 UTC+1 schreef Pim Doodkorte:
Reply all
Reply to author
Forward
0 new messages