foxes 0.7.1__py3-none-any.whl → 0.7.3__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 +60 -46
- foxes/algorithms/downwind/models/farm_wakes_calc.py +17 -6
- foxes/algorithms/downwind/models/point_wakes_calc.py +13 -45
- foxes/algorithms/iterative/iterative.py +1 -1
- foxes/algorithms/iterative/models/farm_wakes_calc.py +18 -4
- foxes/constants.py +5 -0
- foxes/core/__init__.py +2 -1
- foxes/core/ground_model.py +254 -0
- foxes/core/model.py +3 -2
- foxes/core/partial_wakes_model.py +19 -3
- foxes/core/states.py +33 -0
- foxes/core/wake_model.py +138 -2
- foxes/data/__init__.py +1 -1
- foxes/data/states/WRF-Timeseries-3000.nc +0 -0
- foxes/data/states/windio_timeseries_5000.nc +0 -0
- foxes/data/static_data.py +7 -0
- foxes/data/windio/DTU_10MW_turbine.yaml +10 -0
- foxes/data/windio/__init__.py +0 -0
- foxes/data/windio/windio_5turbines_timeseries.yaml +63 -0
- foxes/input/states/__init__.py +1 -0
- foxes/input/states/multi_height.py +225 -6
- foxes/input/windio/__init__.py +6 -1
- foxes/input/windio/get_states.py +115 -0
- foxes/input/windio/read_attributes.py +321 -0
- foxes/input/windio/read_farm.py +163 -0
- foxes/input/windio/read_fields.py +164 -0
- foxes/input/windio/runner.py +105 -0
- foxes/input/windio/windio.py +136 -254
- foxes/models/__init__.py +2 -1
- foxes/models/ground_models/__init__.py +2 -0
- foxes/models/ground_models/no_ground.py +12 -0
- foxes/models/ground_models/wake_mirror.py +161 -0
- foxes/models/model_book.py +114 -164
- foxes/models/partial_wakes/axiwake.py +27 -4
- foxes/models/partial_wakes/top_hat.py +26 -4
- foxes/models/turbine_types/PCt_file.py +1 -0
- foxes/models/turbine_types/PCt_from_two.py +92 -0
- foxes/models/wake_frames/yawed_wakes.py +41 -38
- foxes/models/wake_models/__init__.py +0 -1
- foxes/models/wake_models/induction/__init__.py +1 -0
- foxes/models/wake_models/induction/rankine_half_body.py +1 -1
- foxes/models/wake_models/induction/vortex_sheet.py +227 -0
- foxes/models/wake_models/ti/crespo_hernandez.py +26 -24
- foxes/models/wake_models/ti/iec_ti.py +33 -26
- foxes/models/wake_models/wind/bastankhah14.py +11 -32
- foxes/models/wake_models/wind/bastankhah16.py +30 -34
- foxes/models/wake_models/wind/jensen.py +13 -29
- foxes/models/wake_models/wind/turbopark.py +31 -61
- foxes/models/wake_superpositions/ws_max.py +1 -0
- foxes/models/wake_superpositions/ws_pow.py +1 -0
- foxes/models/wake_superpositions/ws_quadratic.py +1 -0
- foxes/output/grids.py +6 -6
- foxes/output/output.py +6 -6
- foxes/utils/__init__.py +1 -1
- foxes/utils/factory.py +284 -76
- {foxes-0.7.1.dist-info → foxes-0.7.3.dist-info}/METADATA +8 -6
- {foxes-0.7.1.dist-info → foxes-0.7.3.dist-info}/RECORD +65 -51
- {foxes-0.7.1.dist-info → foxes-0.7.3.dist-info}/WHEEL +1 -1
- foxes/models/wake_models/wake_mirror.py +0 -196
- /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.1.dist-info → foxes-0.7.3.dist-info}/LICENSE +0 -0
- {foxes-0.7.1.dist-info → foxes-0.7.3.dist-info}/top_level.txt +0 -0
- {foxes-0.7.1.dist-info → foxes-0.7.3.dist-info}/zip-safe +0 -0
foxes/models/model_book.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from math import sqrt
|
|
2
2
|
import foxes.models as fm
|
|
3
3
|
import foxes.variables as FV
|
|
4
|
-
from foxes.utils import
|
|
4
|
+
from foxes.utils import FDict
|
|
5
5
|
|
|
6
6
|
from foxes.core import (
|
|
7
7
|
PointDataModel,
|
|
@@ -16,6 +16,7 @@ from foxes.core import (
|
|
|
16
16
|
WakeModel,
|
|
17
17
|
AxialInductionModel,
|
|
18
18
|
TurbineInductionModel,
|
|
19
|
+
GroundModel,
|
|
19
20
|
)
|
|
20
21
|
|
|
21
22
|
|
|
@@ -25,42 +26,45 @@ class ModelBook:
|
|
|
25
26
|
|
|
26
27
|
Attributes
|
|
27
28
|
----------
|
|
28
|
-
point_models: foxes.utils.
|
|
29
|
+
point_models: foxes.utils.FDict
|
|
29
30
|
The point models. Keys: model name str,
|
|
30
31
|
values: foxes.core.PointDataModel
|
|
31
|
-
rotor_models: foxes.utils.
|
|
32
|
+
rotor_models: foxes.utils.FDict
|
|
32
33
|
The rotor models. Keys: model name str,
|
|
33
34
|
values: foxes.core.RotorModel
|
|
34
|
-
turbine_types: foxes.utils.
|
|
35
|
+
turbine_types: foxes.utils.FDict
|
|
35
36
|
The turbine type models. Keys: model name str,
|
|
36
37
|
values: foxes.core.TurbineType
|
|
37
|
-
turbine_models: foxes.utils.
|
|
38
|
+
turbine_models: foxes.utils.FDict
|
|
38
39
|
The turbine models. Keys: model name str,
|
|
39
40
|
values: foxes.core.TurbineModel
|
|
40
|
-
farm_models: foxes.utils.
|
|
41
|
+
farm_models: foxes.utils.FDict
|
|
41
42
|
The farm models. Keys: model name str,
|
|
42
43
|
values: foxes.core.FarmModel
|
|
43
|
-
farm_controllers: foxes.utils.
|
|
44
|
+
farm_controllers: foxes.utils.FDict
|
|
44
45
|
The farm controllers. Keys: model name str,
|
|
45
46
|
values: foxes.core.FarmController
|
|
46
|
-
partial_wakes: foxes.utils.
|
|
47
|
+
partial_wakes: foxes.utils.FDict
|
|
47
48
|
The partial wakes. Keys: model name str,
|
|
48
49
|
values: foxes.core.PartialWakeModel
|
|
49
|
-
wake_frames: foxes.utils.
|
|
50
|
+
wake_frames: foxes.utils.FDict
|
|
50
51
|
The wake frames. Keys: model name str,
|
|
51
52
|
values: foxes.core.WakeFrame
|
|
52
|
-
wake_superpositions: foxes.utils.
|
|
53
|
+
wake_superpositions: foxes.utils.FDict
|
|
53
54
|
The wake superposition models. Keys: model name str,
|
|
54
55
|
values: foxes.core.WakeSuperposition
|
|
55
|
-
wake_models: foxes.utils.
|
|
56
|
+
wake_models: foxes.utils.FDict
|
|
56
57
|
The wake models. Keys: model name str,
|
|
57
58
|
values: foxes.core.WakeModel
|
|
58
|
-
induction_models: foxes.utils.
|
|
59
|
+
induction_models: foxes.utils.FDict
|
|
59
60
|
The induction models. Keys: model name str,
|
|
60
61
|
values: foxes.core.AxialInductionModel
|
|
61
|
-
|
|
62
|
+
ground_models: foxes.utils.FDict
|
|
63
|
+
The ground models. Keys: model name str,
|
|
64
|
+
values: foxes.core.GroundModel
|
|
65
|
+
sources: foxes.utils.FDict
|
|
62
66
|
All sources dict
|
|
63
|
-
base_classes: foxes.utils.
|
|
67
|
+
base_classes: foxes.utils.FDict
|
|
64
68
|
The base classes for all model types
|
|
65
69
|
|
|
66
70
|
:group: models
|
|
@@ -77,7 +81,7 @@ class ModelBook:
|
|
|
77
81
|
Path to power/ct curve file, for creation
|
|
78
82
|
of default turbine type model
|
|
79
83
|
"""
|
|
80
|
-
self.point_models =
|
|
84
|
+
self.point_models = FDict(name="point_models")
|
|
81
85
|
self.point_models["tke2ti"] = fm.point_models.TKE2TI()
|
|
82
86
|
|
|
83
87
|
self.rotor_models = FDict(name="rotor_models")
|
|
@@ -88,8 +92,11 @@ class ModelBook:
|
|
|
88
92
|
n2 = float(n2)
|
|
89
93
|
n = int(sqrt(n2))
|
|
90
94
|
if n**2 != n2:
|
|
91
|
-
raise Exception(
|
|
95
|
+
raise Exception(
|
|
96
|
+
f"GridRotor factory: Value {n2} is not the square of an integer"
|
|
97
|
+
)
|
|
92
98
|
return n
|
|
99
|
+
|
|
93
100
|
self.rotor_models.add_factory(
|
|
94
101
|
fm.rotor_models.GridRotor,
|
|
95
102
|
"grid<n2>",
|
|
@@ -100,7 +107,7 @@ class ModelBook:
|
|
|
100
107
|
)
|
|
101
108
|
self.rotor_models.add_factory(
|
|
102
109
|
fm.rotor_models.GridRotor,
|
|
103
|
-
"
|
|
110
|
+
"grid<n2>_raw",
|
|
104
111
|
kwargs=dict(calc_vars=rvars, reduce=False),
|
|
105
112
|
var2arg={"n2": "n"},
|
|
106
113
|
n2=_n2n,
|
|
@@ -115,13 +122,13 @@ class ModelBook:
|
|
|
115
122
|
)
|
|
116
123
|
self.rotor_models.add_factory(
|
|
117
124
|
fm.rotor_models.LevelRotor,
|
|
118
|
-
"
|
|
125
|
+
"level<n>_raw",
|
|
119
126
|
kwargs=dict(calc_vars=rvars, reduce=False),
|
|
120
127
|
n=lambda x: int(x),
|
|
121
128
|
hints={"n": "(Number of vertical levels)"},
|
|
122
129
|
)
|
|
123
130
|
|
|
124
|
-
self.turbine_types =
|
|
131
|
+
self.turbine_types = FDict(name="turbine_types")
|
|
125
132
|
self.turbine_types["null_type"] = fm.turbine_types.NullType()
|
|
126
133
|
self.turbine_types["NREL5MW"] = fm.turbine_types.PCtFile(
|
|
127
134
|
"NREL-5MW-D126-H90.csv", rho=1.225
|
|
@@ -165,8 +172,10 @@ class ModelBook:
|
|
|
165
172
|
"kTI_<kTI>_<kb>",
|
|
166
173
|
kTI=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
167
174
|
kb=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
168
|
-
hints={
|
|
169
|
-
|
|
175
|
+
hints={
|
|
176
|
+
"kTI": "(Value, e.g. 004 for 0.04)",
|
|
177
|
+
"kb": "(Value, e.g. 004 for 0.04)",
|
|
178
|
+
},
|
|
170
179
|
)
|
|
171
180
|
self.turbine_models.add_factory(
|
|
172
181
|
fm.turbine_models.kTI,
|
|
@@ -174,8 +183,10 @@ class ModelBook:
|
|
|
174
183
|
kwargs=dict(ti_var=FV.AMB_TI),
|
|
175
184
|
kTI=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
176
185
|
kb=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
177
|
-
hints={
|
|
178
|
-
|
|
186
|
+
hints={
|
|
187
|
+
"kTI": "(Value, e.g. 004 for 0.04)",
|
|
188
|
+
"kb": "(Value, e.g. 004 for 0.04)",
|
|
189
|
+
},
|
|
179
190
|
)
|
|
180
191
|
|
|
181
192
|
self.turbine_models["hubh_data"] = fm.turbine_models.RotorCentreCalc(
|
|
@@ -187,7 +198,7 @@ class ModelBook:
|
|
|
187
198
|
}
|
|
188
199
|
)
|
|
189
200
|
|
|
190
|
-
self.farm_models =
|
|
201
|
+
self.farm_models = FDict(
|
|
191
202
|
name="farm_models",
|
|
192
203
|
**{
|
|
193
204
|
f"farm_{mname}": fm.farm_models.Turbine2FarmModel(m)
|
|
@@ -195,7 +206,7 @@ class ModelBook:
|
|
|
195
206
|
},
|
|
196
207
|
)
|
|
197
208
|
|
|
198
|
-
self.farm_controllers =
|
|
209
|
+
self.farm_controllers = FDict(
|
|
199
210
|
name="farm_controllers",
|
|
200
211
|
basic_ctrl=fm.farm_controllers.BasicFarmController(),
|
|
201
212
|
)
|
|
@@ -224,13 +235,10 @@ class ModelBook:
|
|
|
224
235
|
name="wake_frames",
|
|
225
236
|
rotor_wd=fm.wake_frames.RotorWD(var_wd=FV.WD),
|
|
226
237
|
rotor_wd_farmo=fm.wake_frames.FarmOrder(),
|
|
227
|
-
yawed=fm.wake_frames.YawedWakes(),
|
|
228
238
|
)
|
|
229
|
-
self.wake_frames.
|
|
239
|
+
self.wake_frames.add_k_factory(
|
|
230
240
|
fm.wake_frames.YawedWakes,
|
|
231
|
-
"
|
|
232
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
233
|
-
hints={"k": "(Value, e.g. 004 for 0.04)"},
|
|
241
|
+
"yawed_[wake_k]",
|
|
234
242
|
)
|
|
235
243
|
self.wake_frames.add_factory(
|
|
236
244
|
fm.wake_frames.Streamlines2D,
|
|
@@ -246,11 +254,13 @@ class ModelBook:
|
|
|
246
254
|
)
|
|
247
255
|
|
|
248
256
|
self.wake_frames["timelines"] = fm.wake_frames.Timelines()
|
|
257
|
+
|
|
249
258
|
def _todt(x):
|
|
250
259
|
if x[-1] == "s":
|
|
251
|
-
return float(x[:-1])/60
|
|
260
|
+
return float(x[:-1]) / 60
|
|
252
261
|
elif x[-3:] == "min":
|
|
253
262
|
return float(x[:-3])
|
|
263
|
+
|
|
254
264
|
self.wake_frames.add_factory(
|
|
255
265
|
fm.wake_frames.Timelines,
|
|
256
266
|
"timelines_<dt>",
|
|
@@ -266,7 +276,7 @@ class ModelBook:
|
|
|
266
276
|
hints={"dt": "(Time step, e.g '10s', '1min' etc.)"},
|
|
267
277
|
)
|
|
268
278
|
|
|
269
|
-
self.wake_superpositions =
|
|
279
|
+
self.wake_superpositions = FDict(
|
|
270
280
|
name="wake_superpositions",
|
|
271
281
|
ws_linear=fm.wake_superpositions.WSLinear(scale_amb=False),
|
|
272
282
|
ws_linear_lim=fm.wake_superpositions.WSLinear(
|
|
@@ -309,192 +319,119 @@ class ModelBook:
|
|
|
309
319
|
ti_max=fm.wake_superpositions.TIMax(superp_to_amb="quadratic"),
|
|
310
320
|
)
|
|
311
321
|
|
|
312
|
-
self.axial_induction =
|
|
313
|
-
self.axial_induction["Betz"] = fm.
|
|
314
|
-
self.axial_induction["Madsen"] = (
|
|
315
|
-
fm.axial_induction_models.MadsenAxialInduction()
|
|
316
|
-
)
|
|
322
|
+
self.axial_induction = FDict(name="induction_models")
|
|
323
|
+
self.axial_induction["Betz"] = fm.axial_induction.BetzAxialInduction()
|
|
324
|
+
self.axial_induction["Madsen"] = fm.axial_induction.MadsenAxialInduction()
|
|
317
325
|
|
|
318
326
|
self.wake_models = FDict(name="wake_models")
|
|
319
327
|
|
|
320
|
-
self.wake_models.
|
|
328
|
+
self.wake_models.add_k_factory(
|
|
321
329
|
fm.wake_models.wind.JensenWake,
|
|
322
|
-
"Jensen_<superposition>",
|
|
330
|
+
"Jensen_<superposition>_[wake_k]",
|
|
331
|
+
kwargs=dict(induction="Betz"),
|
|
323
332
|
superposition=lambda s: f"ws_{s}",
|
|
324
333
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
325
334
|
)
|
|
326
|
-
self.wake_models.add_factory(
|
|
327
|
-
fm.wake_models.wind.JensenWake,
|
|
328
|
-
"Jensen_<superposition>_k<k>",
|
|
329
|
-
superposition=lambda s: f"ws_{s}",
|
|
330
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
331
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
332
|
-
"k": "(Value, e.g. 004 for 0.04)"},
|
|
333
|
-
)
|
|
334
335
|
|
|
335
|
-
self.wake_models.
|
|
336
|
+
self.wake_models.add_k_factory(
|
|
336
337
|
fm.wake_models.wind.Bastankhah2014,
|
|
337
|
-
"Bastankhah2014_<superposition>",
|
|
338
|
-
kwargs=dict(sbeta_factor=0.2),
|
|
338
|
+
"Bastankhah2014_<superposition>_[wake_k]",
|
|
339
|
+
kwargs=dict(sbeta_factor=0.2, induction="Madsen"),
|
|
339
340
|
superposition=lambda s: f"ws_{s}",
|
|
340
341
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
341
342
|
)
|
|
342
|
-
self.wake_models.
|
|
343
|
+
self.wake_models.add_k_factory(
|
|
343
344
|
fm.wake_models.wind.Bastankhah2014,
|
|
344
|
-
"
|
|
345
|
-
kwargs=dict(sbeta_factor=0.2),
|
|
346
|
-
superposition=lambda s: f"ws_{s}",
|
|
347
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
348
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
349
|
-
"k": "(Value, e.g. 004 for 0.04)"},
|
|
350
|
-
)
|
|
351
|
-
self.wake_models.add_factory(
|
|
352
|
-
fm.wake_models.wind.Bastankhah2014,
|
|
353
|
-
"Bastankhah2014B_<superposition>",
|
|
345
|
+
"Bastankhah2014B_<superposition>_[wake_k]",
|
|
354
346
|
kwargs=dict(sbeta_factor=0.2, induction="Betz"),
|
|
355
347
|
superposition=lambda s: f"ws_{s}",
|
|
356
348
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
357
349
|
)
|
|
358
|
-
self.wake_models.
|
|
350
|
+
self.wake_models.add_k_factory(
|
|
359
351
|
fm.wake_models.wind.Bastankhah2014,
|
|
360
|
-
"
|
|
361
|
-
kwargs=dict(sbeta_factor=0.
|
|
362
|
-
superposition=lambda s: f"ws_{s}",
|
|
363
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
364
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
365
|
-
"k": "(Value, e.g. 004 for 0.04)"},
|
|
366
|
-
)
|
|
367
|
-
self.wake_models.add_factory(
|
|
368
|
-
fm.wake_models.wind.Bastankhah2014,
|
|
369
|
-
"Bastankhah025_<superposition>",
|
|
370
|
-
kwargs=dict(sbeta_factor=0.25),
|
|
352
|
+
"Bastankhah025_<superposition>_[wake_k]",
|
|
353
|
+
kwargs=dict(sbeta_factor=0.25, induction="Madsen"),
|
|
371
354
|
superposition=lambda s: f"ws_{s}",
|
|
372
355
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
373
356
|
)
|
|
374
|
-
self.wake_models.
|
|
357
|
+
self.wake_models.add_k_factory(
|
|
375
358
|
fm.wake_models.wind.Bastankhah2014,
|
|
376
|
-
"
|
|
377
|
-
kwargs=dict(sbeta_factor=0.25),
|
|
378
|
-
superposition=lambda s: f"ws_{s}",
|
|
379
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
380
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
381
|
-
"k": "(Value, e.g. 004 for 0.04)"},
|
|
382
|
-
)
|
|
383
|
-
self.wake_models.add_factory(
|
|
384
|
-
fm.wake_models.wind.Bastankhah2014,
|
|
385
|
-
"Bastankhah025B_<superposition>",
|
|
359
|
+
"Bastankhah025B_<superposition>_[wake_k]",
|
|
386
360
|
kwargs=dict(sbeta_factor=0.25, induction="Betz"),
|
|
387
361
|
superposition=lambda s: f"ws_{s}",
|
|
388
362
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
389
363
|
)
|
|
390
|
-
self.wake_models.add_factory(
|
|
391
|
-
fm.wake_models.wind.Bastankhah2014,
|
|
392
|
-
"Bastankhah025B_<superposition>_k<k>",
|
|
393
|
-
kwargs=dict(sbeta_factor=0.25, induction="Betz"),
|
|
394
|
-
superposition=lambda s: f"ws_{s}",
|
|
395
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
396
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
397
|
-
"k": "(Value, e.g. 004 for 0.04)"},
|
|
398
|
-
)
|
|
399
364
|
|
|
400
|
-
self.wake_models.
|
|
365
|
+
self.wake_models.add_k_factory(
|
|
401
366
|
fm.wake_models.wind.Bastankhah2016,
|
|
402
|
-
"Bastankhah2016_<superposition>",
|
|
367
|
+
"Bastankhah2016_<superposition>_[wake_k]",
|
|
368
|
+
kwargs=dict(induction="Madsen"),
|
|
403
369
|
superposition=lambda s: f"ws_{s}",
|
|
404
370
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
405
371
|
)
|
|
406
|
-
self.wake_models.
|
|
372
|
+
self.wake_models.add_k_factory(
|
|
407
373
|
fm.wake_models.wind.Bastankhah2016,
|
|
408
|
-
"
|
|
409
|
-
superposition=lambda s: f"ws_{s}",
|
|
410
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
411
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
412
|
-
"k": "(Value, e.g. 004 for 0.04)"},
|
|
413
|
-
)
|
|
414
|
-
self.wake_models.add_factory(
|
|
415
|
-
fm.wake_models.wind.Bastankhah2016,
|
|
416
|
-
"Bastankhah2016B_<superposition>",
|
|
374
|
+
"Bastankhah2016B_<superposition>_[wake_k]",
|
|
417
375
|
kwargs=dict(induction="Betz"),
|
|
418
376
|
superposition=lambda s: f"ws_{s}",
|
|
419
377
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
420
378
|
)
|
|
421
|
-
self.wake_models.add_factory(
|
|
422
|
-
fm.wake_models.wind.Bastankhah2016,
|
|
423
|
-
"Bastankhah2016B_<superposition>_k<k>",
|
|
424
|
-
kwargs=dict(induction="Betz"),
|
|
425
|
-
superposition=lambda s: f"ws_{s}",
|
|
426
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
427
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
428
|
-
"k": "(Value, e.g. 004 for 0.04)"},
|
|
429
|
-
)
|
|
430
379
|
|
|
431
|
-
self.wake_models.
|
|
380
|
+
self.wake_models.add_k_factory(
|
|
432
381
|
fm.wake_models.wind.TurbOParkWake,
|
|
433
|
-
"TurbOPark_<superposition>",
|
|
382
|
+
"TurbOPark_<superposition>_[wake_k]",
|
|
383
|
+
kwargs=dict(induction="Madsen"),
|
|
434
384
|
superposition=lambda s: f"ws_{s}",
|
|
435
385
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
436
386
|
)
|
|
437
|
-
self.wake_models.
|
|
387
|
+
self.wake_models.add_k_factory(
|
|
438
388
|
fm.wake_models.wind.TurbOParkWake,
|
|
439
|
-
"
|
|
440
|
-
superposition=lambda s: f"ws_{s}",
|
|
441
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
442
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
443
|
-
"k": "(Value, e.g. 004 for 0.04)"},
|
|
444
|
-
)
|
|
445
|
-
self.wake_models.add_factory(
|
|
446
|
-
fm.wake_models.wind.TurbOParkWake,
|
|
447
|
-
"TurbOParkB_<superposition>",
|
|
389
|
+
"TurbOParkB_<superposition>_[wake_k]",
|
|
448
390
|
kwargs=dict(induction="Betz"),
|
|
449
391
|
superposition=lambda s: f"ws_{s}",
|
|
450
392
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
451
393
|
)
|
|
452
|
-
self.wake_models.add_factory(
|
|
453
|
-
fm.wake_models.wind.TurbOParkWake,
|
|
454
|
-
"TurbOParkB_<superposition>_k<k>",
|
|
455
|
-
kwargs=dict(induction="Betz"),
|
|
456
|
-
superposition=lambda s: f"ws_{s}",
|
|
457
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
458
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
459
|
-
"k": "(Value, e.g. 004 for 0.04)"},
|
|
460
|
-
)
|
|
461
394
|
|
|
462
|
-
self.wake_models.
|
|
395
|
+
self.wake_models.add_k_factory(
|
|
463
396
|
fm.wake_models.wind.TurbOParkWakeIX,
|
|
464
|
-
"TurbOParkIX_<superposition>_dx<dx>",
|
|
397
|
+
"TurbOParkIX_<superposition>_[wake_k]_dx<dx>",
|
|
465
398
|
superposition=lambda s: f"ws_{s}",
|
|
466
399
|
dx=lambda x: float(x),
|
|
467
|
-
hints={
|
|
468
|
-
|
|
400
|
+
hints={
|
|
401
|
+
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
402
|
+
"dx": "(Integration step in m)",
|
|
403
|
+
},
|
|
469
404
|
)
|
|
470
405
|
|
|
471
|
-
self.wake_models.
|
|
472
|
-
fm.wake_models.
|
|
473
|
-
"
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
hints={"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
478
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
479
|
-
"dx": "(Integration step in m)"},
|
|
406
|
+
self.wake_models.add_k_factory(
|
|
407
|
+
fm.wake_models.ti.CrespoHernandezTIWake,
|
|
408
|
+
"CrespoHernandez_<superposition>_[wake_k]",
|
|
409
|
+
kwargs=dict(use_ambti=False),
|
|
410
|
+
superposition=lambda s: f"ti_{s}",
|
|
411
|
+
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
480
412
|
)
|
|
481
413
|
|
|
482
414
|
self.wake_models.add_factory(
|
|
483
|
-
fm.wake_models.ti.
|
|
484
|
-
"
|
|
485
|
-
kwargs=dict(
|
|
415
|
+
fm.wake_models.ti.IECTIWake,
|
|
416
|
+
"IECTI2005_<superposition>",
|
|
417
|
+
kwargs=dict(iec_type="2005"),
|
|
486
418
|
superposition=lambda s: f"ti_{s}",
|
|
487
419
|
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
488
420
|
)
|
|
489
421
|
|
|
490
422
|
self.wake_models.add_factory(
|
|
491
|
-
fm.wake_models.ti.
|
|
492
|
-
"
|
|
493
|
-
kwargs=dict(
|
|
423
|
+
fm.wake_models.ti.IECTIWake,
|
|
424
|
+
"IECTI2019_<superposition>",
|
|
425
|
+
kwargs=dict(iec_type="2019"),
|
|
494
426
|
superposition=lambda s: f"ti_{s}",
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
427
|
+
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
428
|
+
)
|
|
429
|
+
self.wake_models.add_k_factory(
|
|
430
|
+
fm.wake_models.ti.IECTIWake,
|
|
431
|
+
"IECTI2019k_<superposition>_[wake_k]",
|
|
432
|
+
kwargs=dict(iec_type="2019", opening_angle=None),
|
|
433
|
+
superposition=lambda s: f"ti_{s}",
|
|
434
|
+
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
498
435
|
)
|
|
499
436
|
|
|
500
437
|
self.wake_models.add_factory(
|
|
@@ -504,11 +441,10 @@ class ModelBook:
|
|
|
504
441
|
superposition=lambda s: f"ti_{s}",
|
|
505
442
|
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
506
443
|
)
|
|
507
|
-
|
|
508
|
-
self.wake_models.add_factory(
|
|
444
|
+
self.wake_models.add_k_factory(
|
|
509
445
|
fm.wake_models.ti.IECTIWake,
|
|
510
|
-
"
|
|
511
|
-
kwargs=dict(iec_type="
|
|
446
|
+
"IECTI2005k_<superposition>_[wake_k]",
|
|
447
|
+
kwargs=dict(iec_type="2005", opening_angle=None),
|
|
512
448
|
superposition=lambda s: f"ti_{s}",
|
|
513
449
|
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
514
450
|
)
|
|
@@ -519,8 +455,20 @@ class ModelBook:
|
|
|
519
455
|
self.wake_models[f"SelfSimilar2020"] = (
|
|
520
456
|
fm.wake_models.induction.SelfSimilar2020()
|
|
521
457
|
)
|
|
458
|
+
self.wake_models[f"VortexSheet"] = fm.wake_models.induction.VortexSheet()
|
|
459
|
+
|
|
460
|
+
self.ground_models = FDict(name="ground_models")
|
|
461
|
+
self.ground_models["no_ground"] = fm.ground_models.NoGround()
|
|
462
|
+
self.ground_models["ground_mirror"] = fm.ground_models.GroundMirror()
|
|
463
|
+
self.ground_models.add_factory(
|
|
464
|
+
fm.ground_models.WakeMirror,
|
|
465
|
+
"blh_mirror_h<height>",
|
|
466
|
+
var2arg={"height": "heights"},
|
|
467
|
+
height=lambda h: [0.0, float(h)],
|
|
468
|
+
hints={"height": "(Boundary layer wake reflection height)"},
|
|
469
|
+
)
|
|
522
470
|
|
|
523
|
-
self.sources =
|
|
471
|
+
self.sources = FDict(
|
|
524
472
|
name="sources",
|
|
525
473
|
point_models=self.point_models,
|
|
526
474
|
rotor_models=self.rotor_models,
|
|
@@ -533,8 +481,9 @@ class ModelBook:
|
|
|
533
481
|
wake_superpositions=self.wake_superpositions,
|
|
534
482
|
wake_models=self.wake_models,
|
|
535
483
|
axial_induction=self.axial_induction,
|
|
484
|
+
ground_models=self.ground_models,
|
|
536
485
|
)
|
|
537
|
-
self.base_classes =
|
|
486
|
+
self.base_classes = FDict(
|
|
538
487
|
name="base_classes",
|
|
539
488
|
point_models=PointDataModel,
|
|
540
489
|
rotor_models=RotorModel,
|
|
@@ -547,6 +496,7 @@ class ModelBook:
|
|
|
547
496
|
wake_superpositions=WakeSuperposition,
|
|
548
497
|
wake_models=WakeModel,
|
|
549
498
|
axial_induction=AxialInductionModel,
|
|
499
|
+
ground_models=GroundModel,
|
|
550
500
|
)
|
|
551
501
|
|
|
552
502
|
for s in self.sources.values():
|
|
@@ -663,7 +613,7 @@ class ModelBook:
|
|
|
663
613
|
|
|
664
614
|
"""
|
|
665
615
|
for ms in self.sources.values():
|
|
666
|
-
if isinstance(ms,
|
|
616
|
+
if isinstance(ms, FDict):
|
|
667
617
|
for m in ms.values():
|
|
668
618
|
if m.initialized:
|
|
669
619
|
m.finalize(algo, verbosity)
|
|
@@ -44,6 +44,31 @@ class PartialAxiwake(PartialCentre):
|
|
|
44
44
|
def __repr__(self):
|
|
45
45
|
return f"{type(self).__name__}(n={self.n})"
|
|
46
46
|
|
|
47
|
+
def check_wmodel(self, wmodel, error=True):
|
|
48
|
+
"""
|
|
49
|
+
Checks the wake model type
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
wmodel: foxes.core.WakeModel
|
|
54
|
+
The wake model to be tested
|
|
55
|
+
error: bool
|
|
56
|
+
Flag for raising TypeError
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
chk: bool
|
|
61
|
+
True if wake model is compatible
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
if not isinstance(wmodel, AxisymmetricWakeModel):
|
|
65
|
+
if error:
|
|
66
|
+
raise TypeError(
|
|
67
|
+
f"Partial wakes '{self.name}': Cannot be applied to wake model '{wmodel.name}', since not an AxisymmetricWakeModel"
|
|
68
|
+
)
|
|
69
|
+
return False
|
|
70
|
+
return True
|
|
71
|
+
|
|
47
72
|
def contribute(
|
|
48
73
|
self,
|
|
49
74
|
algo,
|
|
@@ -79,10 +104,8 @@ class PartialAxiwake(PartialCentre):
|
|
|
79
104
|
The wake model
|
|
80
105
|
|
|
81
106
|
"""
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
f"Partial wakes '{self.name}': Cannot be applied to wake model '{wmodel.name}', since not an AxisymmetricWakeModel"
|
|
85
|
-
)
|
|
107
|
+
# check:
|
|
108
|
+
self.check_wmodel(wmodel, error=True)
|
|
86
109
|
|
|
87
110
|
# prepare:
|
|
88
111
|
n_states = mdata.n_states
|
|
@@ -24,6 +24,31 @@ class PartialTopHat(PartialCentre):
|
|
|
24
24
|
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
|
+
def check_wmodel(self, wmodel, error=True):
|
|
28
|
+
"""
|
|
29
|
+
Checks the wake model type
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
wmodel: foxes.core.WakeModel
|
|
34
|
+
The wake model to be tested
|
|
35
|
+
error: bool
|
|
36
|
+
Flag for raising TypeError
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
chk: bool
|
|
41
|
+
True if wake model is compatible
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
if not isinstance(wmodel, TopHatWakeModel):
|
|
45
|
+
if error:
|
|
46
|
+
raise TypeError(
|
|
47
|
+
f"Partial wakes '{self.name}': Cannot be applied to wake model '{wmodel.name}', since not a TopHatWakeModel"
|
|
48
|
+
)
|
|
49
|
+
return False
|
|
50
|
+
return True
|
|
51
|
+
|
|
27
52
|
def __init__(self, rotor_model=None):
|
|
28
53
|
"""
|
|
29
54
|
Constructor.
|
|
@@ -105,10 +130,7 @@ class PartialTopHat(PartialCentre):
|
|
|
105
130
|
The wake model
|
|
106
131
|
|
|
107
132
|
"""
|
|
108
|
-
|
|
109
|
-
raise TypeError(
|
|
110
|
-
f"Partial wakes '{self.name}': Cannot be applied to wake model '{wmodel.name}', since not a TopHatWakeModel"
|
|
111
|
-
)
|
|
133
|
+
self.check_wmodel(wmodel, error=True)
|
|
112
134
|
|
|
113
135
|
wcoos = algo.wake_frame.get_wake_coos(algo, mdata, fdata, tdata, downwind_index)
|
|
114
136
|
x = wcoos[:, :, 0, 0]
|
|
@@ -103,6 +103,7 @@ class PCtFile(TurbineType):
|
|
|
103
103
|
|
|
104
104
|
def __repr__(self):
|
|
105
105
|
a = f"D={self.D}, H={self.H}, P_nominal={self.P_nominal}, P_unit={self.P_unit}, rho={self.rho}"
|
|
106
|
+
a += f", var_ws_ct={self.WSCT}, var_ws_P={self.WSP}"
|
|
106
107
|
return f"{type(self).__name__}({a})"
|
|
107
108
|
|
|
108
109
|
def output_farm_vars(self, algo):
|