I am attempting to model the hourly runtime of a plant. Contractually, if the decision is made to run the plant, it must be run for a minimum of X = 3 hours and a maximum of Y = 8 hours.
I am trying to model out the constraints so that if the decision is made to run in a day, it must run for X a minimum of X hours and a maximum of Y hours. From there, when the plant is no longer running the decision resets.
Here is my attempt at the constraints:
optimizer = pyo.SolverFactory(solver, executable = solver_exe)
# Define the model
model = pyo.ConcreteModel(name = "HRCO")
# Generate a list of hourly datetime slots
model.TIME_SLOTS = RangeSet(0, int((end_date - start_date).total_seconds() / 3600), name = "Hour Number")
model.Year = Param(model.TIME_SLOTS, initialize=pd.DataFrame(pd.date_range(start= start_date, end = end_date, freq='h'))[0].dt.year.to_dict())
model.min_dispatch = Param(initialize = min_dispatch)
model.max_dispatch = Param(initialize = max_dispatch)
# Variables
model.hours_to_run = Var(model.TIME_SLOTS, within=Binary)
model.consecutive_hours = Var(model.TIME_SLOTS, within=NonNegativeIntegers, initialize = 0)
# Constraints
for year in np.unique(pd.date_range(start= start_date, end = end_date, freq='h').year):
year_slot = [slot for slot in model.TIME_SLOTS if model.Year[slot] == year]
model.add_component("total_hours_constraint_{}".format(year),
Constraint(
expr=sum(model.hours_to_run[slot] for slot in year_slot) <= max_hours
))
def min_consecutive_hours_rule(model, t):
if t == 0:
return model.consecutive_hours[t] == model.hours_to_run[t]
else:
return model.consecutive_hours[t] == model.consecutive_hours[t-1] + model.hours_to_run[t]
model.min_consecutive_hours_constraint = Constraint(model.TIME_SLOTS, rule=min_consecutive_hours_rule)
def min_consecutive_hours_adjusted_rule(model, t):
if t >= model.min_dispatch:
return model.consecutive_hours[t] >= model.min_dispatch
else:
return Constraint.Skip
model.min_consecutive_hours_constraint_adj = Constraint(model.TIME_SLOTS, rule=min_consecutive_hours_adjusted_rule)
def max_consecutive_hours_rule(model, t):
if t >= model.max_dispatch:
return model.consecutive_hours[t] <= model.max_dispatch
else:
return Constraint.Skip
model.max_consecutive_hours_constraint = Constraint(model.TIME_SLOTS, rule=max_consecutive_hours_rule)