Part-load efficiency curve modelling in Gurobi
Dear community,
I would like to model the efficiency of a heat pump as a function of its load level, e.g., efficiency(T) = a*load_level(T)+b, where a and b are constants and T is time.
I have two variables "installed_capacity" and "power(T)", so the load_level(T) is defined as installed_capacity/power(T). But Gurobi does not accept this argument (division only allowed for constants).
Secondly, I also tried a piece-wise linear approximation for the part-load efficiency curve.
def part_load_eff(load_level, c1, c2, c3):
return c1 - c2/(2**(load_level/c3))
part_load_steps = np.linspace(0, 1, 5)
efficiency_steps = part_load_eff(part_load_steps, 3.8299, 3.8236, 0.14659)
v_load_level = m.addVar(lb=0, ub=1, vtype=GRB.CONTINUOUS)
v_efficiency = m.addVar(lb=0, ub=p_hp_cop_max, vtype=GRB.CONTINUOUS)
v_weights = m.addVars(len(part_load_steps), lb=0, ub=1, vtype=GRB.CONTINUOUS)
sos2 = m.addSOS(GRB.SOS_TYPE2, v_weights)
m.addConstr(quicksum(v_weights) == 1)
m.addConstr(quicksum([v_weights[i]*part_load_steps[i] for i in range(len(part_load_steps))]) == v_load_level)
m.addConstr(quicksum([v_weights[i]*efficiency_steps[i] for i in range(len(efficiency_steps))]) == v_efficiency)
But then in this way, the time dimension is not represented (because efficiency varies with time). Does any of you have any suggestion to make this constraint work properly?
Regards
Buddi
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
UPDATE - Another try using table lookup method
p_hp_cop = {0:1.5, 0.2:2.3, 0.4:3.4, 0.6:3.7, 0.8:3.85} #Create a lookup table (dict) for different load levels (key) and efficiency (value)
model.addConstrs(v_hp_cop[T] == max([v for (k,v) in p_hp_cop.items() if k*v_installed_capacity<=v_hp_power[T]]) for T in Time)
This also doesn't work and always returns the highest efficiency irrespective of what the load level is. Looking forward to some wise suggestions to implement part-load efficiency curves.
0 -
Hi Buddi,
Could you try adding the constraint load_level(T) * power(T) = installed_capacity for each time T? Gurobi 9.0 supports bilinear constraints like this. When doing this, be sure to set the NonConvex parameter to 2.
Eli
0 -
Thank you Eli. So I added (with Gurobi 9.0);
model.Params.NonConvex = 2
model.addConstrs(v_hp_load_level[T]*v_hp_power[T] == v_installed_capacity for T in Time)
There were some problems but after I uninstalled everything and reinstalled again, it started working. The challenge I have now is with the computational time. In that regard, especially because my model has a large number of time-steps, I would prefer a simpler table look-up kind of a method. Do you know how it can be implemented?
0
Post is closed for comments.
Comments
4 comments