No error with two fixed units with differents amount of energy
Summary
No error with two fixed units with differents amount of energy :
- FixedConsumptionUnit (p=[0,0,0])
- FixedProductionUnit (p=[200,200,200])
What is the current bug behavior?
The problem should be infeasible or should raise an error and seems feasible. The node_power_balance is not added in the model as it is not considered as a LpConstraints as their is no variable in it.
Possible fixes
In PuLP, the constraint is considered as a Boolean => False, but the iadd(self, other) does not raise any error as a boolean is also an 'int'. A issue have been opened on Pulp: https://github.com/coin-or/pulp/issues/207 If the issue is solved as proposed: the method omegalpes.general.optimisation.model._add_constraints() should be modified as follow:
def _add_constraints(self, time: TimeUnit) -> None:
"""
Add all constraints to the model
:param time: TimeUnit
"""
print('\n--- Adding all constraints to the model ---')
for cst in self._model_constraints_list:
cst_name = cst.parent.name + '_' + cst.name
cst_exp = cst.exp
# Print the constraint expression
if self.verbose:
print('Adding constraint : {0} , exp = {1}'.format(cst_name,
cst_exp))
if isinstance(cst, DynamicConstraint):
loop_exp = "".join([cst.t_range, ':\n'
'\ttry:\n'
'\t\tself += {0}, '
''.format(cst.exp_t),
'"{0}_{1}".format(cst_name, t)\n'
'\texcept TypeError:\n'
'\t\traise ValueError("The constraint {} '
'is infeasible".format(cst.exp_t))'])
exec(loop_exp)
else:
try:
# Add the constraint to the optimization model
self += eval(cst_exp), cst_name
# self.addConstraint(eval(cst_exp), cst_name)
except TypeError:
raise ValueError("The constraint {} is infeasible".format(cst.exp_t))
Examples to test it
import os
from pulp import LpStatus, PULP_CBC_CMD, GLPK_CMD
from omegalpes.energy.energy_nodes import EnergyNode
from omegalpes.energy.units.production_units import FixedProductionUnit, \
VariableProductionUnit
from omegalpes.energy.units.consumption_units import FixedConsumptionUnit, \
VariableConsumptionUnit
from omegalpes.general.optimisation.model import OptimisationModel
from omegalpes.general.time import TimeUnit
def main(work_path):
# # Create an empty model # #
time = TimeUnit(periods=3, dt=1, start='24/11/2018')
model = OptimisationModel(time=time, name='test_bug_2fixedUnits')
# # # Create the units
production = FixedProductionUnit(time=time, name='production',
energy_type='Electrical',
p=[200, 200, 200])
supplier_consumption = FixedConsumptionUnit(time, 'supplier_consumption',
energy_type='Electrical',
p=[0, 0, 0])
# # Create the energy node and connect units # #
node = EnergyNode(time=time, name='elec_node', energy_type='Electrical',)
node.connect_units(production,
supplier_consumption)
# # Add the energy node to the model # #
model.add_nodes(node) # Add node to the model
# Optimisation process
model.writeLP(work_path + r'\optim_models\test_bug_2fixedUnits.lp')
# model.solve_and_update(PULP_CBC_CMD(msg=1))
model.solve_and_update()
return model, time, production, supplier_consumption, node
if __name__ == '__main__':
# OPTIMIZATION PARAMETERS #
WORK_PATH = os.getcwd()
# Run main
MODEL, TIME, PRODUCTION, SUPP_CONS, NODE = \
main(work_path=WORK_PATH)