generated from rl-institut/rli_template
/
facades.py
165 lines (129 loc) · 4.77 KB
/
facades.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
from oemof.solph import sequence, Sink, Flow
from oemof.solph.components import GenericStorage
from oemof.tabular.facades import Facade
class Bev(GenericStorage, Facade):
r""" A Battery electric vehicle unit.
Note that the investment option is not available for this facade at
the current development state.
Parameters
----------
bus: oemof.solph.Bus
An oemof bus instance where the storage unit is connected to.
storage_capacity: numeric
The total storage capacity of the storage (e.g. in MWh)
capacity: numeric
Installed production capacity of the turbine installed at the
reservoir
efficiency: numeric
Efficiency of the turbine converting inflow to electricity
production, default: 1
profile: array-like
Absolute inflow profile of inflow into the storage
input_parameters: dict
Dictionary to specifiy parameters on the input edge. You can use
all keys that are available for the oemof.solph.network.Flow class.
output_parameters: dict
see: input_parameters
The reservoir is modelled as a storage with a constant inflow:
.. math::
x^{level}(t) =
x^{level}(t-1) \cdot (1 - c^{loss\_rate}(t))
+ x^{profile}(t) - \frac{x^{flow, out}(t)}{c^{efficiency}(t)}
\qquad \forall t \in T
.. math::
x^{level}(0) = 0.5 \cdot c^{capacity}
The inflow is bounded by the exogenous inflow profile. Thus if the inflow
exceeds the maximum capacity of the storage, spillage is possible by
setting :math:`x^{profile}(t)` to lower values.
.. math::
0 \leq x^{profile}(t) \leq c^{profile}(t) \qquad \forall t \in T
The spillage of the reservoir is therefore defined by:
:math:`c^{profile}(t) - x^{profile}(t)`.
Note
----
As the Reservoir is a sub-class of `oemof.solph.GenericStorage` you also
pass all arguments of this class.
Examples
--------
Basic usage examples of the GenericStorage with a random selection of
attributes. See the Flow class for all Flow attributes.
>>> from oemof import solph
>>> from oemof.tabular import facades
>>> my_bus = solph.Bus('my_bus')
>>> my_bev = Bev(
... name='my_bev',
... bus=el_bus,
... carrier='electricity',
... tech='bev',
... storage_capacity=1000,
... capacity=50,
... availability=[0.8, 0.7, 0.6],
... drive_power=[1, 2, 6],
... amount=1e9,
... loss_rate=0.01,
... initial_storage_level=0,
... min_storage_level=[0.1, 0.2, 0.15],
... max_storage_level=[0.9, 0.95, 0.92],
... efficiency=0.93
... )
"""
def __init__(self, *args, **kwargs):
kwargs.update(
{
"_facade_requires_": [
"bus",
"carrier",
"tech",
"availability",
"drive_power",
"amount",
"efficiency",
]
}
)
super().__init__(*args, **kwargs)
self.storage_capacity = kwargs.get("storage_capacity")
self.capacity = kwargs.get("capacity")
self.efficiency = kwargs.get("efficiency", 1)
self.profile = kwargs.get("profile")
self.input_parameters = kwargs.get("input_parameters", {})
self.output_parameters = kwargs.get("output_parameters", {})
self.expandable = bool(kwargs.get("expandable", False))
self.build_solph_components()
def build_solph_components(self):
"""
"""
self.nominal_storage_capacity = self.storage_capacity
self.inflow_conversion_factor = sequence(self.efficiency)
self.outflow_conversion_factor = sequence(self.efficiency)
if self.expandable:
raise NotImplementedError(
"Investment for reservoir class is not implemented."
)
outflow = Sink(
label=self.label + "-outflow",
inputs={
self: Flow(nominal_value=self.amount, actual_value=self.drive_power, fixed=True)
},
)
self.inputs.update(
{
self.bus: Flow(
nominal_value=self.capacity,
max=self.availability,
conversion_factors=self.efficiency,
**self.input_parameters
)
}
)
self.outputs.update(
{
self.bus: Flow(
nominal_value=self.capacity,
max=self.availability,
conversion_factors=self.efficiency,
**self.output_parameters
)
}
)
self.subnodes = (outflow,)