-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindexed_model.py
105 lines (90 loc) · 3.67 KB
/
indexed_model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
from pyomo.core.base import Var, ConcreteModel, Objective, Constraint, Set, maximize
class IndexedModel(ConcreteModel):
"""
Creates a Model
Allows devices to be added, their values, constraints and incomes added to the Model
Use the methods to set the objective and the overall energy balance after all devices have been added
Indexed because every value exists for every time step
"""
def __init__(self, index, *args, **kwargs):
super().__init__(*args, **kwargs)
self.t = index
self.income_objective = []
self.fulfillment_objective = []
self.devices = []
self.sources = []
self.energy_types = []
def set_index(self, index):
self.t = Set(initialize=index)
def get_index(self):
return self.t
def set_value(self, name, value):
var = Var(self.t, within=value.within, initialize=0)
full_name = name + "_" + value.name
setattr(self, full_name, var)
def set_constraint(self, device_name, constraint_name, expr):
setattr(
self, device_name + "_" + constraint_name, Constraint(self.t, rule=expr)
)
def set_objective_with_weights(
self,
income_weight,
fulfillment_weight,
step_length,
max_mean_deviation,
min_mean_deviation,
min_income,
max_income,
):
self.income_sum = sum(sum(objective[t] for t in self.t) for objective in self.income_objective)
self.income_dof = (self.income_sum - min_income) / (max_income - min_income)
self.mean_deviation = (
sum(
sum((f[t] * step_length / 3600) for t in self.t)
for f in self.fulfillment_objective
)
/ 96
)
self.fulfillment_dof = 1 - (self.mean_deviation - min_mean_deviation) / (max_mean_deviation - min_mean_deviation)
expr = self.income_dof * income_weight + self.fulfillment_dof * fulfillment_weight
self.obj = Objective(rule=expr, sense=maximize)
def get_attribute(self, device, key):
return getattr(self, device.name + "_" + key)
def get_attribute_by_name(self, name, key):
return getattr(self, name + "_" + key)
def add_device(self, device):
energy_types = device.energy_types
for energy_type in energy_types:
if energy_type not in self.energy_types:
self.energy_types.append(energy_type)
for value in device.values:
self.set_value(device.name, value)
for param in device.params:
self.set_value(device.name, param)
for constraint in device.constraints:
self.set_constraint(device.name + "_c", constraint[0], constraint[1])
self.devices.append(device)
if device.has_income_objective:
self.income_objective.append(getattr(self, device.name + "_income"))
if device.has_fulfillment_objective:
self.fulfillment_objective.append(
getattr(self, device.name + "_fulfillment")
)
def generate_power_balance(self):
for energy_type in self.energy_types:
self.set_constraint(
energy_type,
"power_balance",
lambda model, t: sum(
[
model.get_attribute(device, f"{energy_type}_power")[t]
for device in list(
filter(
lambda device: energy_type in device.energy_types,
self.devices,
)
)
]
)
== 0,
)