Skip to content

Commit e456cb8

Browse files
authored
Fix side effects of battery minimum charging with p_demand (#61)
1 parent cff404f commit e456cb8

4 files changed

Lines changed: 6177 additions & 778 deletions

File tree

src/optimizer/optimizer.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,13 @@ def _setup_variables(self):
154154

155155
# penalty variable for not being able to charge with the required power
156156
self.variables['p_demand_pen'] = [[None for t in self.time_steps] for i in range(len(self.batteries))]
157+
# binary variable to allow one out of two alternative constraints
158+
self.variables['z_p_demand'] = [[None for t in self.time_steps] for i in range(len(self.batteries))]
157159
for i, bat in enumerate(self.batteries):
158160
if bat.p_demand is not None:
159161
for t in self.time_steps:
160162
self.variables['p_demand_pen'][i][t] = pulp.LpVariable(f"p_demand_pen_{i}_{t}", lowBound=0)
163+
self.variables['z_p_demand'][i][t] = pulp.LpVariable(f"z_p_demand_{i}_{t}", cat='Binary')
161164

162165
# penalty variable for staying above max SOC and below min SOC
163166
self.variables['s_max_pen'] = [[pulp.LpVariable(f"s_max_pen_{i}_{t}", lowBound=0) for t in self.time_steps] for i in range(len(self.batteries))]
@@ -269,7 +272,7 @@ def _setup_target_function(self):
269272
if self.batteries[i].s_goal[t] > 0:
270273
# negative target function contribution in a maximizing optimization
271274
objective += - self.prc_e_goal_pen * self.variables['s_goal_pen'][i][t]
272-
# unmet charging demand due to battery reaching maximum SOC
275+
# unmet charging demand due to battery reaching maximum SOC with incentive to do charging early
273276
if bat.p_demand is not None:
274277
for t in self.time_steps:
275278
objective += - self.prc_p_goal_pen \
@@ -444,10 +447,15 @@ def _add_battery_constraints(self):
444447
if bat.p_demand[t] > 0:
445448
# clip required charge to max charging power if needed
446449
# and leave some air to breathe for the optimizer
447-
p_demand = bat.p_demand[t]
448-
if p_demand >= bat.c_max * self.time_series.dt[t] / 3600.:
449-
p_demand = bat.c_max * self.time_series.dt[t] / 3600. * 0.999
450-
self.problem += (self.variables['c'][i][t] + self.variables['p_demand_pen'][i][t] >= p_demand)
450+
p_demand = min(bat.c_max * self.time_series.dt[t] / 3600., bat.p_demand[t])
451+
# two alternative constraints, only one is active:
452+
# constraint option 1: charge energy tries to reach min charge energy parameter
453+
self.problem += (self.variables['c'][i][t] + self.variables['p_demand_pen'][i][t]
454+
+ self.M * self.variables['z_p_demand'][i][t] >= p_demand)
455+
# constraint option 2: charge energy tries to reach energy to fill the battery to s_max
456+
self.problem += (self.variables['c'][i][t] + self.variables['p_demand_pen'][i][t]
457+
+ self.M * (1 - self.variables['z_p_demand'][i][t])
458+
- (self.batteries[i].s_max - self.variables['s'][i][t]) >= 0.)
451459
elif bat.c_min > 0:
452460
# in time steps without given charging demand, apply normal lower bound:
453461
# Lower bound: either 0 or at least c_min

0 commit comments

Comments
 (0)