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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
|
+
from foxes.core import WakeK
|
|
3
4
|
from foxes.models.wake_models.top_hat import TopHatWakeModel
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
@@ -21,11 +22,8 @@ class IECTIWake(TopHatWakeModel):
|
|
|
21
22
|
|
|
22
23
|
Attributes
|
|
23
24
|
----------
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
based on the wake opening angle.
|
|
27
|
-
k_var: str
|
|
28
|
-
The variable name for k
|
|
25
|
+
wake_k: foxes.core.WakeK
|
|
26
|
+
Handler for the wake growth parameter k
|
|
29
27
|
|
|
30
28
|
:group: models.wake_models.ti
|
|
31
29
|
|
|
@@ -36,8 +34,8 @@ class IECTIWake(TopHatWakeModel):
|
|
|
36
34
|
superposition,
|
|
37
35
|
opening_angle=21.6,
|
|
38
36
|
iec_type="2019",
|
|
39
|
-
|
|
40
|
-
**
|
|
37
|
+
induction="Betz",
|
|
38
|
+
**wake_k,
|
|
41
39
|
):
|
|
42
40
|
"""
|
|
43
41
|
Constructor.
|
|
@@ -46,37 +44,48 @@ class IECTIWake(TopHatWakeModel):
|
|
|
46
44
|
----------
|
|
47
45
|
superposition: str
|
|
48
46
|
The TI wake superposition.
|
|
49
|
-
opening_angle: float
|
|
47
|
+
opening_angle: float, optional
|
|
50
48
|
The wake opening angle. The wake growth parameter k is calculated
|
|
51
49
|
based on the wake opening angle.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
iec_type: str
|
|
51
|
+
Either '2005' or '2019'/'Frandsen'
|
|
52
|
+
wake_k: dict, optional
|
|
53
|
+
Parameters for the WakeK class
|
|
56
54
|
|
|
57
55
|
"""
|
|
58
|
-
super().__init__(superpositions={FV.TI: superposition},
|
|
56
|
+
super().__init__(superpositions={FV.TI: superposition}, induction=induction)
|
|
59
57
|
|
|
60
|
-
|
|
58
|
+
if opening_angle is not None:
|
|
59
|
+
if "k" in wake_k or "ka" in wake_k or "kb" in wake_k:
|
|
60
|
+
raise KeyError(
|
|
61
|
+
f"Can handle 'opening_angle' or ('k', 'ka', 'kb') parameters, not both"
|
|
62
|
+
)
|
|
63
|
+
wake_k["k"] = float(np.tan(np.deg2rad(opening_angle / 2.0)))
|
|
61
64
|
|
|
62
65
|
self.iec_type = iec_type
|
|
63
|
-
self.
|
|
64
|
-
setattr(self, k_var, k)
|
|
66
|
+
self.wake_k = WakeK(**wake_k)
|
|
65
67
|
|
|
66
68
|
def __repr__(self):
|
|
67
|
-
k = getattr(self, self.k_var)
|
|
68
69
|
iname = (
|
|
69
70
|
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
70
71
|
)
|
|
71
72
|
s = f"{type(self).__name__}"
|
|
72
|
-
s += f"({self.superpositions[FV.TI]}, induction={iname}"
|
|
73
|
-
|
|
74
|
-
s += f", k_var={self.k_var}"
|
|
75
|
-
else:
|
|
76
|
-
s += f", {self.k_var}={k}"
|
|
77
|
-
s += ")"
|
|
73
|
+
s += f"({self.superpositions[FV.TI]}, induction={iname}, "
|
|
74
|
+
s += self.wake_k.repr() + ")"
|
|
78
75
|
return s
|
|
79
76
|
|
|
77
|
+
def sub_models(self):
|
|
78
|
+
"""
|
|
79
|
+
List of all sub-models
|
|
80
|
+
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
smdls: list of foxes.core.Model
|
|
84
|
+
All sub models
|
|
85
|
+
|
|
86
|
+
"""
|
|
87
|
+
return [self.wake_k]
|
|
88
|
+
|
|
80
89
|
def new_wake_deltas(self, algo, mdata, fdata, tdata):
|
|
81
90
|
"""
|
|
82
91
|
Creates new empty wake delta arrays.
|
|
@@ -138,10 +147,8 @@ class IECTIWake(TopHatWakeModel):
|
|
|
138
147
|
The wake radii, shape: (n_states, n_targets)
|
|
139
148
|
|
|
140
149
|
"""
|
|
141
|
-
k = self.
|
|
142
|
-
self.k_var,
|
|
150
|
+
k = self.wake_k(
|
|
143
151
|
FC.STATE_TARGET,
|
|
144
|
-
lookup="sw",
|
|
145
152
|
algo=algo,
|
|
146
153
|
fdata=fdata,
|
|
147
154
|
tdata=tdata,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
|
+
from foxes.core import WakeK
|
|
3
4
|
from foxes.models.wake_models.gaussian import GaussianWakeModel
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
@@ -18,28 +19,18 @@ class Bastankhah2014(GaussianWakeModel):
|
|
|
18
19
|
|
|
19
20
|
Attributes
|
|
20
21
|
----------
|
|
21
|
-
k: float
|
|
22
|
-
The wake growth parameter k. If not given here
|
|
23
|
-
it will be searched in the farm data.
|
|
24
22
|
sbeta_factor: float
|
|
25
23
|
Factor multiplying sbeta
|
|
26
|
-
k_var: str
|
|
27
|
-
The variable name for k
|
|
28
24
|
induction: foxes.core.AxialInductionModel or str
|
|
29
25
|
The induction model
|
|
26
|
+
wake_k: foxes.core.WakeK
|
|
27
|
+
Handler for the wake growth parameter k
|
|
30
28
|
|
|
31
29
|
:group: models.wake_models.wind
|
|
32
30
|
|
|
33
31
|
"""
|
|
34
32
|
|
|
35
|
-
def __init__(
|
|
36
|
-
self,
|
|
37
|
-
superposition,
|
|
38
|
-
k=None,
|
|
39
|
-
sbeta_factor=0.2,
|
|
40
|
-
k_var=FV.K,
|
|
41
|
-
induction="Madsen",
|
|
42
|
-
):
|
|
33
|
+
def __init__(self, superposition, sbeta_factor=0.2, induction="Madsen", **wake_k):
|
|
43
34
|
"""
|
|
44
35
|
Constructor.
|
|
45
36
|
|
|
@@ -47,37 +38,27 @@ class Bastankhah2014(GaussianWakeModel):
|
|
|
47
38
|
----------
|
|
48
39
|
superposition: str
|
|
49
40
|
The wind speed deficit superposition.
|
|
50
|
-
k: float, optional
|
|
51
|
-
The wake growth parameter k. If not given here
|
|
52
|
-
it will be searched in the farm data.
|
|
53
41
|
sbeta_factor: float
|
|
54
42
|
Factor multiplying sbeta
|
|
55
|
-
k_var: str
|
|
56
|
-
The variable name for k
|
|
57
43
|
induction: foxes.core.AxialInductionModel or str
|
|
58
44
|
The induction model
|
|
45
|
+
wake_k: dict, optional
|
|
46
|
+
Parameters for the WakeK class
|
|
59
47
|
|
|
60
48
|
"""
|
|
61
49
|
super().__init__(superpositions={FV.WS: superposition})
|
|
62
50
|
|
|
63
51
|
self.sbeta_factor = sbeta_factor
|
|
64
|
-
self.k_var = k_var
|
|
65
52
|
self.induction = induction
|
|
66
|
-
|
|
67
|
-
setattr(self, k_var, k)
|
|
53
|
+
self.wake_k = WakeK(**wake_k)
|
|
68
54
|
|
|
69
55
|
def __repr__(self):
|
|
70
|
-
k = getattr(self, self.k_var)
|
|
71
56
|
iname = (
|
|
72
57
|
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
73
58
|
)
|
|
74
59
|
s = f"{type(self).__name__}"
|
|
75
|
-
s += f"({self.superpositions[FV.WS]}, induction={iname}"
|
|
76
|
-
|
|
77
|
-
s += f", k_var={self.k_var}"
|
|
78
|
-
else:
|
|
79
|
-
s += f", {self.k_var}={k}"
|
|
80
|
-
s += ")"
|
|
60
|
+
s += f"({self.superpositions[FV.WS]}, induction={iname}, "
|
|
61
|
+
s += self.wake_k.repr() + ")"
|
|
81
62
|
return s
|
|
82
63
|
|
|
83
64
|
def sub_models(self):
|
|
@@ -90,7 +71,7 @@ class Bastankhah2014(GaussianWakeModel):
|
|
|
90
71
|
All sub models
|
|
91
72
|
|
|
92
73
|
"""
|
|
93
|
-
return [self.induction]
|
|
74
|
+
return [self.wake_k, self.induction]
|
|
94
75
|
|
|
95
76
|
def initialize(self, algo, verbosity=0, force=False):
|
|
96
77
|
"""
|
|
@@ -180,10 +161,8 @@ class Bastankhah2014(GaussianWakeModel):
|
|
|
180
161
|
)[st_sel]
|
|
181
162
|
|
|
182
163
|
# get k:
|
|
183
|
-
k = self.
|
|
184
|
-
self.k_var,
|
|
164
|
+
k = self.wake_k(
|
|
185
165
|
FC.STATE_TARGET,
|
|
186
|
-
lookup="sw",
|
|
187
166
|
algo=algo,
|
|
188
167
|
fdata=fdata,
|
|
189
168
|
tdata=tdata,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.models.wake_models.dist_sliced import DistSlicedWakeModel
|
|
4
|
-
from foxes.core
|
|
4
|
+
from foxes.core import Model, WakeK
|
|
5
5
|
import foxes.variables as FV
|
|
6
6
|
import foxes.constants as FC
|
|
7
7
|
|
|
@@ -48,7 +48,7 @@ class Bastankhah2016Model(Model):
|
|
|
48
48
|
SIGMA_Z_FAR = "sigma_z_far"
|
|
49
49
|
DELTA_FAR = "delta_far"
|
|
50
50
|
|
|
51
|
-
def __init__(self, alpha
|
|
51
|
+
def __init__(self, alpha, beta, induction):
|
|
52
52
|
"""
|
|
53
53
|
Constructor.
|
|
54
54
|
|
|
@@ -401,14 +401,17 @@ class Bastankhah2016(DistSlicedWakeModel):
|
|
|
401
401
|
The model for computing common data
|
|
402
402
|
model_pars: dict
|
|
403
403
|
Model parameters
|
|
404
|
-
K: float
|
|
405
|
-
The wake growth parameter k. If not given here
|
|
406
|
-
it will be searched in the farm data.
|
|
407
404
|
YAWM: float
|
|
408
405
|
The yaw misalignment YAWM. If not given here
|
|
409
406
|
it will be searched in the farm data.
|
|
410
|
-
|
|
411
|
-
|
|
407
|
+
alpha: float
|
|
408
|
+
model parameter used to determine onset of far wake region
|
|
409
|
+
beta: float
|
|
410
|
+
model parameter used to determine onset of far wake region
|
|
411
|
+
induction: foxes.core.AxialInductionModel or str
|
|
412
|
+
The induction model
|
|
413
|
+
wake_k: dict, optional
|
|
414
|
+
Parameters for the WakeK class
|
|
412
415
|
|
|
413
416
|
:group: models.wake_models.wind
|
|
414
417
|
|
|
@@ -417,9 +420,10 @@ class Bastankhah2016(DistSlicedWakeModel):
|
|
|
417
420
|
def __init__(
|
|
418
421
|
self,
|
|
419
422
|
superposition,
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
+
alpha=0.58,
|
|
424
|
+
beta=0.07,
|
|
425
|
+
induction="Madsen",
|
|
426
|
+
**wake_k,
|
|
423
427
|
):
|
|
424
428
|
"""
|
|
425
429
|
Constructor.
|
|
@@ -428,9 +432,6 @@ class Bastankhah2016(DistSlicedWakeModel):
|
|
|
428
432
|
----------
|
|
429
433
|
superposition: str
|
|
430
434
|
The wind deficit superposition
|
|
431
|
-
k: float
|
|
432
|
-
The wake growth parameter k. If not given here
|
|
433
|
-
it will be searched in the farm data, by default None
|
|
434
435
|
ct_max: float
|
|
435
436
|
The maximal value for ct, values beyond will be limited
|
|
436
437
|
to this number, by default 0.9999
|
|
@@ -438,32 +439,27 @@ class Bastankhah2016(DistSlicedWakeModel):
|
|
|
438
439
|
model parameter used to determine onset of far wake region
|
|
439
440
|
beta: float
|
|
440
441
|
model parameter used to determine onset of far wake region
|
|
441
|
-
|
|
442
|
-
The
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
if not found in wake model
|
|
442
|
+
induction: foxes.core.AxialInductionModel or str
|
|
443
|
+
The induction model
|
|
444
|
+
wake_k: dict, optional
|
|
445
|
+
Parameters for the WakeK class
|
|
446
446
|
|
|
447
447
|
"""
|
|
448
448
|
super().__init__(superpositions={FV.WS: superposition})
|
|
449
449
|
|
|
450
450
|
self.model = None
|
|
451
|
-
self.
|
|
452
|
-
self.
|
|
451
|
+
self.alpha = alpha
|
|
452
|
+
self.beta = beta
|
|
453
|
+
self.induction = induction
|
|
454
|
+
self.wake_k = WakeK(**wake_k)
|
|
453
455
|
|
|
454
|
-
setattr(self, k_var, k)
|
|
455
456
|
setattr(self, FV.YAWM, 0.0)
|
|
456
457
|
|
|
457
458
|
def __repr__(self):
|
|
458
|
-
|
|
459
|
-
iname = self.model_pars.get("induction", "Madsen")
|
|
459
|
+
iname = self.induction
|
|
460
460
|
s = f"{type(self).__name__}"
|
|
461
|
-
s += f"({self.superpositions[FV.WS]}, induction={iname}"
|
|
462
|
-
|
|
463
|
-
s += f", k_var={self.k_var}"
|
|
464
|
-
else:
|
|
465
|
-
s += f", {self.k_var}={k}"
|
|
466
|
-
s += ")"
|
|
461
|
+
s += f"({self.superpositions[FV.WS]}, induction={iname}, "
|
|
462
|
+
s += self.wake_k.repr() + ")"
|
|
467
463
|
return s
|
|
468
464
|
|
|
469
465
|
def sub_models(self):
|
|
@@ -476,7 +472,7 @@ class Bastankhah2016(DistSlicedWakeModel):
|
|
|
476
472
|
Names of all sub models
|
|
477
473
|
|
|
478
474
|
"""
|
|
479
|
-
return [self.model]
|
|
475
|
+
return [self.wake_k, self.model]
|
|
480
476
|
|
|
481
477
|
def initialize(self, algo, verbosity=0, force=False):
|
|
482
478
|
"""
|
|
@@ -493,7 +489,9 @@ class Bastankhah2016(DistSlicedWakeModel):
|
|
|
493
489
|
|
|
494
490
|
"""
|
|
495
491
|
if not self.initialized:
|
|
496
|
-
self.model = Bastankhah2016Model(
|
|
492
|
+
self.model = Bastankhah2016Model(
|
|
493
|
+
alpha=self.alpha, beta=self.beta, induction=self.induction
|
|
494
|
+
)
|
|
497
495
|
super().initialize(algo, verbosity, force)
|
|
498
496
|
|
|
499
497
|
def calc_wakes_x_yz(
|
|
@@ -556,10 +554,8 @@ class Bastankhah2016(DistSlicedWakeModel):
|
|
|
556
554
|
gamma *= np.pi / 180
|
|
557
555
|
|
|
558
556
|
# get k:
|
|
559
|
-
k = self.
|
|
560
|
-
self.k_var,
|
|
557
|
+
k = self.wake_k(
|
|
561
558
|
FC.STATE_TARGET,
|
|
562
|
-
lookup="sw",
|
|
563
559
|
algo=algo,
|
|
564
560
|
fdata=fdata,
|
|
565
561
|
tdata=tdata,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
from foxes.core import WakeK
|
|
3
2
|
from foxes.models.wake_models.top_hat import TopHatWakeModel
|
|
4
3
|
import foxes.variables as FV
|
|
5
4
|
import foxes.constants as FC
|
|
@@ -11,17 +10,14 @@ class JensenWake(TopHatWakeModel):
|
|
|
11
10
|
|
|
12
11
|
Attributes
|
|
13
12
|
----------
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
it will be searched in the farm data.
|
|
17
|
-
k_var: str
|
|
18
|
-
The variable name for k
|
|
13
|
+
wake_k: foxes.core.WakeK
|
|
14
|
+
Handler for the wake growth parameter k
|
|
19
15
|
|
|
20
16
|
:group: models.wake_models.wind
|
|
21
17
|
|
|
22
18
|
"""
|
|
23
19
|
|
|
24
|
-
def __init__(self, superposition,
|
|
20
|
+
def __init__(self, superposition, induction="Betz", **wake_k):
|
|
25
21
|
"""
|
|
26
22
|
Constructor.
|
|
27
23
|
|
|
@@ -29,32 +25,22 @@ class JensenWake(TopHatWakeModel):
|
|
|
29
25
|
----------
|
|
30
26
|
superposition: str
|
|
31
27
|
The wind deficit superposition
|
|
32
|
-
|
|
33
|
-
The
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
The variable name for k
|
|
37
|
-
kwargs: dict, optional
|
|
38
|
-
Additional parameters for the base class
|
|
28
|
+
induction: foxes.core.AxialInductionModel or str
|
|
29
|
+
The induction model
|
|
30
|
+
wake_k: dict, optional
|
|
31
|
+
Parameters for the WakeK class
|
|
39
32
|
|
|
40
33
|
"""
|
|
41
|
-
super().__init__(superpositions={FV.WS: superposition},
|
|
42
|
-
|
|
43
|
-
self.k_var = k_var
|
|
44
|
-
setattr(self, k_var, k)
|
|
34
|
+
super().__init__(superpositions={FV.WS: superposition}, induction=induction)
|
|
35
|
+
self.wake_k = WakeK(**wake_k)
|
|
45
36
|
|
|
46
37
|
def __repr__(self):
|
|
47
|
-
k = getattr(self, self.k_var)
|
|
48
38
|
iname = (
|
|
49
39
|
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
50
40
|
)
|
|
51
41
|
s = f"{type(self).__name__}"
|
|
52
|
-
s += f"({self.superpositions[FV.WS]}, induction={iname}"
|
|
53
|
-
|
|
54
|
-
s += f", k_var={self.k_var}"
|
|
55
|
-
else:
|
|
56
|
-
s += f", {self.k_var}={k}"
|
|
57
|
-
s += ")"
|
|
42
|
+
s += f"({self.superpositions[FV.WS]}, induction={iname}, "
|
|
43
|
+
s += self.wake_k.repr() + ")"
|
|
58
44
|
return s
|
|
59
45
|
|
|
60
46
|
def calc_wake_radius(
|
|
@@ -105,10 +91,8 @@ class JensenWake(TopHatWakeModel):
|
|
|
105
91
|
upcast=False,
|
|
106
92
|
)
|
|
107
93
|
|
|
108
|
-
k = self.
|
|
109
|
-
self.k_var,
|
|
94
|
+
k = self.wake_k(
|
|
110
95
|
FC.STATE_TARGET,
|
|
111
|
-
lookup="sw",
|
|
112
96
|
algo=algo,
|
|
113
97
|
fdata=fdata,
|
|
114
98
|
tdata=tdata,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
|
+
from foxes.core import WakeK
|
|
3
4
|
from foxes.models.wake_models.gaussian import GaussianWakeModel
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
@@ -18,8 +19,6 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
18
19
|
|
|
19
20
|
Attributes
|
|
20
21
|
----------
|
|
21
|
-
k: float
|
|
22
|
-
The wake growth parameter k.
|
|
23
22
|
sbeta_factor: float
|
|
24
23
|
Factor multiplying sbeta
|
|
25
24
|
c1: float
|
|
@@ -28,6 +27,8 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
28
27
|
Factor from Frandsen turbulence model
|
|
29
28
|
induction: foxes.core.AxialInductionModel or str
|
|
30
29
|
The induction model
|
|
30
|
+
wake_k: foxes.core.WakeK
|
|
31
|
+
Handler for the wake growth parameter k
|
|
31
32
|
|
|
32
33
|
:group: models.wake_models.wind
|
|
33
34
|
|
|
@@ -36,12 +37,11 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
36
37
|
def __init__(
|
|
37
38
|
self,
|
|
38
39
|
superposition,
|
|
39
|
-
k=None,
|
|
40
40
|
sbeta_factor=0.25,
|
|
41
41
|
c1=1.5,
|
|
42
42
|
c2=0.8,
|
|
43
|
-
k_var=FV.K,
|
|
44
43
|
induction="Madsen",
|
|
44
|
+
**wake_k,
|
|
45
45
|
):
|
|
46
46
|
"""
|
|
47
47
|
Constructor.
|
|
@@ -50,19 +50,16 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
50
50
|
----------
|
|
51
51
|
superposition: str
|
|
52
52
|
The wind deficit superposition
|
|
53
|
-
k: float, optional
|
|
54
|
-
The wake growth parameter k. If not given here
|
|
55
|
-
it will be searched in the farm data.
|
|
56
53
|
sbeta_factor: float
|
|
57
54
|
Factor multiplying sbeta
|
|
58
55
|
c1: float
|
|
59
56
|
Factor from Frandsen turbulence model
|
|
60
57
|
c2: float
|
|
61
58
|
Factor from Frandsen turbulence model
|
|
62
|
-
k_var: str
|
|
63
|
-
The variable name for k
|
|
64
59
|
induction: foxes.core.AxialInductionModel or str
|
|
65
60
|
The induction model
|
|
61
|
+
wake_k: dict, optional
|
|
62
|
+
Parameters for the WakeK class
|
|
66
63
|
|
|
67
64
|
"""
|
|
68
65
|
super().__init__(superpositions={FV.WS: superposition})
|
|
@@ -70,23 +67,16 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
70
67
|
self.sbeta_factor = sbeta_factor
|
|
71
68
|
self.c1 = c1
|
|
72
69
|
self.c2 = c2
|
|
73
|
-
self.k_var = k_var
|
|
74
70
|
self.induction = induction
|
|
75
|
-
|
|
76
|
-
setattr(self, k_var, k)
|
|
71
|
+
self.wake_k = WakeK(**wake_k)
|
|
77
72
|
|
|
78
73
|
def __repr__(self):
|
|
79
|
-
k = getattr(self, self.k_var)
|
|
80
74
|
iname = (
|
|
81
75
|
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
82
76
|
)
|
|
83
77
|
s = f"{type(self).__name__}"
|
|
84
|
-
s += f"({self.superpositions[FV.WS]}, induction={iname}"
|
|
85
|
-
|
|
86
|
-
s += f", k_var={self.k_var}"
|
|
87
|
-
else:
|
|
88
|
-
s += f", {self.k_var}={k}"
|
|
89
|
-
s += ")"
|
|
78
|
+
s += f"({self.superpositions[FV.WS]}, induction={iname}, "
|
|
79
|
+
s += self.wake_k.repr() + ")"
|
|
90
80
|
return s
|
|
91
81
|
|
|
92
82
|
def sub_models(self):
|
|
@@ -99,7 +89,7 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
99
89
|
All sub models
|
|
100
90
|
|
|
101
91
|
"""
|
|
102
|
-
return [self.induction]
|
|
92
|
+
return [self.wake_k, self.induction]
|
|
103
93
|
|
|
104
94
|
def initialize(self, algo, verbosity=0, force=False):
|
|
105
95
|
"""
|
|
@@ -198,20 +188,21 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
198
188
|
tdata=tdata,
|
|
199
189
|
downwind_index=downwind_index,
|
|
200
190
|
upcast=True,
|
|
201
|
-
)
|
|
191
|
+
)
|
|
202
192
|
|
|
203
193
|
# get k:
|
|
204
|
-
k = self.
|
|
205
|
-
self.k_var,
|
|
194
|
+
k = self.wake_k(
|
|
206
195
|
FC.STATE_TARGET,
|
|
207
|
-
lookup="sw",
|
|
208
196
|
algo=algo,
|
|
209
197
|
fdata=fdata,
|
|
210
198
|
tdata=tdata,
|
|
211
199
|
downwind_index=downwind_index,
|
|
212
200
|
upcast=True,
|
|
201
|
+
amb_ti=ati,
|
|
213
202
|
)[st_sel]
|
|
214
203
|
|
|
204
|
+
ati = ati[st_sel]
|
|
205
|
+
|
|
215
206
|
# calculate sigma:
|
|
216
207
|
# beta = np.sqrt(0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct))
|
|
217
208
|
a = self.induction.ct2a(ct)
|
|
@@ -270,20 +261,16 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
270
261
|
----------
|
|
271
262
|
dx: float
|
|
272
263
|
The step size of the integral
|
|
273
|
-
k: float
|
|
274
|
-
The wake growth parameter k.
|
|
275
264
|
sbeta_factor: float
|
|
276
265
|
Factor multiplying sbeta
|
|
277
|
-
k_var: str
|
|
278
|
-
The variable name for k
|
|
279
|
-
ti_var: str
|
|
280
|
-
The TI variable
|
|
281
266
|
self_wake: bool
|
|
282
267
|
Flag for considering only own wake in ti integral
|
|
283
268
|
induction: foxes.core.AxialInductionModel or str
|
|
284
269
|
The induction model
|
|
285
270
|
ipars: dict
|
|
286
271
|
Additional parameters for centreline integration
|
|
272
|
+
wake_k: foxes.core.WakeK
|
|
273
|
+
Handler for the wake growth parameter k
|
|
287
274
|
|
|
288
275
|
:group: models.wake_models.wind
|
|
289
276
|
|
|
@@ -293,13 +280,11 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
293
280
|
self,
|
|
294
281
|
superposition,
|
|
295
282
|
dx,
|
|
296
|
-
k=None,
|
|
297
283
|
sbeta_factor=0.25,
|
|
298
|
-
k_var=FV.K,
|
|
299
|
-
ti_var=FV.TI,
|
|
300
284
|
self_wake=True,
|
|
301
285
|
induction="Madsen",
|
|
302
|
-
|
|
286
|
+
ipars={},
|
|
287
|
+
**wake_k,
|
|
303
288
|
):
|
|
304
289
|
"""
|
|
305
290
|
Constructor.
|
|
@@ -310,48 +295,35 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
310
295
|
The wind deficit superposition
|
|
311
296
|
dx: float
|
|
312
297
|
The step size of the integral
|
|
313
|
-
k: float, optional
|
|
314
|
-
The wake growth parameter k. If not given here
|
|
315
|
-
it will be searched in the farm data.
|
|
316
298
|
sbeta_factor: float
|
|
317
299
|
Factor multiplying sbeta
|
|
318
|
-
k_var: str
|
|
319
|
-
The variable name for k
|
|
320
|
-
ti_var: str
|
|
321
|
-
The TI variable
|
|
322
300
|
self_wake: bool
|
|
323
301
|
Flag for considering only own wake in ti integral
|
|
324
302
|
induction: foxes.core.AxialInductionModel or str
|
|
325
303
|
The induction model
|
|
326
|
-
ipars: dict
|
|
304
|
+
ipars: dict
|
|
327
305
|
Additional parameters for centreline integration
|
|
306
|
+
wake_k: dict, optional
|
|
307
|
+
Parameters for the WakeK class
|
|
328
308
|
|
|
329
309
|
"""
|
|
330
310
|
super().__init__(superpositions={FV.WS: superposition})
|
|
331
311
|
|
|
332
312
|
self.dx = dx
|
|
333
313
|
self.sbeta_factor = sbeta_factor
|
|
334
|
-
self.k_var = k_var
|
|
335
|
-
self.ti_var = ti_var
|
|
336
314
|
self.ipars = ipars
|
|
337
315
|
self._tiwakes = None
|
|
338
316
|
self.self_wake = self_wake
|
|
339
317
|
self.induction = induction
|
|
340
|
-
|
|
341
|
-
setattr(self, k_var, k)
|
|
318
|
+
self.wake_k = WakeK(**wake_k)
|
|
342
319
|
|
|
343
320
|
def __repr__(self):
|
|
344
|
-
k = getattr(self, self.k_var)
|
|
345
321
|
iname = (
|
|
346
322
|
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
347
323
|
)
|
|
348
324
|
s = f"{type(self).__name__}"
|
|
349
|
-
s += f"({self.superpositions[FV.WS]}, induction={iname}, dx={self.dx}"
|
|
350
|
-
|
|
351
|
-
s += f", k_var={self.k_var}"
|
|
352
|
-
else:
|
|
353
|
-
s += f", {self.k_var}={k}"
|
|
354
|
-
s += f", ti_var={self.ti_var})"
|
|
325
|
+
s += f"({self.superpositions[FV.WS]}, induction={iname}, dx={self.dx}, "
|
|
326
|
+
s += self.wake_k.repr() + ")"
|
|
355
327
|
return s
|
|
356
328
|
|
|
357
329
|
def sub_models(self):
|
|
@@ -364,7 +336,7 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
364
336
|
All sub models
|
|
365
337
|
|
|
366
338
|
"""
|
|
367
|
-
return [self.induction]
|
|
339
|
+
return [self.wake_k, self.induction]
|
|
368
340
|
|
|
369
341
|
def initialize(self, algo, verbosity=0, force=False):
|
|
370
342
|
"""
|
|
@@ -411,11 +383,11 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
411
383
|
for w in algo.wake_models.values():
|
|
412
384
|
if w is not self:
|
|
413
385
|
wdel = w.new_wake_deltas(algo, mdata, fdata, tdata)
|
|
414
|
-
if self.ti_var in wdel:
|
|
386
|
+
if self.wake_k.ti_var in wdel:
|
|
415
387
|
self._tiwakes.append(w)
|
|
416
|
-
if self.ti_var not in FV.amb2var and len(self._tiwakes) == 0:
|
|
388
|
+
if self.wake_k.ti_var not in FV.amb2var and len(self._tiwakes) == 0:
|
|
417
389
|
raise KeyError(
|
|
418
|
-
f"Model '{self.name}': Missing wake model that computes wake delta for variable {self.ti_var}"
|
|
390
|
+
f"Model '{self.name}': Missing wake model that computes wake delta for variable {self.wake_k.ti_var}"
|
|
419
391
|
)
|
|
420
392
|
|
|
421
393
|
return super().new_wake_deltas(algo, mdata, fdata, tdata)
|
|
@@ -490,10 +462,8 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
490
462
|
)[st_sel]
|
|
491
463
|
|
|
492
464
|
# get k:
|
|
493
|
-
k = self.
|
|
494
|
-
self.k_var,
|
|
465
|
+
k = self.wake_k(
|
|
495
466
|
FC.STATE_TARGET,
|
|
496
|
-
lookup="sw",
|
|
497
467
|
algo=algo,
|
|
498
468
|
fdata=fdata,
|
|
499
469
|
tdata=tdata,
|
|
@@ -514,7 +484,7 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
514
484
|
mdata,
|
|
515
485
|
fdata,
|
|
516
486
|
downwind_index,
|
|
517
|
-
[self.ti_var],
|
|
487
|
+
[self.wake_k.ti_var],
|
|
518
488
|
x,
|
|
519
489
|
dx=self.dx,
|
|
520
490
|
wake_models=self._tiwakes,
|