foxes 0.7.2__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.

Files changed (60) hide show
  1. foxes/VERSION +1 -1
  2. foxes/algorithms/downwind/downwind.py +57 -45
  3. foxes/algorithms/downwind/models/farm_wakes_calc.py +17 -6
  4. foxes/algorithms/downwind/models/point_wakes_calc.py +13 -45
  5. foxes/algorithms/iterative/iterative.py +1 -1
  6. foxes/algorithms/iterative/models/farm_wakes_calc.py +18 -4
  7. foxes/constants.py +5 -0
  8. foxes/core/__init__.py +2 -1
  9. foxes/core/ground_model.py +254 -0
  10. foxes/core/model.py +3 -2
  11. foxes/core/partial_wakes_model.py +19 -3
  12. foxes/core/states.py +33 -0
  13. foxes/core/wake_model.py +138 -2
  14. foxes/data/__init__.py +1 -1
  15. foxes/data/states/WRF-Timeseries-3000.nc +0 -0
  16. foxes/data/states/windio_timeseries_5000.nc +0 -0
  17. foxes/data/static_data.py +7 -0
  18. foxes/data/windio/DTU_10MW_turbine.yaml +10 -0
  19. foxes/data/windio/__init__.py +0 -0
  20. foxes/data/windio/windio_5turbines_timeseries.yaml +63 -0
  21. foxes/input/states/__init__.py +1 -0
  22. foxes/input/states/multi_height.py +225 -6
  23. foxes/input/windio/__init__.py +6 -1
  24. foxes/input/windio/get_states.py +115 -0
  25. foxes/input/windio/read_attributes.py +321 -0
  26. foxes/input/windio/read_farm.py +163 -0
  27. foxes/input/windio/read_fields.py +164 -0
  28. foxes/input/windio/runner.py +105 -0
  29. foxes/input/windio/windio.py +136 -254
  30. foxes/models/__init__.py +1 -0
  31. foxes/models/ground_models/__init__.py +2 -0
  32. foxes/models/ground_models/no_ground.py +12 -0
  33. foxes/models/ground_models/wake_mirror.py +161 -0
  34. foxes/models/model_book.py +68 -149
  35. foxes/models/partial_wakes/axiwake.py +27 -4
  36. foxes/models/partial_wakes/top_hat.py +26 -4
  37. foxes/models/turbine_types/PCt_file.py +1 -0
  38. foxes/models/turbine_types/PCt_from_two.py +92 -0
  39. foxes/models/wake_frames/yawed_wakes.py +41 -38
  40. foxes/models/wake_models/__init__.py +0 -1
  41. foxes/models/wake_models/induction/__init__.py +1 -0
  42. foxes/models/wake_models/induction/rankine_half_body.py +1 -1
  43. foxes/models/wake_models/induction/vortex_sheet.py +227 -0
  44. foxes/models/wake_models/ti/crespo_hernandez.py +26 -24
  45. foxes/models/wake_models/ti/iec_ti.py +33 -26
  46. foxes/models/wake_models/wind/bastankhah14.py +11 -32
  47. foxes/models/wake_models/wind/bastankhah16.py +30 -34
  48. foxes/models/wake_models/wind/jensen.py +13 -29
  49. foxes/models/wake_models/wind/turbopark.py +31 -61
  50. foxes/output/grids.py +6 -6
  51. foxes/output/output.py +6 -6
  52. foxes/utils/__init__.py +1 -1
  53. foxes/utils/factory.py +203 -11
  54. {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/METADATA +8 -6
  55. {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/RECORD +59 -45
  56. {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/WHEEL +1 -1
  57. foxes/models/wake_models/wake_mirror.py +0 -196
  58. {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/LICENSE +0 -0
  59. {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/top_level.txt +0 -0
  60. {foxes-0.7.2.dist-info → foxes-0.7.3.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
- opening_angle: float
25
- The wake opening angle. The wake growth parameter k is calculated
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
- k_var=FV.K,
40
- **kwargs,
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
- k_var: str
53
- The variable name for k
54
- kwargs: dict, optional
55
- Additional parameters for the base class
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}, **kwargs)
56
+ super().__init__(superpositions={FV.TI: superposition}, induction=induction)
59
57
 
60
- k = float(np.tan(np.deg2rad(opening_angle / 2.0)))
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.k_var = k_var
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
- if k is None:
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.get_data(
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
- if k is None:
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.get_data(
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.model import Model
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=0.58, beta=0.07, induction="Madsen"):
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
- k_var: str
411
- The variable name for k
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
- k=None,
421
- k_var=FV.K,
422
- **kwargs,
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
- k_var: str
442
- The variable name for k
443
- kwargs: dict, optional
444
- Additional parameters for the Bastankhah2016Model,
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.model_pars = kwargs
452
- self.k_var = k_var
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
- k = getattr(self, self.k_var)
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
- if k is None:
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(**self.model_pars)
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.get_data(
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
- import numpy as np
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
- k: float, optional
15
- The wake growth parameter k. If not given here
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, k=None, k_var=FV.K, **kwargs):
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
- k: float, optional
33
- The wake growth parameter k. If not given here
34
- it will be searched in the farm data.
35
- k_var: str
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}, **kwargs)
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
- if k is None:
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.get_data(
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
- if k is None:
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
- )[st_sel]
191
+ )
202
192
 
203
193
  # get k:
204
- k = self.get_data(
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
- **ipars,
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, optional
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
- if k is None:
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.get_data(
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,