foxes 0.7.2__py3-none-any.whl → 0.7.3.1__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 +57 -45
- 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 +1 -0
- 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 +68 -149
- 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/output/grids.py +6 -6
- foxes/output/output.py +6 -6
- foxes/utils/__init__.py +1 -1
- foxes/utils/factory.py +203 -11
- {foxes-0.7.2.dist-info → foxes-0.7.3.1.dist-info}/METADATA +8 -6
- {foxes-0.7.2.dist-info → foxes-0.7.3.1.dist-info}/RECORD +59 -45
- {foxes-0.7.2.dist-info → foxes-0.7.3.1.dist-info}/WHEEL +1 -1
- foxes/models/wake_models/wake_mirror.py +0 -196
- {foxes-0.7.2.dist-info → foxes-0.7.3.1.dist-info}/LICENSE +0 -0
- {foxes-0.7.2.dist-info → foxes-0.7.3.1.dist-info}/top_level.txt +0 -0
- {foxes-0.7.2.dist-info → foxes-0.7.3.1.dist-info}/zip-safe +0 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from foxes.core import GroundModel
|
|
2
|
+
import foxes.variables as FV
|
|
3
|
+
import foxes.constants as FC
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class WakeMirror(GroundModel):
|
|
7
|
+
"""
|
|
8
|
+
Wake reflection from ground and/or other horizontal planes.
|
|
9
|
+
|
|
10
|
+
Attributes
|
|
11
|
+
----------
|
|
12
|
+
heights: list of float
|
|
13
|
+
The reflection heights
|
|
14
|
+
|
|
15
|
+
:group: models.ground_models
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, heights):
|
|
20
|
+
"""
|
|
21
|
+
Constructor.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
heights: list of float
|
|
26
|
+
The reflection heights
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
super().__init__()
|
|
30
|
+
self.heights = heights
|
|
31
|
+
|
|
32
|
+
def contribute_to_farm_wakes(
|
|
33
|
+
self,
|
|
34
|
+
algo,
|
|
35
|
+
mdata,
|
|
36
|
+
fdata,
|
|
37
|
+
tdata,
|
|
38
|
+
downwind_index,
|
|
39
|
+
wake_deltas,
|
|
40
|
+
wmodel,
|
|
41
|
+
pwake,
|
|
42
|
+
):
|
|
43
|
+
"""
|
|
44
|
+
Modifies wake deltas at target points by
|
|
45
|
+
contributions from the specified wake source turbines.
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
algo: foxes.core.Algorithm
|
|
50
|
+
The calculation algorithm
|
|
51
|
+
mdata: foxes.core.MData
|
|
52
|
+
The model data
|
|
53
|
+
fdata: foxes.core.FData
|
|
54
|
+
The farm data
|
|
55
|
+
tdata: foxes.core.TData
|
|
56
|
+
The target point data
|
|
57
|
+
downwind_index: int
|
|
58
|
+
The index of the wake causing turbine
|
|
59
|
+
in the downwnd order
|
|
60
|
+
wake_deltas: dict
|
|
61
|
+
The wake deltas. Key: variable name,
|
|
62
|
+
value: numpy.ndarray with shape
|
|
63
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
64
|
+
wmodel: foxes.core.WakeModel
|
|
65
|
+
The wake model
|
|
66
|
+
pwake: foxes.core.PartialWakesModel
|
|
67
|
+
The partial wakes model
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
# prepare:
|
|
71
|
+
hh = fdata[FV.H][:, downwind_index].copy()
|
|
72
|
+
|
|
73
|
+
# contribution from main wake:
|
|
74
|
+
wcoos = algo.wake_frame.get_wake_coos(algo, mdata, fdata, tdata, downwind_index)
|
|
75
|
+
wmodel.contribute(algo, mdata, fdata, tdata, downwind_index, wcoos, wake_deltas)
|
|
76
|
+
|
|
77
|
+
# contribution from mirrors:
|
|
78
|
+
tdata[FC.TARGETS] = tdata[FC.TARGETS].copy() # making sure this is no ref
|
|
79
|
+
for h in self.heights:
|
|
80
|
+
|
|
81
|
+
fdata[FV.H][:, downwind_index] = hh + 2 * (h - hh)
|
|
82
|
+
|
|
83
|
+
pwake.contribute(
|
|
84
|
+
algo, mdata, fdata, tdata, downwind_index, wake_deltas, wmodel
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# reset heights:
|
|
88
|
+
fdata[FV.H][:, downwind_index] = hh
|
|
89
|
+
|
|
90
|
+
def contribute_to_point_wakes(
|
|
91
|
+
self,
|
|
92
|
+
algo,
|
|
93
|
+
mdata,
|
|
94
|
+
fdata,
|
|
95
|
+
tdata,
|
|
96
|
+
downwind_index,
|
|
97
|
+
wake_deltas,
|
|
98
|
+
wmodel,
|
|
99
|
+
):
|
|
100
|
+
"""
|
|
101
|
+
Modifies wake deltas at target points by
|
|
102
|
+
contributions from the specified wake source turbines.
|
|
103
|
+
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
algo: foxes.core.Algorithm
|
|
107
|
+
The calculation algorithm
|
|
108
|
+
mdata: foxes.core.MData
|
|
109
|
+
The model data
|
|
110
|
+
fdata: foxes.core.FData
|
|
111
|
+
The farm data
|
|
112
|
+
tdata: foxes.core.TData
|
|
113
|
+
The target point data
|
|
114
|
+
downwind_index: int
|
|
115
|
+
The index of the wake causing turbine
|
|
116
|
+
in the downwnd order
|
|
117
|
+
wake_deltas: dict
|
|
118
|
+
The wake deltas. Key: variable name,
|
|
119
|
+
value: numpy.ndarray with shape
|
|
120
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
121
|
+
wmodel: foxes.core.WakeModel
|
|
122
|
+
The wake model
|
|
123
|
+
|
|
124
|
+
"""
|
|
125
|
+
# prepare:
|
|
126
|
+
hh = fdata[FV.H][:, downwind_index].copy()
|
|
127
|
+
|
|
128
|
+
# contribution from main wake:
|
|
129
|
+
wcoos = algo.wake_frame.get_wake_coos(algo, mdata, fdata, tdata, downwind_index)
|
|
130
|
+
wmodel.contribute(algo, mdata, fdata, tdata, downwind_index, wcoos, wake_deltas)
|
|
131
|
+
|
|
132
|
+
# contribution from mirrors:
|
|
133
|
+
tdata[FC.TARGETS] = tdata[FC.TARGETS].copy() # making sure this is no ref
|
|
134
|
+
for h in self.heights:
|
|
135
|
+
|
|
136
|
+
fdata[FV.H][:, downwind_index] = hh + 2 * (h - hh)
|
|
137
|
+
|
|
138
|
+
wcoos = algo.wake_frame.get_wake_coos(
|
|
139
|
+
algo, mdata, fdata, tdata, downwind_index
|
|
140
|
+
)
|
|
141
|
+
wmodel.contribute(
|
|
142
|
+
algo, mdata, fdata, tdata, downwind_index, wcoos, wake_deltas
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# reset heights:
|
|
146
|
+
fdata[FV.H][:, downwind_index] = hh
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class GroundMirror(WakeMirror):
|
|
150
|
+
"""
|
|
151
|
+
Wake reflection from the ground.
|
|
152
|
+
|
|
153
|
+
:group: models.ground_models
|
|
154
|
+
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
def __init__(self):
|
|
158
|
+
"""
|
|
159
|
+
Constructor.
|
|
160
|
+
"""
|
|
161
|
+
super().__init__(heights=[0.0])
|
foxes/models/model_book.py
CHANGED
|
@@ -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
|
|
|
@@ -58,6 +59,9 @@ class ModelBook:
|
|
|
58
59
|
induction_models: foxes.utils.FDict
|
|
59
60
|
The induction models. Keys: model name str,
|
|
60
61
|
values: foxes.core.AxialInductionModel
|
|
62
|
+
ground_models: foxes.utils.FDict
|
|
63
|
+
The ground models. Keys: model name str,
|
|
64
|
+
values: foxes.core.GroundModel
|
|
61
65
|
sources: foxes.utils.FDict
|
|
62
66
|
All sources dict
|
|
63
67
|
base_classes: foxes.utils.FDict
|
|
@@ -231,13 +235,10 @@ class ModelBook:
|
|
|
231
235
|
name="wake_frames",
|
|
232
236
|
rotor_wd=fm.wake_frames.RotorWD(var_wd=FV.WD),
|
|
233
237
|
rotor_wd_farmo=fm.wake_frames.FarmOrder(),
|
|
234
|
-
yawed=fm.wake_frames.YawedWakes(),
|
|
235
238
|
)
|
|
236
|
-
self.wake_frames.
|
|
239
|
+
self.wake_frames.add_k_factory(
|
|
237
240
|
fm.wake_frames.YawedWakes,
|
|
238
|
-
"
|
|
239
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
240
|
-
hints={"k": "(Value, e.g. 004 for 0.04)"},
|
|
241
|
+
"yawed_[wake_k]",
|
|
241
242
|
)
|
|
242
243
|
self.wake_frames.add_factory(
|
|
243
244
|
fm.wake_frames.Streamlines2D,
|
|
@@ -324,169 +325,76 @@ class ModelBook:
|
|
|
324
325
|
|
|
325
326
|
self.wake_models = FDict(name="wake_models")
|
|
326
327
|
|
|
327
|
-
self.wake_models.
|
|
328
|
+
self.wake_models.add_k_factory(
|
|
328
329
|
fm.wake_models.wind.JensenWake,
|
|
329
|
-
"Jensen_<superposition>",
|
|
330
|
+
"Jensen_<superposition>_[wake_k]",
|
|
331
|
+
kwargs=dict(induction="Betz"),
|
|
330
332
|
superposition=lambda s: f"ws_{s}",
|
|
331
333
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
332
334
|
)
|
|
333
|
-
self.wake_models.add_factory(
|
|
334
|
-
fm.wake_models.wind.JensenWake,
|
|
335
|
-
"Jensen_<superposition>_k<k>",
|
|
336
|
-
superposition=lambda s: f"ws_{s}",
|
|
337
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
338
|
-
hints={
|
|
339
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
340
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
341
|
-
},
|
|
342
|
-
)
|
|
343
335
|
|
|
344
|
-
self.wake_models.
|
|
336
|
+
self.wake_models.add_k_factory(
|
|
345
337
|
fm.wake_models.wind.Bastankhah2014,
|
|
346
|
-
"Bastankhah2014_<superposition>",
|
|
347
|
-
kwargs=dict(sbeta_factor=0.2),
|
|
338
|
+
"Bastankhah2014_<superposition>_[wake_k]",
|
|
339
|
+
kwargs=dict(sbeta_factor=0.2, induction="Madsen"),
|
|
348
340
|
superposition=lambda s: f"ws_{s}",
|
|
349
341
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
350
342
|
)
|
|
351
|
-
self.wake_models.
|
|
343
|
+
self.wake_models.add_k_factory(
|
|
352
344
|
fm.wake_models.wind.Bastankhah2014,
|
|
353
|
-
"
|
|
354
|
-
kwargs=dict(sbeta_factor=0.2),
|
|
355
|
-
superposition=lambda s: f"ws_{s}",
|
|
356
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
357
|
-
hints={
|
|
358
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
359
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
360
|
-
},
|
|
361
|
-
)
|
|
362
|
-
self.wake_models.add_factory(
|
|
363
|
-
fm.wake_models.wind.Bastankhah2014,
|
|
364
|
-
"Bastankhah2014B_<superposition>",
|
|
345
|
+
"Bastankhah2014B_<superposition>_[wake_k]",
|
|
365
346
|
kwargs=dict(sbeta_factor=0.2, induction="Betz"),
|
|
366
347
|
superposition=lambda s: f"ws_{s}",
|
|
367
348
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
368
349
|
)
|
|
369
|
-
self.wake_models.
|
|
370
|
-
fm.wake_models.wind.Bastankhah2014,
|
|
371
|
-
"Bastankhah2014B_<superposition>_k<k>",
|
|
372
|
-
kwargs=dict(sbeta_factor=0.2, induction="Betz"),
|
|
373
|
-
superposition=lambda s: f"ws_{s}",
|
|
374
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
375
|
-
hints={
|
|
376
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
377
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
378
|
-
},
|
|
379
|
-
)
|
|
380
|
-
self.wake_models.add_factory(
|
|
350
|
+
self.wake_models.add_k_factory(
|
|
381
351
|
fm.wake_models.wind.Bastankhah2014,
|
|
382
|
-
"Bastankhah025_<superposition>",
|
|
383
|
-
kwargs=dict(sbeta_factor=0.25),
|
|
352
|
+
"Bastankhah025_<superposition>_[wake_k]",
|
|
353
|
+
kwargs=dict(sbeta_factor=0.25, induction="Madsen"),
|
|
384
354
|
superposition=lambda s: f"ws_{s}",
|
|
385
355
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
386
356
|
)
|
|
387
|
-
self.wake_models.
|
|
357
|
+
self.wake_models.add_k_factory(
|
|
388
358
|
fm.wake_models.wind.Bastankhah2014,
|
|
389
|
-
"
|
|
390
|
-
kwargs=dict(sbeta_factor=0.25),
|
|
391
|
-
superposition=lambda s: f"ws_{s}",
|
|
392
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
393
|
-
hints={
|
|
394
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
395
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
396
|
-
},
|
|
397
|
-
)
|
|
398
|
-
self.wake_models.add_factory(
|
|
399
|
-
fm.wake_models.wind.Bastankhah2014,
|
|
400
|
-
"Bastankhah025B_<superposition>",
|
|
359
|
+
"Bastankhah025B_<superposition>_[wake_k]",
|
|
401
360
|
kwargs=dict(sbeta_factor=0.25, induction="Betz"),
|
|
402
361
|
superposition=lambda s: f"ws_{s}",
|
|
403
362
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
404
363
|
)
|
|
405
|
-
self.wake_models.add_factory(
|
|
406
|
-
fm.wake_models.wind.Bastankhah2014,
|
|
407
|
-
"Bastankhah025B_<superposition>_k<k>",
|
|
408
|
-
kwargs=dict(sbeta_factor=0.25, induction="Betz"),
|
|
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={
|
|
412
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
413
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
414
|
-
},
|
|
415
|
-
)
|
|
416
364
|
|
|
417
|
-
self.wake_models.
|
|
365
|
+
self.wake_models.add_k_factory(
|
|
418
366
|
fm.wake_models.wind.Bastankhah2016,
|
|
419
|
-
"Bastankhah2016_<superposition>",
|
|
367
|
+
"Bastankhah2016_<superposition>_[wake_k]",
|
|
368
|
+
kwargs=dict(induction="Madsen"),
|
|
420
369
|
superposition=lambda s: f"ws_{s}",
|
|
421
370
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
422
371
|
)
|
|
423
|
-
self.wake_models.
|
|
424
|
-
fm.wake_models.wind.Bastankhah2016,
|
|
425
|
-
"Bastankhah2016_<superposition>_k<k>",
|
|
426
|
-
superposition=lambda s: f"ws_{s}",
|
|
427
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
428
|
-
hints={
|
|
429
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
430
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
431
|
-
},
|
|
432
|
-
)
|
|
433
|
-
self.wake_models.add_factory(
|
|
372
|
+
self.wake_models.add_k_factory(
|
|
434
373
|
fm.wake_models.wind.Bastankhah2016,
|
|
435
|
-
"Bastankhah2016B_<superposition>",
|
|
374
|
+
"Bastankhah2016B_<superposition>_[wake_k]",
|
|
436
375
|
kwargs=dict(induction="Betz"),
|
|
437
376
|
superposition=lambda s: f"ws_{s}",
|
|
438
377
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
439
378
|
)
|
|
440
|
-
self.wake_models.add_factory(
|
|
441
|
-
fm.wake_models.wind.Bastankhah2016,
|
|
442
|
-
"Bastankhah2016B_<superposition>_k<k>",
|
|
443
|
-
kwargs=dict(induction="Betz"),
|
|
444
|
-
superposition=lambda s: f"ws_{s}",
|
|
445
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
446
|
-
hints={
|
|
447
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
448
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
449
|
-
},
|
|
450
|
-
)
|
|
451
379
|
|
|
452
|
-
self.wake_models.
|
|
380
|
+
self.wake_models.add_k_factory(
|
|
453
381
|
fm.wake_models.wind.TurbOParkWake,
|
|
454
|
-
"TurbOPark_<superposition>",
|
|
382
|
+
"TurbOPark_<superposition>_[wake_k]",
|
|
383
|
+
kwargs=dict(induction="Madsen"),
|
|
455
384
|
superposition=lambda s: f"ws_{s}",
|
|
456
385
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
457
386
|
)
|
|
458
|
-
self.wake_models.
|
|
387
|
+
self.wake_models.add_k_factory(
|
|
459
388
|
fm.wake_models.wind.TurbOParkWake,
|
|
460
|
-
"
|
|
461
|
-
superposition=lambda s: f"ws_{s}",
|
|
462
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
463
|
-
hints={
|
|
464
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
465
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
466
|
-
},
|
|
467
|
-
)
|
|
468
|
-
self.wake_models.add_factory(
|
|
469
|
-
fm.wake_models.wind.TurbOParkWake,
|
|
470
|
-
"TurbOParkB_<superposition>",
|
|
389
|
+
"TurbOParkB_<superposition>_[wake_k]",
|
|
471
390
|
kwargs=dict(induction="Betz"),
|
|
472
391
|
superposition=lambda s: f"ws_{s}",
|
|
473
392
|
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
474
393
|
)
|
|
475
|
-
self.wake_models.add_factory(
|
|
476
|
-
fm.wake_models.wind.TurbOParkWake,
|
|
477
|
-
"TurbOParkB_<superposition>_k<k>",
|
|
478
|
-
kwargs=dict(induction="Betz"),
|
|
479
|
-
superposition=lambda s: f"ws_{s}",
|
|
480
|
-
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
481
|
-
hints={
|
|
482
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
483
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
484
|
-
},
|
|
485
|
-
)
|
|
486
394
|
|
|
487
|
-
self.wake_models.
|
|
395
|
+
self.wake_models.add_k_factory(
|
|
488
396
|
fm.wake_models.wind.TurbOParkWakeIX,
|
|
489
|
-
"TurbOParkIX_<superposition>_dx<dx>",
|
|
397
|
+
"TurbOParkIX_<superposition>_[wake_k]_dx<dx>",
|
|
490
398
|
superposition=lambda s: f"ws_{s}",
|
|
491
399
|
dx=lambda x: float(x),
|
|
492
400
|
hints={
|
|
@@ -495,37 +403,35 @@ class ModelBook:
|
|
|
495
403
|
},
|
|
496
404
|
)
|
|
497
405
|
|
|
498
|
-
self.wake_models.
|
|
499
|
-
fm.wake_models.
|
|
500
|
-
"
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
hints={
|
|
505
|
-
"superposition": "(Superposition, e.g. linear for ws_linear)",
|
|
506
|
-
"k": "(Value, e.g. 004 for 0.04)",
|
|
507
|
-
"dx": "(Integration step in m)",
|
|
508
|
-
},
|
|
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)"},
|
|
509
412
|
)
|
|
510
413
|
|
|
511
414
|
self.wake_models.add_factory(
|
|
512
|
-
fm.wake_models.ti.
|
|
513
|
-
"
|
|
514
|
-
kwargs=dict(
|
|
415
|
+
fm.wake_models.ti.IECTIWake,
|
|
416
|
+
"IECTI2005_<superposition>",
|
|
417
|
+
kwargs=dict(iec_type="2005"),
|
|
515
418
|
superposition=lambda s: f"ti_{s}",
|
|
516
419
|
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
517
420
|
)
|
|
518
421
|
|
|
519
422
|
self.wake_models.add_factory(
|
|
520
|
-
fm.wake_models.ti.
|
|
521
|
-
"
|
|
522
|
-
kwargs=dict(
|
|
423
|
+
fm.wake_models.ti.IECTIWake,
|
|
424
|
+
"IECTI2019_<superposition>",
|
|
425
|
+
kwargs=dict(iec_type="2019"),
|
|
523
426
|
superposition=lambda s: f"ti_{s}",
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
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)"},
|
|
529
435
|
)
|
|
530
436
|
|
|
531
437
|
self.wake_models.add_factory(
|
|
@@ -535,11 +441,10 @@ class ModelBook:
|
|
|
535
441
|
superposition=lambda s: f"ti_{s}",
|
|
536
442
|
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
537
443
|
)
|
|
538
|
-
|
|
539
|
-
self.wake_models.add_factory(
|
|
444
|
+
self.wake_models.add_k_factory(
|
|
540
445
|
fm.wake_models.ti.IECTIWake,
|
|
541
|
-
"
|
|
542
|
-
kwargs=dict(iec_type="
|
|
446
|
+
"IECTI2005k_<superposition>_[wake_k]",
|
|
447
|
+
kwargs=dict(iec_type="2005", opening_angle=None),
|
|
543
448
|
superposition=lambda s: f"ti_{s}",
|
|
544
449
|
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
545
450
|
)
|
|
@@ -550,6 +455,18 @@ class ModelBook:
|
|
|
550
455
|
self.wake_models[f"SelfSimilar2020"] = (
|
|
551
456
|
fm.wake_models.induction.SelfSimilar2020()
|
|
552
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
|
+
)
|
|
553
470
|
|
|
554
471
|
self.sources = FDict(
|
|
555
472
|
name="sources",
|
|
@@ -564,6 +481,7 @@ class ModelBook:
|
|
|
564
481
|
wake_superpositions=self.wake_superpositions,
|
|
565
482
|
wake_models=self.wake_models,
|
|
566
483
|
axial_induction=self.axial_induction,
|
|
484
|
+
ground_models=self.ground_models,
|
|
567
485
|
)
|
|
568
486
|
self.base_classes = FDict(
|
|
569
487
|
name="base_classes",
|
|
@@ -578,6 +496,7 @@ class ModelBook:
|
|
|
578
496
|
wake_superpositions=WakeSuperposition,
|
|
579
497
|
wake_models=WakeModel,
|
|
580
498
|
axial_induction=AxialInductionModel,
|
|
499
|
+
ground_models=GroundModel,
|
|
581
500
|
)
|
|
582
501
|
|
|
583
502
|
for s in self.sources.values():
|
|
@@ -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):
|