OMEGAlpes issueshttps://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues2021-11-18T11:15:51+01:00https://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/73Inconsistency between units W or kW2021-11-18T11:15:51+01:00Pierre-Thomas Demarspierre-thomas.demars@grenoble-inp.orgInconsistency between units W or kWFixedProductionUnit and FixedConsumptionUnit asked to provide profile in Watts.
However, the plot_node_energetic_flows is plotting a graph with kW as y-axis, which lead to a false graph if the above unit recommandation is followed.
My a...FixedProductionUnit and FixedConsumptionUnit asked to provide profile in Watts.
However, the plot_node_energetic_flows is plotting a graph with kW as y-axis, which lead to a false graph if the above unit recommandation is followed.
My advice would be to choose a base unit (kW in my opinion) and work with it everywhere.https://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/72LPFICS : find_infeasible_constraint_set method doesn't exist2021-12-20T16:18:46+01:00Pierre-Thomas Demarspierre-thomas.demars@grenoble-inp.orgLPFICS : find_infeasible_constraint_set method doesn't exist### Summary
When trying to optimize a model with the method **model.solve_and_update()**, it may be possible that this is infeasible. In this case, an error message is printed and tells the user to use LFPICS to find the reason of the i...### Summary
When trying to optimize a model with the method **model.solve_and_update()**, it may be possible that this is infeasible. In this case, an error message is printed and tells the user to use LFPICS to find the reason of the infeasibility.
However, after downloading and installing the FPCIS, the method **find_infeasible_constraint_set** doesn't exist, neither than all the other methods that the massage is indicating.https://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/69Interference between zoom and scroll - Graphical interface2021-12-20T16:30:00+01:00Pierre-Thomas Demarspierre-thomas.demars@grenoble-inp.orgInterference between zoom and scroll - Graphical interface
### Summary
When you scroll in the parameters menu of an item of the graphical interface, it is also activating the zoom of the schematic.
### Steps to reproduce
- open the graphical interface
- insert an item
- open the parameters ...
### Summary
When you scroll in the parameters menu of an item of the graphical interface, it is also activating the zoom of the schematic.
### Steps to reproduce
- open the graphical interface
- insert an item
- open the parameters of the item
- scroll in these parameters
- behind the menu, you will see that it is also zooming and dezooming the schematic
### What is the expected *correct* behavior?
The scroll should not have an impact on the zoomhttps://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/68OMEGALPES Version Bug2021-10-20T15:11:59+02:00EXT HaichengLINGOMEGALPES Version Bug
### Summary
J'ai créé un model simple d'OMEGalpes avec un node unique, un unité de énergy shiftable, un unité de énergy non shiftable, un pv production, import de réseau et export de réseau (voir graphe ci-dessous). J'ai essayé de maxi...
### Summary
J'ai créé un model simple d'OMEGalpes avec un node unique, un unité de énergy shiftable, un unité de énergy non shiftable, un pv production, import de réseau et export de réseau (voir graphe ci-dessous). J'ai essayé de maximizer le taux d'autoconsommation de ce système. Pour OMEGALPES 0.3.0, mon model marche bien, mais pour OMEGALPES 0.4.0, la somme de l'énergy shiftable est doublé après l'optimization.
![image](/uploads/ce64671e99010376c44d9b285489ddae/image.png)
### Steps to reproduce
Code ci-dessous pour mon modèle simple.
```
from omegalpes.energy.energy_nodes import EnergyNode
from omegalpes.energy.units.consumption_units import VariableConsumptionUnit, \
FixedConsumptionUnit, \
ShiftableConsumptionUnit
from omegalpes.energy.units.conversion_units import \
ElectricalToThermalConversionUnit
from omegalpes.energy.units.production_units import FixedProductionUnit, \
VariableProductionUnit
from omegalpes.energy.units.storage_units import StorageUnit
from omegalpes.general.optimisation.elements import DynamicConstraint, \
ActorDynamicConstraint
from omegalpes.general.optimisation.model import OptimisationModel
from omegalpes.general.utils.plots import plt, plot_node_energetic_flows
from omegalpes.general.utils.output_data import save_energy_flows
from omegalpes.general.time import TimeUnit
import time as pytime
ticks=pytime.time()
time=TimeUnit(periods=24*2,dt=0.5)
model = OptimisationModel(time=time, name='test1')
shiftable_profil=[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.9539886794999997,15.615420819999999,11.920456660000001,11.686931215000001,6.328051115000001,0.0,0.0,0.0,0.0,0.0,0.0,0.0,4.9798052539999995,2.3410368835,1.198254565,5.09158163,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
non_shiftable_profil=[0.37543609600000005,0.3827568758,0.41772119455,0.41300544539999995,0.37572268635000006,0.45921000115,0.40829399094999996,0.3626934204999999,0.40511711730000005,0.45187492395,0.3541168846,2.0367472584999997,5.593399205000001,3.2283945739999997,1.8756685155000001,5.161145234999999,4.257118335,0.2818472856,0.39048589219999996,0.525636969,0.39893672599999996,0.3304699479,0.35347408525,1.8127138985,19.184854825,9.824261025,2.7618319745,2.8369244629999995,2.8619368235000002,5.112723865,13.10237332,0.422179015,0.50466066,0.3183611662,0.2983260663,0.55899239,0.36345739684999995,0.2980055731,0.41351376185,1.070029914,1.1156348735000001,0.5006441875,0.4488774645,0.3891072421,0.3614403071,0.3448761461,0.38707076985,0.37071801174999996]
pv_production_j1=[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.524,4.07,4.106,8.404,7.148,10.054,9.658,14.5,4.798,8.348,17.664,8.268,6.598,24.48,28.418,22.656,21.186,10.436,6.79,3.64,2.738,3.93,4.062,5.51,0.608,0.124,0.0,0.0,0.0,0.0,0.0,0.0, 0.0]
non_shiftable_consommation=FixedConsumptionUnit(time, 'non_shiftable_consommation', energy_type='Electrical', p=non_shiftable_profil)
shiftable_consommation= ShiftableConsumptionUnit(time, name='shiftable_consommation',
power_values=shiftable_profil,
energy_type='Electrical')
# Create the electrical grid imports as a production
elec_grid_imports = VariableProductionUnit(time, 'elec_grid_imports',
energy_type='Electrical')
# Create the electrical grid exports as a consumption
elec_grid_exports = VariableConsumptionUnit(time, 'elec_grid_exports',
energy_type='Electrical')
PV_prod_j1 = FixedProductionUnit(time, name='PV_prod_j1',energy_type='Electrical', p= pv_production_j1)
imp_exp = DynamicConstraint(name='imp_exp',
exp_t='elec_grid_imports_u[t] + '
'elec_grid_exports_u[t] <= 1.5',
parent=elec_grid_imports)
# Add the constraint to the elec_grid_imports model
setattr(elec_grid_imports, 'imp_exp', imp_exp)
elec_grid_imports.minimize_production()
elec_node = EnergyNode(time, 'elec_node', energy_type='Electrical')
elec_node.connect_units(shiftable_consommation,non_shiftable_consommation,elec_grid_imports,
elec_grid_exports, PV_prod_j1)
model.add_nodes(elec_node)
new_time = pytime.time()
print('duration =', new_time - ticks)
model.solve_and_update()
flows = elec_node.get_flows
profile_table=pd.Series()
for flow in flows:
label = flow.parent.name
parent = flow.parent
# Get the power profiles
if isinstance(flow.value, list):
energy_flow = flow.value
elif isinstance(flow.value, dict):
energy_flow = list(flow.value.values())
energy_flow_data=pd.Series(energy_flow,name=label )
profile_table=pd.concat([profile_table,energy_flow_data],axis=1)
print(sum(profile_table['shiftable_consommation']))
print('*'*20)
print(sum(shiftable_profil))
```
### What is the current *bug* behavior?
Marche bien pour 0.3.0, mais pas pour Omegalpes 0.4.0,la somme de l'énergy shiftable est doubléSacha HodencqSacha Hodencqhttps://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/62"Ghost" additional energy production whenever a ConversionUnit's outlet is li...2020-10-23T17:08:22+02:00EXT Jaume Fitó"Ghost" additional energy production whenever a ConversionUnit's outlet is linked to more than 1 nodeIt seems that when the production sub-unit of a Conversion Unit is linked directly to more than 1 Energy Node, OMEGAlpes "assumes" that the unit can deliver its maximum power output to **all nodes at the same time**. As a result, the tot...It seems that when the production sub-unit of a Conversion Unit is linked directly to more than 1 Energy Node, OMEGAlpes "assumes" that the unit can deliver its maximum power output to **all nodes at the same time**. As a result, the total energy delivered by the ConversionUnit can be up to X times superior to its actual maximum production, with X being the number of downstream nodes connected to the production sub-unit.
Results plotted for the energy nodes reveal this "ghost" additional production, but otherwise it goes unnoticed by the Conversion Unit. The production sub-unit's "e_tot" respects the Conversion Unit's energy balance, but the aggregated energy received by all downstream nodes connected to the production sub-unit does not. Apparently, OMEGAlpes does not give any Warning for this misformulation. The user can only notice by analyzing the profiles.
I'm aware that the proper way to code it user-level would be to connect the ConversionUnit.production_unit to just 1 Node, which then exports to all target nodes downstream. But anyway, there should be some mechanism to protect users from this issue.
----------
_**Example:**_
![issue_diagram](/uploads/d0a64ea0a1a6370874c7f86febd75947/issue_diagram.png)
_solar_thermal_collectors = ElectricalToThermalConversionUnit(time, name='solar_thermal_collectors', elec_to_therm_ratio=0.7)_
_space_heating_node = EnergyNode(time, name='space_heating_node', energy_type='Thermal')_
_dhw_node = EnergyNode(time, name='dhw_node', energy_type='Thermal')_
_space_heating_node.connect_units(solar_thermal_collectors.thermal_production_unit,
heat_pump_heating.thermal_production_unit,
zac_2_heating, zac_3_heating, hameau_heating)_
_dhw_node.connect_units(thermal_storage, zac_2_dhw, zac_3_dhw,
hameau_dhw, heat_pump_dhw.thermal_production_unit,
solar_thermal_collectors.thermal_production_unit)_
----------
**ElectricalToThermalConversionUnit's inlet and outlet power profiles:**
(It can be seen that the energy balance is respected)
![solar_thermal_panel](/uploads/1e3dc4bf206e7b13da7ab34933ee8d0b/solar_thermal_panel.png)
**Both nodes downstream:**
(At every time step between t = 9 h and t = 16 h the Energy Nodes are receiving from the ElectricalToThermalConversionUnit, in total, twice the maximum energy that that unit can possibly deliver.)
![space_heating_node](/uploads/672d698593a73203ad4206869d7ff293/space_heating_node.png)
![dhw_node](/uploads/28d9e85f40d55d5e8eb0deacc2ccfab8/dhw_node.png)https://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/58Bug with Shiftable Energy Unit2020-05-05T09:54:20+02:00Lou MorrietBug with Shiftable Energy Unit### Summary
A ShiftableEnergyUnit does not respects the profil given as a parameter.
It considers the maximum of energy it can use, and if mandatory is True, e_min=e_max however, pmin != pmax
### Steps to reproduce
Create a ShiftableP...### Summary
A ShiftableEnergyUnit does not respects the profil given as a parameter.
It considers the maximum of energy it can use, and if mandatory is True, e_min=e_max however, pmin != pmax
### Steps to reproduce
Create a ShiftableProductionUnit with power_value = [1,2,3,4,5,6]
Create a VariableConsumptionUnit
show the power after solving with p.get_value()
### Example Project
[test_daily_shiftable.py](/uploads/336b5eb7b4b0b945a0ec1239a809a070/test_daily_shiftable.py)
### What is the current *bug* behavior?
The power_values given as a parameter is not respected
power_value = [4, 5, 6, 2, 3, 4, 7, 8, 13, 15]
and load.p = [0,0,..., 25,25,25,25,25,2]
### What is the expected *correct* behavior?
and load.p = [0,0,... 4, 5, 6, 2, 3, 4, 7, 8, 13, 15]
### Possible fixes
add to enable that the energy_unit is on during the same time as
indicated in the list power_values :
```
cst_name_len = 'def_len_power_values'
cst_len = DefinitionConstraint(name=cst_name_len,
exp="lpSum({0}_u[t] for t in "
"time.I) == "
"len({"
"1})".format(self.name,
power_profile))
setattr(self, cst_name_len, cst_len)
```Lou MorrietLou Morriethttps://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/45e_tot calculation for storage2019-11-27T14:31:33+01:00Sacha Hodencqe_tot calculation for storage<!---
Please read this!
Before opening a new issue, make sure to search for keywords in the issues
filtered by the "Bug" label, following this link :
- https://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/issues?label_name%...<!---
Please read this!
Before opening a new issue, make sure to search for keywords in the issues
filtered by the "Bug" label, following this link :
- https://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/issues?label_name%5B%5D=bug
and verify the issue you're about to submit isn't a duplicate.
--->
### Summary
The e_tot calculation is defined in EnergyUnits as :
`{0}_e_tot == time.DT * lpSum({0}_p[t]for t in time.I`
while p[t] in storage units is calculated as :
`{0}_p[t] == {0}_pc[t] - {0}_pd[t]`
### Steps to reproduce
Opening the storage design example and printing e_tot
`print(STORAGE.e_tot)`
### What is the current *bug* behavior?
The previous command gives a wrong result for e_tot but the right result for the difference between e_ch and e_disch that can be obtained as follow:
`print("sum pcharge", sum(STORAGE.pc.value.values()))
print("sum pdischarge", sum(STORAGE.pd.value.values()))`
### What is the expected *correct* behavior?
e_ch and e_disch should be created and easily accessible, and e_tot also accessible but indicated as the difference between e_ch and e_dischSacha HodencqSacha Hodencqhttps://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/43Calculate the sum of consumption commons and hot water tanks from a new file2019-11-14T11:50:15+01:00Clélia BriantCalculate the sum of consumption commons and hot water tanks from a new file### Summary
I am working on getting the data of the new file : Communs_+chauffe_eau_180924_au_190826.csv. It has an other format than the others that is why I was working on implementing a new function for FixconsumptionUnit to be able ...### Summary
I am working on getting the data of the new file : Communs_+chauffe_eau_180924_au_190826.csv. It has an other format than the others that is why I was working on implementing a new function for FixconsumptionUnit to be able to use the data from the file. It represents the consumption of the commons and the hot water tanks.
But the code doesn't manage to calculate the sum of this consumption whereas it can do it for the others consumptions unit as the one of the dwellings (LOAD)
### Steps to reproduce
- Collect the file : TestcommonsandHWT_from24to26nov.csv which is the file we want to extract the datas.
- Use my proposition of version input_data where I created an adapted function which can read this file (it has not the same format than the others): read_dateiniso8601_data_csv_file(file_path=None, start=None, end=None):
- Run the code input-data.py (new version) and terrain1_enogrid_BRIANT.py
### What is the current *bug* behavior?
It says the CONSCHWT has a total consumption of 0 kWh (total consumption of the hot water tanks and the commons), which is not possible.
### What is the expected *correct* behavior?
CONSCHWT has a total consumption of 67,1 kWh
### Relevant logs and/or screenshots, python output
![Capture_d_écran_2019-11-14_à_11.38.21](/uploads/8771d112fdb359942a53b50793e7b07b/Capture_d_écran_2019-11-14_à_11.38.21.png)
![Capture_d_écran_2019-11-14_à_11.39.47](/uploads/32bb2aafb70985f395cb7d1af283b954/Capture_d_écran_2019-11-14_à_11.39.47.png)
![Capture_d_écran_2019-11-14_à_11.39.57](/uploads/6ac32eafcd0c9e5c0f3961c5e36400d6/Capture_d_écran_2019-11-14_à_11.39.57.png)
![Capture_d_écran_2019-11-14_à_11.40.15](/uploads/6845f893293d5528ceadbb14ff482abd/Capture_d_écran_2019-11-14_à_11.40.15.png)
![Capture_d_écran_2019-11-14_à_11.40.35](/uploads/36a0c4d477c172594f24019913691703/Capture_d_écran_2019-11-14_à_11.40.35.png)
![Capture_d_écran_2019-11-14_à_11.40.45](/uploads/5787f084bfa859f043ab640b3523d5d9/Capture_d_écran_2019-11-14_à_11.40.45.png)
![Capture_d_écran_2019-11-14_à_11.41.04](/uploads/a60474469da173603501d848dac74b8a/Capture_d_écran_2019-11-14_à_11.41.04.png)https://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/39No error with two fixed units with differents amount of energy2019-07-18T14:51:08+02:00Lou MorrietNo 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 ...### 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)
```Lou MorrietLou Morriethttps://gricad-gitlab.univ-grenoble-alpes.fr/omegalpes/omegalpes/-/issues/28Past states - Edge behaviour of the storage2019-11-25T10:48:10+01:00EXT HodencqPast states - Edge behaviour of the storageSince the energy calculation is made for t+1, wrong discharging or charging power can happen during the last timestep. Static constraints need to be set to prevent this edge behaviour.
The past states management also has to be investigated.Since the energy calculation is made for t+1, wrong discharging or charging power can happen during the last timestep. Static constraints need to be set to prevent this edge behaviour.
The past states management also has to be investigated.Sacha HodencqSacha Hodencq