Why are the constraints I set in my CVXPY solar power optimization problem violated?

151 Views Asked by At

I am struggling with a CVXPY optimization problem because the optimized result violates the constraints I set. The optimization problem deals with energy produced by solar panels throughout a full day, considering the energy limit set by the utility. When there is more energy produced than the energy limit during a given hour, this is called the overload, where overload = energy - energy_limit. When the overload > 0, curtailment is necessary. The excess is defined as any overload energy that was not curtailed: excess = overload - curtail. The price of energy is 0.1 cents per kWh, so the price of every kWh of energy curtailed is added to the sum_cost. The budget_total is the amount of money that can be used for curtailment, and no curtailment is allowed once the budget_total is used up (when budget_total = sum_cost).

The goal of the optimization is to minimize excess, meaning that the energy limit is never exceeded after curtailment takes place. The constraints are that excess >= 0, curtail >= 0, sum_cost <= budget_total, overload >= 0, and curtail <= energy. The optimization code is given below. The problem is that the constraints excess >= 0 and overload >= 0 are violated, as can be seen in figure 1. Why are these constraints violated and how can I fix this?

def optimization(total_energy_list, avg_total_budget, Max_Energy, optimized):

# define Variables and Parameters scalars and vectors
# amount of money spent on curtailment (vector), determined by opt
cost = cp.Variable(HOURS)
# how many kWh of energy curtailed per hour (vector), det by opt
curtail = cp.Variable(HOURS)
# amount of energy not curtailed per hour (vector)
excess = cp.Variable(HOURS)
# amount of energy necessary to curtail per hour (vector)
overload = cp.Variable(HOURS)

budget_total = cp.Parameter()  # total amount of budget allowed for day (scalar)
kWh_cost = cp.Parameter()  # cost of 1 kWh of energy (scalar)
# amount of energy generated by PV per hour (vector)
energy = cp.Parameter(HOURS)
sum_cost = cp.Parameter()  # running total of cost spent over day (scalar)
# limit on amount of energy that can be sent to grid in one hour (scalar)
energy_limit = cp.Parameter()

# give parameters initial values
budget_total.value = avg_total_budget
kWh_cost.value = .1
sum_cost.value = 0
energy_limit.value = Max_Energy
energy.value = np.array(representative_day)  

# create constraints
constraints = [excess >= 0, curtail >= 0, sum_cost <= budget_total, curtail <= energy, overload >= 0]


overload = energy - energy_limit
# define excess energy as the amount of energy remaining over the limit after curtailment
excess = overload - curtail
# calculate the cost of energy curtailed
cost = curtail * kWh_cost
sum_cost = sum(cost)
# get the sum of squares of excess 
sum_excess = cp.sum_squares(excess)
# objective is to minimize the excess
obj = cp.Minimize(sum_excess)
# solve the problem with the given constraints and objective
prob = cp.Problem(obj, constraints)
prob.solve(solver=cp.GUROBI, verbose=False)

#get values for plotting
curtail_val = curtail.value
excess_val = excess.value
sum_excess_val = sum_excess.value
cost_val = cost.value
sum_cost_val = sum_cost.value
overload_val = overload.value
pow_after_curtailment = []
zip_list = zip(representative_day, curtail_val)
for list1_i, list2_i in zip_list:
    pow_after_curtailment.append(list1_i-list2_i)

#plot optimization results 
if (optimized == True):
    plot1 = plt.figure(1, dpi=1200)
    x_hours = list(range(1, 25))
    y = representative_day
    plt.plot(x_hours, excess_val, label="excess")
    plt.plot(x_hours, overload_val, label="overload", linestyle = "--")
    plt.plot(x_hours, curtail_val, label="curtail")
    plt.plot(x_hours, y, label="uncurtailed power(kW)")
    plt.plot(x_hours, pow_after_curtailment, label="optimized curtailed power(kW)")
    plt.title("Optimization Power")
    plt.legend(loc=2, prop={'size': 6})
    plt.xlabel('Hours')
    plt.ylabel('Power (kW)')
0

There are 0 best solutions below