foxes 0.7.0.6__py3-none-any.whl → 0.7.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of foxes might be problematic. Click here for more details.
- foxes/VERSION +1 -1
- foxes/algorithms/downwind/downwind.py +6 -4
- foxes/core/wake_frame.py +4 -4
- foxes/models/__init__.py +1 -1
- foxes/models/model_book.py +385 -248
- foxes/models/wake_models/wind/bastankhah14.py +1 -1
- foxes/models/wake_models/wind/turbopark.py +67 -17
- foxes/models/wake_superpositions/__init__.py +4 -4
- foxes/models/wake_superpositions/ws_linear.py +156 -0
- foxes/models/wake_superpositions/ws_max.py +159 -0
- foxes/models/wake_superpositions/ws_pow.py +162 -0
- foxes/models/wake_superpositions/ws_quadratic.py +156 -0
- foxes/utils/__init__.py +1 -0
- foxes/utils/factory.py +349 -0
- {foxes-0.7.0.6.dist-info → foxes-0.7.2.dist-info}/METADATA +1 -1
- {foxes-0.7.0.6.dist-info → foxes-0.7.2.dist-info}/RECORD +23 -22
- /foxes/models/{axial_induction_models → axial_induction}/__init__.py +0 -0
- /foxes/models/{axial_induction_models → axial_induction}/betz.py +0 -0
- /foxes/models/{axial_induction_models → axial_induction}/madsen.py +0 -0
- {foxes-0.7.0.6.dist-info → foxes-0.7.2.dist-info}/LICENSE +0 -0
- {foxes-0.7.0.6.dist-info → foxes-0.7.2.dist-info}/WHEEL +0 -0
- {foxes-0.7.0.6.dist-info → foxes-0.7.2.dist-info}/top_level.txt +0 -0
- {foxes-0.7.0.6.dist-info → foxes-0.7.2.dist-info}/zip-safe +0 -0
|
@@ -178,3 +178,159 @@ class WSQuadratic(WakeSuperposition):
|
|
|
178
178
|
if self.lim_high is not None:
|
|
179
179
|
w = np.minimum(w, self.lim_high - amb_results)
|
|
180
180
|
return w
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class WSQuadraticLocal(WakeSuperposition):
|
|
184
|
+
"""
|
|
185
|
+
Local quadratic supersposition of wind deficit results
|
|
186
|
+
|
|
187
|
+
Attributes
|
|
188
|
+
----------
|
|
189
|
+
lim_low: float
|
|
190
|
+
Lower limit of the final waked wind speed
|
|
191
|
+
lim_high: float
|
|
192
|
+
Upper limit of the final waked wind speed
|
|
193
|
+
|
|
194
|
+
:group: models.wake_superpositions
|
|
195
|
+
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
def __init__(self, lim_low=None, lim_high=None):
|
|
199
|
+
"""
|
|
200
|
+
Constructor.
|
|
201
|
+
|
|
202
|
+
Parameters
|
|
203
|
+
----------
|
|
204
|
+
lim_low: float
|
|
205
|
+
Lower limit of the final waked wind speed
|
|
206
|
+
lim_high: float
|
|
207
|
+
Upper limit of the final waked wind speed
|
|
208
|
+
|
|
209
|
+
"""
|
|
210
|
+
super().__init__()
|
|
211
|
+
self.lim_low = lim_low
|
|
212
|
+
self.lim_high = lim_high
|
|
213
|
+
|
|
214
|
+
def __repr__(self):
|
|
215
|
+
a = f"lim_low={self.lim_low}, lim_high={self.lim_high}"
|
|
216
|
+
return f"{type(self).__name__}({a})"
|
|
217
|
+
|
|
218
|
+
def input_farm_vars(self, algo):
|
|
219
|
+
"""
|
|
220
|
+
The variables which are needed for running
|
|
221
|
+
the model.
|
|
222
|
+
|
|
223
|
+
Parameters
|
|
224
|
+
----------
|
|
225
|
+
algo: foxes.core.Algorithm
|
|
226
|
+
The calculation algorithm
|
|
227
|
+
|
|
228
|
+
Returns
|
|
229
|
+
-------
|
|
230
|
+
input_vars: list of str
|
|
231
|
+
The input variable names
|
|
232
|
+
|
|
233
|
+
"""
|
|
234
|
+
return []
|
|
235
|
+
|
|
236
|
+
def add_wake(
|
|
237
|
+
self,
|
|
238
|
+
algo,
|
|
239
|
+
mdata,
|
|
240
|
+
fdata,
|
|
241
|
+
tdata,
|
|
242
|
+
downwind_index,
|
|
243
|
+
st_sel,
|
|
244
|
+
variable,
|
|
245
|
+
wake_delta,
|
|
246
|
+
wake_model_result,
|
|
247
|
+
):
|
|
248
|
+
"""
|
|
249
|
+
Add a wake delta to previous wake deltas,
|
|
250
|
+
at rotor points.
|
|
251
|
+
|
|
252
|
+
Parameters
|
|
253
|
+
----------
|
|
254
|
+
algo: foxes.core.Algorithm
|
|
255
|
+
The calculation algorithm
|
|
256
|
+
mdata: foxes.core.MData
|
|
257
|
+
The model data
|
|
258
|
+
fdata: foxes.core.FData
|
|
259
|
+
The farm data
|
|
260
|
+
tdata: foxes.core.TData
|
|
261
|
+
The target point data
|
|
262
|
+
downwind_index: int
|
|
263
|
+
The index of the wake causing turbine
|
|
264
|
+
in the downwnd order
|
|
265
|
+
st_sel: numpy.ndarray of bool
|
|
266
|
+
The selection of targets, shape: (n_states, n_targets)
|
|
267
|
+
variable: str
|
|
268
|
+
The variable name for which the wake deltas applies
|
|
269
|
+
wake_delta: numpy.ndarray
|
|
270
|
+
The original wake deltas, shape:
|
|
271
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
272
|
+
wake_model_result: numpy.ndarray
|
|
273
|
+
The new wake deltas of the selected rotors,
|
|
274
|
+
shape: (n_st_sel, n_tpoints, ...)
|
|
275
|
+
|
|
276
|
+
Returns
|
|
277
|
+
-------
|
|
278
|
+
wdelta: numpy.ndarray
|
|
279
|
+
The updated wake deltas, shape:
|
|
280
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
281
|
+
|
|
282
|
+
"""
|
|
283
|
+
if variable not in [FV.REWS, FV.REWS2, FV.REWS3, FV.WS]:
|
|
284
|
+
raise ValueError(
|
|
285
|
+
f"Superposition '{self.name}': Expecting wind speed variable, got {variable}"
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
if np.any(st_sel):
|
|
289
|
+
wake_delta[st_sel] += wake_model_result**2
|
|
290
|
+
|
|
291
|
+
return wake_delta
|
|
292
|
+
|
|
293
|
+
def calc_final_wake_delta(
|
|
294
|
+
self,
|
|
295
|
+
algo,
|
|
296
|
+
mdata,
|
|
297
|
+
fdata,
|
|
298
|
+
variable,
|
|
299
|
+
amb_results,
|
|
300
|
+
wake_delta,
|
|
301
|
+
):
|
|
302
|
+
"""
|
|
303
|
+
Calculate the final wake delta after adding all
|
|
304
|
+
contributions.
|
|
305
|
+
|
|
306
|
+
Parameters
|
|
307
|
+
----------
|
|
308
|
+
algo: foxes.core.Algorithm
|
|
309
|
+
The calculation algorithm
|
|
310
|
+
mdata: foxes.core.MData
|
|
311
|
+
The model data
|
|
312
|
+
fdata: foxes.core.FData
|
|
313
|
+
The farm data
|
|
314
|
+
variable: str
|
|
315
|
+
The variable name for which the wake deltas applies
|
|
316
|
+
amb_results: numpy.ndarray
|
|
317
|
+
The ambient results at targets,
|
|
318
|
+
shape: (n_states, n_targets, n_tpoints)
|
|
319
|
+
wake_delta: numpy.ndarray
|
|
320
|
+
The wake deltas at targets, shape:
|
|
321
|
+
(n_states, n_targets, n_tpoints)
|
|
322
|
+
|
|
323
|
+
Returns
|
|
324
|
+
-------
|
|
325
|
+
final_wake_delta: numpy.ndarray
|
|
326
|
+
The final wake delta, which will be added to the ambient
|
|
327
|
+
results by simple plus operation. Shape:
|
|
328
|
+
(n_states, n_targets, n_tpoints)
|
|
329
|
+
|
|
330
|
+
"""
|
|
331
|
+
w = -np.sqrt(wake_delta) * amb_results
|
|
332
|
+
if self.lim_low is not None:
|
|
333
|
+
w = np.maximum(w, self.lim_low - amb_results)
|
|
334
|
+
if self.lim_high is not None:
|
|
335
|
+
w = np.minimum(w, self.lim_high - amb_results)
|
|
336
|
+
return w
|
foxes/utils/__init__.py
CHANGED
|
@@ -7,6 +7,7 @@ from .pandas_utils import PandasFileHelper
|
|
|
7
7
|
from .xarray_utils import write_nc
|
|
8
8
|
from .subclasses import all_subclasses
|
|
9
9
|
from .dict import Dict
|
|
10
|
+
from .factory import Factory, FDict
|
|
10
11
|
from .data_book import DataBook
|
|
11
12
|
from .cubic_roots import cubic_roots
|
|
12
13
|
from .geopandas_utils import read_shp, shp2csv, read_shp_polygons, shp2geom2d
|
foxes/utils/factory.py
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from .dict import Dict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Factory:
|
|
7
|
+
"""
|
|
8
|
+
Constructs objects from a choice of allowed
|
|
9
|
+
constructor parameters
|
|
10
|
+
|
|
11
|
+
Attributes
|
|
12
|
+
----------
|
|
13
|
+
base: class
|
|
14
|
+
The class of which objects are to be created
|
|
15
|
+
name_template: str
|
|
16
|
+
The name template, e.g. 'name_<A>_<B>_<C>' for
|
|
17
|
+
variables A, B, C
|
|
18
|
+
args: tuple
|
|
19
|
+
Fixed arguments for the base class
|
|
20
|
+
kwargs: dict
|
|
21
|
+
Fixed arguments for the base class
|
|
22
|
+
var2arg: dict
|
|
23
|
+
Mapping from variable to constructor argument
|
|
24
|
+
hints: dict
|
|
25
|
+
Hints for print_toc, only for variables for which the
|
|
26
|
+
options are functions or missing
|
|
27
|
+
options: dict
|
|
28
|
+
For each variable, e.g. A, B or C, the list or dict
|
|
29
|
+
or function that maps a str to the actual value
|
|
30
|
+
|
|
31
|
+
:group: utils
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
base,
|
|
38
|
+
name_template,
|
|
39
|
+
args=(),
|
|
40
|
+
kwargs={},
|
|
41
|
+
var2arg={},
|
|
42
|
+
hints={},
|
|
43
|
+
**options,
|
|
44
|
+
):
|
|
45
|
+
"""
|
|
46
|
+
Constructor.
|
|
47
|
+
|
|
48
|
+
Parameters
|
|
49
|
+
----------
|
|
50
|
+
base: class
|
|
51
|
+
The class of which objects are to be created
|
|
52
|
+
name_template: str
|
|
53
|
+
The name template, e.g. 'name_<A>_<B>_<C>' for
|
|
54
|
+
variables A, B, C
|
|
55
|
+
args: tuple
|
|
56
|
+
Fixed arguments for the base class
|
|
57
|
+
kwargs: dict
|
|
58
|
+
Fixed arguments for the base class
|
|
59
|
+
var2arg: dict
|
|
60
|
+
Mapping from variable to constructor argument
|
|
61
|
+
hints: dict
|
|
62
|
+
Hints for print_toc, only for variables for which the
|
|
63
|
+
options are functions or missing
|
|
64
|
+
options: dict
|
|
65
|
+
For each variable, e.g. A, B or C, the list or dict
|
|
66
|
+
or function that maps a str to the actual value
|
|
67
|
+
|
|
68
|
+
"""
|
|
69
|
+
self.base = base
|
|
70
|
+
self.name_template = name_template
|
|
71
|
+
self.args = args
|
|
72
|
+
self.kwargs = kwargs
|
|
73
|
+
self.var2arg = var2arg
|
|
74
|
+
self.hints = hints
|
|
75
|
+
|
|
76
|
+
parts = name_template.split(">")
|
|
77
|
+
if len(parts) < 2:
|
|
78
|
+
raise ValueError(
|
|
79
|
+
f"Factory '{name_template}': Expecting at least one variable in template, pattern '<..>'"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
self._vars = []
|
|
83
|
+
self._pre = []
|
|
84
|
+
for i, p in enumerate(parts):
|
|
85
|
+
if i < len(parts) - 1:
|
|
86
|
+
parts2 = p.split("<")
|
|
87
|
+
if len(parts2) != 2:
|
|
88
|
+
raise ValueError(
|
|
89
|
+
f"Factory '{name_template}': incomplete pattern brackets '<..>' between variables, e.g. '_'"
|
|
90
|
+
)
|
|
91
|
+
if i > 0 and len(parts2[0]) == 0:
|
|
92
|
+
raise ValueError(
|
|
93
|
+
f"Factory '{name_template}': Missing seperator like '_' in template between variables '{self._vars[-1]}' and '{parts[1]}'"
|
|
94
|
+
)
|
|
95
|
+
self._pre.append(parts2[0])
|
|
96
|
+
self._vars.append(parts2[1])
|
|
97
|
+
else:
|
|
98
|
+
self._pre.append(p)
|
|
99
|
+
|
|
100
|
+
if len(self.variables) > 1:
|
|
101
|
+
for vi, v in enumerate(self.variables):
|
|
102
|
+
p = self._pre[vi]
|
|
103
|
+
if vi < len(self.variables) - 1 and p == "":
|
|
104
|
+
raise ValueError(
|
|
105
|
+
f"Factory '{name_template}': Require indicator before variable '{v}' in template, e.g. '{v}<{v}>'"
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
self.options = Dict(name=f"{self._pre[0]}_options")
|
|
109
|
+
for v, o in options.items():
|
|
110
|
+
if v not in self.variables:
|
|
111
|
+
raise KeyError(
|
|
112
|
+
f"Factory '{name_template}': Variable '{v}' found in options, but not in template"
|
|
113
|
+
)
|
|
114
|
+
if isinstance(o, list) or isinstance(o, tuple):
|
|
115
|
+
o = {str(k): k for k in o}
|
|
116
|
+
if isinstance(o, dict):
|
|
117
|
+
for k in o.keys():
|
|
118
|
+
if not isinstance(k, str):
|
|
119
|
+
raise TypeError(
|
|
120
|
+
f"Factory '{name_template}': Found option for variable '{v}' that is not a str, {k}"
|
|
121
|
+
)
|
|
122
|
+
self.options[v] = Dict(name=f"{self._pre[0]}_options_{v}", **o)
|
|
123
|
+
elif hasattr(o, "__call__"):
|
|
124
|
+
self.options[v] = o
|
|
125
|
+
else:
|
|
126
|
+
raise ValueError(
|
|
127
|
+
f"Factory '{name_template}': Variable '{v}' has option of type '{type(v).__name__}'. Only list, tuple, dict or function are supported"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def name_prefix(self):
|
|
132
|
+
"""
|
|
133
|
+
The beginning of the name template
|
|
134
|
+
|
|
135
|
+
Returns
|
|
136
|
+
-------
|
|
137
|
+
nbase: str
|
|
138
|
+
The beginning of the name template
|
|
139
|
+
|
|
140
|
+
"""
|
|
141
|
+
return self._pre[0]
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def name_suffix(self):
|
|
145
|
+
"""
|
|
146
|
+
The ending of the name template
|
|
147
|
+
|
|
148
|
+
Returns
|
|
149
|
+
-------
|
|
150
|
+
nbase: str
|
|
151
|
+
The ending of the name template
|
|
152
|
+
|
|
153
|
+
"""
|
|
154
|
+
return self._pre[-1]
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def variables(self):
|
|
158
|
+
"""
|
|
159
|
+
The list of variables
|
|
160
|
+
|
|
161
|
+
Returns
|
|
162
|
+
-------
|
|
163
|
+
vrs: list of str
|
|
164
|
+
The variables
|
|
165
|
+
|
|
166
|
+
"""
|
|
167
|
+
return self._vars
|
|
168
|
+
|
|
169
|
+
def __str__(self):
|
|
170
|
+
"""String representation"""
|
|
171
|
+
s = f"{self.name_template}: {self.base.__name__} with"
|
|
172
|
+
for k, d in self.kwargs.items():
|
|
173
|
+
s += f"\n {k}={d}"
|
|
174
|
+
for v in self.variables:
|
|
175
|
+
if v in self.options and isinstance(self.options[v], dict):
|
|
176
|
+
s += f"\n {v} from {list(self.options[v])}"
|
|
177
|
+
else:
|
|
178
|
+
s += f"\n {v}={self.hints.get(v, '(value)')}"
|
|
179
|
+
return s
|
|
180
|
+
|
|
181
|
+
def check_match(self, name):
|
|
182
|
+
"""
|
|
183
|
+
Tests if a name matches the template
|
|
184
|
+
|
|
185
|
+
Parameters
|
|
186
|
+
----------
|
|
187
|
+
name: str
|
|
188
|
+
The name to be checked
|
|
189
|
+
|
|
190
|
+
Returns
|
|
191
|
+
-------
|
|
192
|
+
success: bool
|
|
193
|
+
True if the template is matched
|
|
194
|
+
|
|
195
|
+
"""
|
|
196
|
+
data_str = name
|
|
197
|
+
for vi in range(len(self.variables)):
|
|
198
|
+
p = self._pre[vi]
|
|
199
|
+
i = data_str.find(p)
|
|
200
|
+
j = i + len(p)
|
|
201
|
+
if i < 0 or len(data_str) <= j:
|
|
202
|
+
return False
|
|
203
|
+
data_str = data_str[j:]
|
|
204
|
+
|
|
205
|
+
q = self._pre[vi + 1]
|
|
206
|
+
if q != "":
|
|
207
|
+
i = data_str.find(q)
|
|
208
|
+
j = i + len(q)
|
|
209
|
+
if i < 0 or len(data_str) <= j:
|
|
210
|
+
return False
|
|
211
|
+
else:
|
|
212
|
+
data_str = ""
|
|
213
|
+
|
|
214
|
+
return True
|
|
215
|
+
|
|
216
|
+
def construct(self, name):
|
|
217
|
+
"""
|
|
218
|
+
Create an object of the base class.
|
|
219
|
+
|
|
220
|
+
Parameters
|
|
221
|
+
----------
|
|
222
|
+
name: str
|
|
223
|
+
The name, matching the template
|
|
224
|
+
|
|
225
|
+
Returns
|
|
226
|
+
-------
|
|
227
|
+
obj: object
|
|
228
|
+
The instance of the base class
|
|
229
|
+
|
|
230
|
+
"""
|
|
231
|
+
j = 0
|
|
232
|
+
wlist = []
|
|
233
|
+
for pi, p in enumerate(self._pre):
|
|
234
|
+
if len(p) > 0:
|
|
235
|
+
i = name[j:].find(p)
|
|
236
|
+
if i < 0 or (pi == 0 and i > 0):
|
|
237
|
+
raise ValueError(
|
|
238
|
+
f"Factory '{self.name_template}': Name '{name}' not matching template"
|
|
239
|
+
)
|
|
240
|
+
w = name[j : j + i]
|
|
241
|
+
j += i + len(p)
|
|
242
|
+
else:
|
|
243
|
+
w = name[j:]
|
|
244
|
+
if pi > 0:
|
|
245
|
+
wlist.append(w)
|
|
246
|
+
|
|
247
|
+
kwargs = {}
|
|
248
|
+
for vi, v in enumerate(self.variables):
|
|
249
|
+
w = self.var2arg.get(v, v)
|
|
250
|
+
data = wlist[vi]
|
|
251
|
+
if v in self.options:
|
|
252
|
+
o = self.options[v]
|
|
253
|
+
if hasattr(o, "__call__"):
|
|
254
|
+
kwargs[w] = o(data)
|
|
255
|
+
else:
|
|
256
|
+
kwargs[w] = self.options[v][data]
|
|
257
|
+
else:
|
|
258
|
+
kwargs[w] = data
|
|
259
|
+
|
|
260
|
+
kwargs.update(self.kwargs)
|
|
261
|
+
|
|
262
|
+
return self.base(*self.args, **kwargs)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class FDict(Dict):
|
|
266
|
+
"""
|
|
267
|
+
A dictionary with factory support
|
|
268
|
+
|
|
269
|
+
Attributes
|
|
270
|
+
----------
|
|
271
|
+
store_created: bool
|
|
272
|
+
Flag for storing created objects
|
|
273
|
+
factories: list of foxes.utils.Factory
|
|
274
|
+
The factories
|
|
275
|
+
|
|
276
|
+
:group: utils
|
|
277
|
+
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
def __init__(self, *args, store_created=True, **kwargs):
|
|
281
|
+
"""
|
|
282
|
+
Constructor.
|
|
283
|
+
|
|
284
|
+
Parameters
|
|
285
|
+
----------
|
|
286
|
+
args: tuple, optional
|
|
287
|
+
Parameters for the base class
|
|
288
|
+
store_created: bool
|
|
289
|
+
Flag for storing created objects
|
|
290
|
+
kwargs: dict, optional
|
|
291
|
+
Parameters for the base class
|
|
292
|
+
|
|
293
|
+
"""
|
|
294
|
+
super().__init__(*args, **kwargs)
|
|
295
|
+
self.store_created = store_created
|
|
296
|
+
self.factories = []
|
|
297
|
+
|
|
298
|
+
def add_factory(self, *args, **kwargs):
|
|
299
|
+
"""
|
|
300
|
+
Constructor.
|
|
301
|
+
|
|
302
|
+
Parameters
|
|
303
|
+
----------
|
|
304
|
+
args: tuple, optional
|
|
305
|
+
Parameters for the Factory constructor
|
|
306
|
+
kwargs: dict, optional
|
|
307
|
+
Parameters for the Factory constructor
|
|
308
|
+
|
|
309
|
+
"""
|
|
310
|
+
f = Factory(*args, **kwargs)
|
|
311
|
+
i = len(self.factories)
|
|
312
|
+
for gi in range(len(self.factories) - 1, -1, -1):
|
|
313
|
+
g = self.factories[gi]
|
|
314
|
+
if (
|
|
315
|
+
g.name_prefix == f.name_prefix
|
|
316
|
+
and g.name_suffix == f.name_suffix
|
|
317
|
+
and len(f.variables) > len(g.variables)
|
|
318
|
+
):
|
|
319
|
+
i = gi
|
|
320
|
+
|
|
321
|
+
if i == len(self.factories):
|
|
322
|
+
self.factories.append(f)
|
|
323
|
+
else:
|
|
324
|
+
self.factories.insert(i, f)
|
|
325
|
+
|
|
326
|
+
def __contains__(self, key):
|
|
327
|
+
found = super().__contains__(key)
|
|
328
|
+
if not found:
|
|
329
|
+
for f in self.factories:
|
|
330
|
+
if f.check_match(key):
|
|
331
|
+
return True
|
|
332
|
+
return found
|
|
333
|
+
|
|
334
|
+
def __getitem__(self, key):
|
|
335
|
+
try:
|
|
336
|
+
return super().__getitem__(key)
|
|
337
|
+
except KeyError:
|
|
338
|
+
for f in self.factories:
|
|
339
|
+
try:
|
|
340
|
+
obj = f.construct(key)
|
|
341
|
+
if self.store_created:
|
|
342
|
+
self[key] = obj
|
|
343
|
+
return obj
|
|
344
|
+
except ValueError:
|
|
345
|
+
pass
|
|
346
|
+
|
|
347
|
+
k = ", ".join(sorted(list(self.keys())))
|
|
348
|
+
e = f"{self.name}: Cannot find key '{key}', also no factory matches. Known keys: {k}. Known factories: {[f.name_template for f in self.factories]}"
|
|
349
|
+
raise KeyError(e)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
foxes/VERSION,sha256=
|
|
1
|
+
foxes/VERSION,sha256=0BdnGL0hTOhHTAbtYcOVyhE_38Ks3YbZqpkztA2bVh4,6
|
|
2
2
|
foxes/__init__.py,sha256=4ptDOBaQC8fAd_ZH5XH7d5pIgx3JXEY9xLcK3Nrs2Ow,718
|
|
3
3
|
foxes/constants.py,sha256=UfflqHQ67uSQYFFktZBSe6rrWntoL2ccpMHnKs7zTcA,2650
|
|
4
4
|
foxes/variables.py,sha256=I-S25WejH33ffOcVnmN2TDL1pIxWqg0aM1lhIBwZ9NQ,4454
|
|
5
5
|
foxes/algorithms/__init__.py,sha256=uaXU8OYMT3eclcE6a2b8NkozHVXoM1BF5RJA2XR4DUw,260
|
|
6
6
|
foxes/algorithms/downwind/__init__.py,sha256=lyygq5GMc6NAPmH0b0mhGeccWyuC8JTOEMZl-UlmE5M,53
|
|
7
|
-
foxes/algorithms/downwind/downwind.py,sha256=
|
|
7
|
+
foxes/algorithms/downwind/downwind.py,sha256=7TuClA6ZbHNJg2L9oOrWWUQ_qhRsiRTwYuK1BkN8od0,21690
|
|
8
8
|
foxes/algorithms/downwind/models/__init__.py,sha256=0ov8rjIQ02w3iB6yYCxaswPvHDlPM_8_di6xPh1TTkQ,300
|
|
9
9
|
foxes/algorithms/downwind/models/farm_wakes_calc.py,sha256=nRE_lCwrlVYB9zXJ0XR557IncNb6M7tUbhN9kBPgw_c,5178
|
|
10
10
|
foxes/algorithms/downwind/models/init_farm_data.py,sha256=sTUMYGLU9iHr56prdNRR4cs0yuCFp7gqiCDut685HKM,4022
|
|
@@ -40,7 +40,7 @@ foxes/core/turbine.py,sha256=P5qPKmV1qohZdAKW4lPiUerQkRDTxUOhsvBPQqy8mBo,3054
|
|
|
40
40
|
foxes/core/turbine_model.py,sha256=IcsU848QNHbUhDN5oqd7VnVWKx_VM5UwRhlPsWK_njw,2049
|
|
41
41
|
foxes/core/turbine_type.py,sha256=uet3SiJDqt9bPD8tq5xkq-blGV7o1Nd0lNn_2DlqOyk,3151
|
|
42
42
|
foxes/core/vertical_profile.py,sha256=pgjari78N2CHZOWnidQ_7KGsSs4lTFP9isn-w6e1Yro,1642
|
|
43
|
-
foxes/core/wake_frame.py,sha256=
|
|
43
|
+
foxes/core/wake_frame.py,sha256=JbDWjHtZ6nSt-pSSlIsrKea4shwx_7YViZCCl9kNI_0,10239
|
|
44
44
|
foxes/core/wake_model.py,sha256=HAnYOVvT5gWr1Gyu1CWUe7_uO0nLTdIAHzQCiFN0X-o,4497
|
|
45
45
|
foxes/core/wake_superposition.py,sha256=_XRgHeIVf_g8MkudwCLAX0DcTBp4Wdy9bDJLRPqkQrM,2811
|
|
46
46
|
foxes/core/wind_farm.py,sha256=COJ6iLFeU_EiYJKLzcG2f9k9z3YegHKr-NvrAS1X_ks,1708
|
|
@@ -83,11 +83,11 @@ foxes/input/states/create/random_abl_states.py,sha256=45h0a84FmeLZwxbtwtxs5kmoz8
|
|
|
83
83
|
foxes/input/states/create/random_timeseries.py,sha256=gJpaQ4nEXxOjI4hp3xjNcVbCsmZUm-brXUxoqDb63WE,1266
|
|
84
84
|
foxes/input/windio/__init__.py,sha256=Bj9qtJNapfvgFcjThCI_oDia2hvMKN_seNLgm5KhWhw,89
|
|
85
85
|
foxes/input/windio/windio.py,sha256=GtUS3IpHdvb_f2WPcoutpbKNQMEZbE4Bc0U3EVfXBEQ,7948
|
|
86
|
-
foxes/models/__init__.py,sha256=
|
|
87
|
-
foxes/models/model_book.py,sha256=
|
|
88
|
-
foxes/models/
|
|
89
|
-
foxes/models/
|
|
90
|
-
foxes/models/
|
|
86
|
+
foxes/models/__init__.py,sha256=oLuCuBgSGFPVviqtBhzEu-zo1lxLKeRE0ksqA3dkrz0,406
|
|
87
|
+
foxes/models/model_book.py,sha256=34HoVcIEUneqb4EZZYaC0mhtraulEO_Ga50omRJSAhY,26786
|
|
88
|
+
foxes/models/axial_induction/__init__.py,sha256=CdYOzu45DWu7xrzpRpFIQ6CGZIMABjjy_lqAszjj9lg,78
|
|
89
|
+
foxes/models/axial_induction/betz.py,sha256=rAaq7pnu-FmfYh61BU5Af1h4_bG2AAimP4Qah1aZo88,894
|
|
90
|
+
foxes/models/axial_induction/madsen.py,sha256=_-ycfh8SnIpCKWm1uwx5VH7f49FQvR0y1Nbb_U8xWyU,1403
|
|
91
91
|
foxes/models/farm_controllers/__init__.py,sha256=oDdW_fA3GSkJBzn9Vsd3T9bBVhB9-j_IglFjYV4G2rU,72
|
|
92
92
|
foxes/models/farm_controllers/basic.py,sha256=6pinNXiyfoG3apXhqQWcnxx4vN_7Q63YryXX5Z7kTE0,249
|
|
93
93
|
foxes/models/farm_models/__init__.py,sha256=WoC1Cmeo5-LLdC5I_S9hwZhZOtBnWDL6azjaUTcoOuY,66
|
|
@@ -157,20 +157,20 @@ foxes/models/wake_models/ti/__init__.py,sha256=EOlqFHL2mzcKGFRZqlVYTiqGJqPb6dx7I
|
|
|
157
157
|
foxes/models/wake_models/ti/crespo_hernandez.py,sha256=i02Ye9b5DU6rexYmKWPOvCgerpmws39AKT_02km43C0,8811
|
|
158
158
|
foxes/models/wake_models/ti/iec_ti.py,sha256=kQRqwElW9uL9TJeZ7wNkFs9vLVJfighRCOtAjyn1jh8,6203
|
|
159
159
|
foxes/models/wake_models/wind/__init__.py,sha256=X_QdQ_f3fKCIrZZ9K_CzzsHSl13AyvPRcWdEZ1y9Bk4,223
|
|
160
|
-
foxes/models/wake_models/wind/bastankhah14.py,sha256=
|
|
160
|
+
foxes/models/wake_models/wind/bastankhah14.py,sha256=zPSi3oCiZlzR1XHx6UBb_n3hOBH2tZW16uGVud1I56I,5602
|
|
161
161
|
foxes/models/wake_models/wind/bastankhah16.py,sha256=V3onz6hXBkW0bb9le4n8srjWq23Ama2Fq69iUdM9LHM,17629
|
|
162
162
|
foxes/models/wake_models/wind/jensen.py,sha256=jEBBIARBHydqEC9YHRd5B7WExhBnTpxfty6Ldxd_Q8Y,4639
|
|
163
|
-
foxes/models/wake_models/wind/turbopark.py,sha256=
|
|
164
|
-
foxes/models/wake_superpositions/__init__.py,sha256=
|
|
163
|
+
foxes/models/wake_models/wind/turbopark.py,sha256=PCo9pKVFTB0r5sFfOyd2co6xQZv8H9rm52Po7d8MyRE,15250
|
|
164
|
+
foxes/models/wake_superpositions/__init__.py,sha256=p_pI_bUC-JjpGfg-7hyo3EpB_qVYqg5CCFt_vSG9DF4,371
|
|
165
165
|
foxes/models/wake_superpositions/ti_linear.py,sha256=T9lP5PsHzi04Neq5dS3HDZGwyV7Qzvx_umCbk9M7Zks,3911
|
|
166
166
|
foxes/models/wake_superpositions/ti_max.py,sha256=fnfYmr_Wt9EPZftHoHnqRlTwFWAawrEheGgLA0NwIlA,3936
|
|
167
167
|
foxes/models/wake_superpositions/ti_pow.py,sha256=4ZS3d0ulRkIDaVeG2VvcdjpJch673INQRUGgj37cs_A,4160
|
|
168
168
|
foxes/models/wake_superpositions/ti_quadratic.py,sha256=tkmaoIm7a-Q4c3qtMpBmX25jfcVdt0Qp7Xn0fQrxN4A,3926
|
|
169
|
-
foxes/models/wake_superpositions/ws_linear.py,sha256=
|
|
170
|
-
foxes/models/wake_superpositions/ws_max.py,sha256=
|
|
171
|
-
foxes/models/wake_superpositions/ws_pow.py,sha256=
|
|
169
|
+
foxes/models/wake_superpositions/ws_linear.py,sha256=TiKaRAxNioY4oIloJODfT1zftnkXzhuqfqEkqG33owc,9155
|
|
170
|
+
foxes/models/wake_superpositions/ws_max.py,sha256=MktXVo3PfMgh172DJP_KRftiqs8jXsuaQPLne1jHKyY,9381
|
|
171
|
+
foxes/models/wake_superpositions/ws_pow.py,sha256=aPtm5NwQx6byNfetSX57Z7tVkXtgXIRleSf4grKtZF0,9602
|
|
172
172
|
foxes/models/wake_superpositions/ws_product.py,sha256=8dCDaKfuzHfTEBo0_N7BR-x_qG2tWXTabzPsgpIAtXk,4672
|
|
173
|
-
foxes/models/wake_superpositions/ws_quadratic.py,sha256=
|
|
173
|
+
foxes/models/wake_superpositions/ws_quadratic.py,sha256=jUo4wFkrUPbj-27m3ozCEzab7iamkNZtVlrCwY-Yh2w,9197
|
|
174
174
|
foxes/opt/__init__.py,sha256=okwZagHJMkUkLvKCSQLbE0cjx_47RLl3bEz576j6CdI,172
|
|
175
175
|
foxes/opt/constraints/__init__.py,sha256=UZzN_JlxGaASdGtvBn5d5xwdSDpwO6bklj3vw70IZvU,159
|
|
176
176
|
foxes/opt/constraints/area_geometry.py,sha256=9TFsyuM8_pp3HEUV4N0w0KnhxOk0OLPMKd6ZvNQGC80,6156
|
|
@@ -216,11 +216,12 @@ foxes/output/flow_plots_2d/__init__.py,sha256=2d4RyQYPOYr-HiBCbp1swSPG4Nf3NGezTr
|
|
|
216
216
|
foxes/output/flow_plots_2d/flow_plots.py,sha256=RYdYZui11IlJE5Mm_R3dtkkQDC0XbAz2JyOT1U25PAA,28209
|
|
217
217
|
foxes/output/flow_plots_2d/get_fig.py,sha256=gGMOfzNCukq_l0FZLmi3zSBl0ANkQi2WoKaGTpB6xhc,6169
|
|
218
218
|
foxes/output/flow_plots_2d/seq_flow_ani_plugin.py,sha256=RFlzbZG2L9A583d7wSqZHogP561YEtfcu5M5FaCqIIE,2782
|
|
219
|
-
foxes/utils/__init__.py,sha256=
|
|
219
|
+
foxes/utils/__init__.py,sha256=enB6w5vHEYTVR37UEIh7oIzqIg83XmDMlcEmZQ7bP8g,739
|
|
220
220
|
foxes/utils/cubic_roots.py,sha256=u2Pf-yHZ6EASpFONMfkv0mvldmd1E1VRZxj69YabDoc,3321
|
|
221
221
|
foxes/utils/data_book.py,sha256=DgxusriNH-fhHNN_v6TY3QWcAnrAcw20Wgz7lDfbMeg,5302
|
|
222
222
|
foxes/utils/dict.py,sha256=s922OY22wOKBMbzQ_g-T-MhEw1dga0d3CCwFwd0nI78,886
|
|
223
223
|
foxes/utils/exec_python.py,sha256=BRylxWOyYHpjIZXCuoOp_A-P9VMoQZ13P2vpHs-lqj8,1714
|
|
224
|
+
foxes/utils/factory.py,sha256=_EO9H2xS-ceNJh9okS5FtQYKEGQUdcmhmCPZg6iLZ7w,10036
|
|
224
225
|
foxes/utils/geopandas_helpers.py,sha256=inVQHMco6Op7YN3VFH1DGAJZWREuveJUS7gyoRudw2A,7895
|
|
225
226
|
foxes/utils/geopandas_utils.py,sha256=inVQHMco6Op7YN3VFH1DGAJZWREuveJUS7gyoRudw2A,7895
|
|
226
227
|
foxes/utils/load.py,sha256=7jrCX2GQ_GTgrSu3nz-jfxiyswa7Q3XXCYqobl6bkyk,1290
|
|
@@ -249,9 +250,9 @@ foxes/utils/geom2d/half_plane.py,sha256=kzZD6pkZxZ03MK9WAboWzXb5Ws5dWLQY9GIahD4D
|
|
|
249
250
|
foxes/utils/geom2d/polygon.py,sha256=8ASfy7No_-Pt_xDSeNsDtLEkCjBWsNZK8nIxDQtqeOE,5534
|
|
250
251
|
foxes/utils/runners/__init__.py,sha256=-WL4ZmdgNYldkqhCV6dR-aXCumBrH-Ea-V1shsRhsbs,55
|
|
251
252
|
foxes/utils/runners/runners.py,sha256=Sc06qsCzPduMyxbywgf6G3uHRioDs1qWRSc6GZbLFAY,6932
|
|
252
|
-
foxes-0.7.
|
|
253
|
-
foxes-0.7.
|
|
254
|
-
foxes-0.7.
|
|
255
|
-
foxes-0.7.
|
|
256
|
-
foxes-0.7.
|
|
257
|
-
foxes-0.7.
|
|
253
|
+
foxes-0.7.2.dist-info/LICENSE,sha256=bBCH6mYTPzSepk2s2UUZ3II_ZYXrn1bnSqB85-aZHxU,1071
|
|
254
|
+
foxes-0.7.2.dist-info/METADATA,sha256=4M2qRnVI00yQWjqJ9Fc6srHQh1M-6pSypZlNaeDzVP0,9520
|
|
255
|
+
foxes-0.7.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
256
|
+
foxes-0.7.2.dist-info/top_level.txt,sha256=B4spGR6JHsVHz7CEXsa68xsjYalAA70nBwHa1gfyRHc,6
|
|
257
|
+
foxes-0.7.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
258
|
+
foxes-0.7.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|