Wrong calculation for power dictionnary in FixedEnergyUnit
Summary
OMEGAlpes recognizes if the data power are a list or a dictionnary. However, the calculations are inaccurate for dictionnaries for e_tot, p_max and p_min. Bug1: The dictionnaries are not well updated once the optimisation is done Bug2: if p is a dictionnay, sum(p) takes into account the keys and not the values.
Example Project
def main(work_path):
# Creating the unit dedicated to time management
time = TimeUnit(periods=4, dt=1 )
# Creating an empty model
model = OptimisationModel(time=time, name='elec_prod_simple_example')
# Creating the production units - the production profile are unknown
grid_production_a = VariableProductionUnit(time=time,
name='grid_production_A',
energy_type='Electrical)
dwelling_consumption = FixedConsumptionUnit(time, 'dwelling_consumption',
energy_type='Electrical',
p={0: 162.0, 1: 138.0,
2: 91.0, 3: 100})
# Creating the energy nodes and connecting units
elec_node = EnergyNode(time, 'elec_node', energy_type='Electrical')
elec_node.connect_units(dwelling_consumption, grid_production_a)
# Adding the energy node to the model
model.add_nodes(elec_node)
# Optimisation process
model.writeLP(work_path + r'\optim_models\elec_prod_simple_example.lp')
model.solve_and_update() # Run optimization and update values
return model, time, dwelling_consumption, grid_production_a
def print_results():
if LpStatus[MODEL.status] == 'Optimal':
print("\n - - - - - OPTIMIZATION RESULTS - - - - - ")
print('Dwelling consumption = {0} kWh.'.format(
DWELLING_CONSUMPTION.e_tot))
print('Dwelling consumption = {0} kWh.'.format(
DWELLING_CONSUMPTION.p))
print('grid_production A production = {0} kWh'.format(
GRID_PRODUCTION_A.e_tot))
print('grid_production A production = {0} kWh'.format(
GRID_PRODUCTION_A.p))
elif LpStatus[MODEL.status] == 'Infeasible':
print("Sorry, the optimisation problem has no feasible solution !")
elif LpStatus[MODEL.status] == 'Unbounded':
print("The cost function of the optimisation problem is unbounded !")
elif LpStatus[MODEL.status] == 'Undefined':
print("Sorry, a feasible solution has not been found (but may exist). "
"PuLP does not manage to interpret the solver's output, "
"the infeasibility of the MILP problem may have been "
"detected during presolve")
if __name__ == "__main__":
WORK_PATH = os.getcwd()
# *** RUN MAIN ***
MODEL, TIME, DWELLING_CONSUMPTION, GRID_PRODUCTION_A, \
= main(work_path=WORK_PATH)
# *** SHOW RESULTS ***
print_results()
What is the current bug behavior?
Bug1: Dwelling consumption = 6.0 kWh. Dwelling consumption = {0: 3.0, 1: 3.0, 2: 0.0, 3: 0.0} kWh.
Bug2: Infeasible because of the following constraint: dwelling_consumption_calc_e_tot: dwelling_consumption_e_tot = 491.0
What is the expected correct behavior?
Dwelling consumption = 491.0 kWh. Dwelling consumption = {0: 162.0, 1: 138.0, 2: 91.0, 3: 100} kWh.
Possible fixes
Solving Bug1: In model.py, updating dictionnary should be fixed as follow:
# If the values are stored in a dictionary
if isinstance(q_val, dict):
if any(i for i in q_opt.values()):
globals()[q_name] = LpVariable.dict(name=q_name,
indexs=q_val.keys(),
lowBound=q_lb, upBound=q_ub,
cat=q_type)
else:
globals()[q_name] = q_val
In elements.py, correct
elif isinstance(value, dict):
# The value is a dict
** if any(isinstance(n, (int, float)) for n in list(
value.values())):**
# At least one value of the dict is specified
self.opt = {}
# The opt parameter is a dict of False
self.opt.update({i: False for i in list(value.keys())})
Solving Bug2 in EnergyUnits.py class FixedEnergyUnit
if isinstance(p, list):
e_tot = sum(p) * time.DT
p_min = min(p)
p_max = max(p)
elif isinstance(p, dict):
# Checking the length of the dictionary corresponds to the length
# of the time unit
if len(time.DATES) == len(p):
e_tot = sum(p.values()) * time.DT
p_min = min(p.values())
p_max = max(p.values())