PyomoException Error
OngoingPlease I would like any help on resolving the following error:
"PyomoException: Cannot convert non-constant Pyomo expression (0.25 < 6.610211319717535 - DemandRes[0]) to bool.
This error is usually caused by using a Var, unit, or mutable Param in a Boolean context such as an "if" statement, or when checking container membership or equality. For example,
>>> m.x = Var() >>> if m.x >= 1:
... pass >>> m.y = Var() >>> if m.y in [m.x, m.y]: ... pass
would both cause this exception.
Thanks
-
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 Han0 -
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.
Comments
2 comments