# Mutable parameter in Pyomo causes a problem

I am defining a Pyomo model that should have some mutable Big-M parameters whose values should be dynamically assigned (once). However, I am having a problem with a difference equation as described in this post Error message in difference equation in Pyomo. Here you can see my extremel simplified model in pyomo (that does not make much sense from a logical point of view, but I just want to adress the error):

import pyomo.environ as pyo
import pandas as pd
from pyomo.util.infeasible import log_infeasible_constraints

#Define the model
model = pyo.ConcreteModel()

#Define the sets
model.set_timeslots = pyo.RangeSet(1, 288)

#Define the bigM parameter
model.param_BigM_Surplus_Positive = pyo.Param(model.set_timeslots, mutable=True, default =0)

#Define the variables
model.variable_temperatureBufferStorage = pyo.Var(model.set_timeslots, bounds=(20, 22))
model.variable_surplusPowerTotal = pyo.Var(model.set_timeslots)

#Equations for the Big-M parameters
'''When commenting this Big-M parameter equation out, the model can be solved. Otherwise I get an error for each value of the variable model.variable_temperatureBufferStorage
variable ERROR: evaluating object as numeric value:
variable_temperatureBufferStorage[274]
(object: <class 'pyomo.core.base.var._GeneralVarData'>)
No value for uninitialized NumericValue object
variable_temperatureBufferStorage[274]
'''
def BigM_Surplus_PositiveRule (model, t):
return model.param_BigM_Surplus_Positive [t] == 10

model.constraint_BigM_Surplus_Positive = pyo.Constraint(model.set_timeslots, rule = BigM_Surplus_PositiveRule)

# Defining the constraints

#Temperature constraint for the buffer storage (space heating) with energetic difference equation
def temperatureBufferStorageConstraintRule(model, t):
if t == model.set_timeslots.first():
return model.variable_temperatureBufferStorage[t] == 21
return model.variable_temperatureBufferStorage[t] == model.variable_temperatureBufferStorage[t-1]

model.constraint_temperatureBufferStorage = pyo.Constraint (model.set_timeslots, rule=temperatureBufferStorageConstraintRule)

#Equations for the surplus power
def surplusPowerTotalRule (model, t):
return model.variable_surplusPowerTotal [t] == 1

model.constraint_surplusPowerTotal = pyo.Constraint(model.set_timeslots, rule = surplusPowerTotalRule)

#Objectives

def objectiveRule_combined_general (model):
return  sum(model.variable_surplusPowerTotal[t] for t in model.set_timeslots)

model.objective_combined_general = pyo.Objective( rule=objectiveRule_combined_general, sense =pyo.minimize)

print("Start of solving")
solver = pyo.SolverFactory('gurobi')
solver.options['MIPGap'] = 1
solver.options['TimeLimit'] = 20
solution = solver.solve(model, tee=True)

log_infeasible_constraints(model)


The problematic part is when I define the constraints for the mutable Big-M parameter model.param_BigM_Surplus_Positive = pyo.Param(model.set_timeslots, mutable=True, default =0). When they are active and not commented out I get an error from Gurobi telling that the problem is infeasible or unbounded:

Infeasible or unbounded model
model.name="unknown";
- termination condition: infeasibleOrUnbounded
- message from solver: Problem proven to be infeasible or unbounded.


When looking what is causing this problem with from pyomo.util.infeasible import log_infeasible_constraints I can see an error for each value of the variable model.variable_temperatureBufferStorage

ERROR: evaluating object as numeric value:
variable_temperatureBufferStorage[2]
(object: <class 'pyomo.core.base.var._GeneralVarData'>)
No value for uninitialized NumericValue object
variable_temperatureBufferStorage[2]
ERROR: evaluating object as numeric value:
variable_temperatureBufferStorage[3]
(object: <class 'pyomo.core.base.var._GeneralVarData'>)
No value for uninitialized NumericValue object
variable_temperatureBufferStorage[3]
ERROR: evaluating object as numeric value:
variable_temperatureBufferStorage[4]
(object: <class 'pyomo.core.base.var._GeneralVarData'>)
No value for uninitialized NumericValue object
variable_temperatureBufferStorage[4]


Without the Big-M parameter constraints the model is solvable. So my question is why does this error occur when having a mutable parameter and how can I tackle this problem?

• Not sure what you are trying to achieve here but a constraint "0=10" is often considered to be infeasible. – Erwin Kalvelagen Apr 16 at 10:03
• Thanks for your comment Erwin. Basically I would like to define a parameter Big-M(t) whose values are assigned to it by using other parameters. I do this in the constraint model.constraint_BigM_Surplus_Positive  (for simplicity I just assign the value 10 to it in this simplified example). So the value of the parameter Big-M should be calculated for every timeslot (t). – PeterBe Apr 16 at 10:15
• In the defintion of the Big-M parameter model.param_BigM_Surplus_Positive = pyo.Param(model.set_timeslots, mutable=True, default =0) I have to specify a default value otherwise I get a Value Error "ValueError: Error evaluating Param value (param_BigM_Surplus_Positive[1]): The Param value is currently set to an invalid value. This is typically from a scalar Param or mutable Indexed Param without an initial or default value." – PeterBe Apr 16 at 10:15
• It is important, even essential, to know the difference between a parameter and a variable. A parameter is constant inside a constraint. The solver can only change variables. – Erwin Kalvelagen Apr 16 at 10:20
• Thanks Erwin for your comment. Well, I do understand the difference between a parameter and a variable. The Big-M parameter is in fact a parameter and not a variable. The solver should not change any of its values. The values are all predefined by calculating it for every timeslot (t) using other constant parameters. The calculations are just normal calculations that have nothing to do with a solver. I can tell you that I have exactly the same model implemented in GAMS and there the exactly same Big-M parameter is defined as a parameter – PeterBe Apr 16 at 10:28

Based on given model section, model.param_BigM_Surplus_Positive parameter is used in only constraint which is:

model.constraint_BigM_Surplus_Positive = pyo.Constraint(model.set_timeslots, rule = BigM_Surplus_PositiveRule)


You are using BigM_Surplus_PositiveRule for generating constraint which is:

model.param_BigM_Surplus_Positive[t] == 10
`

But this parameter is defined as 0, therefore model is infeasible. If you want to assign 10 to this parameter, you should use initialize function.

Note: On your model there isn't any big-m constraint. In this question you can find an example.