ADGEfficiency / energy-py-linear

Optimize energy assets using mixed-integer linear programming
GNU General Public License v3.0
83 stars 26 forks source link

Set constraint to limit number of battery cycles #70

Open andreasslyngstad opened 3 months ago

andreasslyngstad commented 3 months ago

Hello

My name is Andreas Slyngstad, and I am a software developer, currently working on a business case for batteries in Germany.

The business case is based around price arbitrage, and of the limits for this business case is number of battery cycles performed in a given simulation period. Here, a battery cycle includes discharge -> charge for some predefined limit of depth of discharge.

My question is: Is there any possible way to enforce the MILP solver constrain the problem to only be able to do a maximum of n number of cycles, lets say max 15 for some simulation period.

Example Battery specs

If possible (but not critical), is there any way to set a min/max range of SOC (state of charge) ? Lets say state of charge can be in the range of 10% - 90%.

Best regards

Andreas Slyngstad

ADGEfficiency commented 3 months ago

@andreasslyngstad

Limit Depth of Discharge

If possible (but not critical), is there any way to set a min/max range of SOC (state of charge)? Lets say state of charge can be in the range of 10% - 90%.

If you want to set a limit of depth of charge, you can reduce the size of the battery in the simulation:

import energypylinear as epl

# battery with full depth of discharge
asset = epl.Battery(
    power_mw=1,
    capacity_mwh=2,
    efficiency_pct=0.98,
)

# battery with 10-90% depth of discharge
asset = epl.Battery(
    power_mw=1,
    capacity_mwh=2 * 0.8,
    efficiency_pct=0.98,
)

Does this suit your requirement?

Currently there is nothing in the simulation that depends on depth of charge (like efficiency or charge rate), so I think setting depth of discharge this way is defensible. LMK if you disagree.

Constrain Charge Cycles

Is there any possible way to enforce the MILP solver constrain the problem to only be able to do a maximum of n number of cycles, lets say max 15 for some simulation period.

Currently there is not, but it is something we can add.

I would like something like the below - where you can define the constraints as either a list of epl models, or as a list of dictionaries:

import energypylinear as epl

asset = epl.Battery(
    power_mw=1,
    capacity_mwh=2,
    efficiency_pct=0.98,
    constraints=[
        epl.Constraint(
            lhs=[
                epl.ConstraintTerm(
                    asset_type="battery", variable="electric_charge_mwh"
                ),
                epl.ConstraintTerm(
                    asset_type="battery", variable="electric_discharge_mwh"
                ),
            ],
            rhs=2 * 15,
            sense="le"
        )
    ],
)

asset = epl.Battery(
    power_mw=1,
    capacity_mwh=2,
    efficiency_pct=0.98,
    constraints=[
        {
            "lhs": [
                {"asset_type": "battery", "variable": "electric_charge_mwh"},
                {"asset_type": "battery", "variable": "electric_discharge_mwh"},
            ],
            "rhs": 2 * 15,
            "sense": "le"
        }
    ],
)

What do you think @andreasslyngstad ? Would you like to contribute to this feature at all?