Skip to main content

PyomoException Error

Ongoing

Comments

2 comments

  • Chung-Kyun Han
    • Gurobi Staff Gurobi Staff

    Hi Olatunji,

    Thank you for reaching us.

    It seems that the variable 'DemandRes[0]' is Pyomo's Var(), and the object can not be used in an if statement directly.

    The alternative way for expressing an if statement is to use big-M (reference this link)

    If you tell us what you want to achieve through the if statement and share the part of your code, we can give you further help.


    Best regards,
    Chung-Kyun Han

    0
  • Floris Hol
    • Gurobi-versary
    • First Comment

    I do have the same issue. It seems I can't use a Var in an if statement. Chung-Kyun Han Could you please have a look at my code and see if you know how I can fix it? Would appreciate that very much.

    I've left a comment with 'ERROR' to highlight where the error is caused in the update_grid_import_constraint function:

    from typing import Any
    from pyomo.environ import *
    import pandas as pd


    # Dummy data for the dataframe (you can replace this with your actual data)

    data = {
    'period': [0, 1, 2, 3, 4],
    'spot_price': [0.125, 0.134, 0.059, -0.038, 0.040],
    'energy_generated': [100, 150, 520, 180, 200],
    'energy_consumed': [200, 300, 240, 360, 400],
    }

    df = pd.DataFrame(data)

    # Define model and solver
    battery = ConcreteModel()

    # Define constants for the battery model
    INITIAL_CAPACITY = 0
    MIN_BATTERY_CAPACITY = 0
    MAX_BATTERY_CAPACITY = 1000

    # Parameters refer to data that must be provided in order to find an optimal (or good) assignment of values to
    # the decision variables
    # Define the period set
    battery.Period = Set(initialize=list(df.period), ordered=True)
    # Define the price parameter
    battery.Spot_price = Param(battery.Period, initialize={i: df['spot_price'][i] for i in battery.Period}, within=Any)
    # Define energy production
    battery.Energy_generated = Param(battery.Period,
    initialize={i: df['energy_generated'][i] for i in battery.Period}, within=Any)
    # Define energy consumption
    battery.Energy_consumed = Param(battery.Period,
    initialize={i: df['energy_consumed'][i] for i in battery.Period}, within=Any)

    # Define battery variables
    battery.Capacity = Var(battery.Period, bounds=(MIN_BATTERY_CAPACITY, MAX_BATTERY_CAPACITY))
    battery.Grid_import = Var(battery.Period, bounds=(0, None))
    battery.Grid_export = Var(battery.Period, bounds=(0, None))

    # Set constraints for the battery defining capacity rule for the battery
    def update_battery_capacity_constraint(battery, i):
    """
    The rule capacity_constraint is crucial for ensuring that the battery's capacity is properly
    updated over time within the optimization model.

    Enforce the battery capacity constraint for the optimization model.

    This constraint calculates the battery capacity for each period based on the charging and
    discharging actions, while considering the battery's initial capacity and efficiency.

    Note: The output shows the capacity at the beginning of each period.
    Grid_import and Grid_export depend on mutations being made during the period.
    """
    if i == battery.Period.first():
    return battery.Capacity[i] == INITIAL_CAPACITY
    return battery.Capacity[i] == (
    battery.Capacity[i - 1]
    + (battery.Grid_import[i - 1])
    + (battery.Energy_generated[i - 1])
    - (battery.Energy_consumed[i - 1])
    - (battery.Grid_export[i - 1])
    )


    # Make sure the battery does not charge above the limit
    def update_grid_import_constraint(battery, i):
    """
    - Maximize import from the grid if the spot price is negative.
    - Don't import from the grid if more energy is generated than consumed.
    - Import from the grid if more energy is consumed than is generated.
    """
    if battery.Spot_price[i] < 0:
    return battery.Grid_import[i] == MAX_BATTERY_CAPACITY - battery.Capacity[i]
    elif battery.Energy_generated[i] - battery.Energy_consumed[i] > 0:
    return battery.Grid_import[i] == 0
    # THIS ELIF IS CAUSING THE ERROR BECAUSE battery.Capacity[i] is a Var in an if statement
    elif battery.Capacity[i] > battery.Energy_consumed[i]:
    return battery.Grid_import[i] == 0
    else:
    return battery.Grid_import[i] == battery.Energy_consumed[i] - battery.Energy_generated[i]


    def update_grid_export_constraint(battery, i):
    """
    - Don't export to the grid if the spot price is negative.
    - If more energy is generated than consumed creating excess energy, export to the grid.
    - If this is not the case, only export if there is remaining energy from the mutations
    happening in update_battery_capacity_constraint.
    """
    if battery.Spot_price[i] < 0:
    return battery.Grid_export[i] == 0
    elif battery.Energy_generated[i] - battery.Energy_consumed[i] > 0:
    return battery.Grid_export[i] == battery.Capacity[i] + battery.Energy_generated[i] - battery.Energy_consumed[i]
    else:
    return battery.Grid_export[i] == battery.Capacity[i]


    # Set the battery objective function to be maximized
    def maximise_profit(battery):
    """
    Calculate the total profit for the battery optimization problem.

    This function calculates the total profit by summing up the revenue generated
    from exporting to the grid, minus the cost of importing from the grid. The revenue and cost are calculated for
    each time period based on the spot price, grid export, and grid import.

    Parameters:
    battery: The Pyomo ConcreteModel representing the battery optimization model.

    Returns:
    float: The total profit calculated based on the optimization results.
    """
    rev = sum(df.spot_price[i] * battery.Grid_export[i] for i in battery.Period)

    cost = sum(df.spot_price[i] * battery.Grid_import[i] for i in battery.Period)

    return rev - cost


    # Add the constraint functions to the model
    battery.Capacity_constraint = Constraint(battery.Period, rule=update_battery_capacity_constraint)
    battery.Grid_import_constraint = Constraint(battery.Period, rule=update_grid_import_constraint)
    battery.Grid_export_constraint = Constraint(battery.Period, rule=update_grid_export_constraint)


    # Set the battery objective function to be maximized
    battery.profit = Objective(rule=maximise_profit, sense=maximize)

    # Print the model to check if it's defined correctly
    battery.pprint()

    # Define the solving instance
    instance = battery.create_instance()

    # Solve the model
    solver = SolverFactory('glpk', executable='<personal path to your solver>\glpsol.exe')
    results = solver.solve(instance)

    # Check if the solver successfully found a solution
    if results.solver.termination_condition == TerminationCondition.optimal:
    # Display the final objective value (revenue)
    print("Final Objective Value (Revenue):", value(instance.profit))

    # Access the Discharge_power variable values after solving
    battery_capacity_values = {i: value(instance.Capacity[i]) for i in instance.Period}
    print("Battery Capacity Values:", battery_capacity_values)
    grid_import_values = {i: value(instance.Grid_import[i]) for i in instance.Period}
    print("Grid Import Values:", grid_import_values)
    grid_export_values = {i: value(instance.Grid_export[i]) for i in instance.Period}
    print("Grid Export Values:", grid_export_values)

    print(results)
    else:
    print("Solver did not find an optimal solution.")
    0

Please sign in to leave a comment.