foxes 1.0__py3-none-any.whl → 1.1.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.

Files changed (128) hide show
  1. docs/source/conf.py +0 -1
  2. examples/states_lookup_table/run.py +1 -1
  3. examples/timeseries/run.py +11 -4
  4. foxes/algorithms/downwind/downwind.py +18 -13
  5. foxes/algorithms/downwind/models/farm_wakes_calc.py +1 -1
  6. foxes/algorithms/downwind/models/init_farm_data.py +1 -1
  7. foxes/algorithms/downwind/models/point_wakes_calc.py +1 -1
  8. foxes/algorithms/downwind/models/reorder_farm_output.py +1 -1
  9. foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
  10. foxes/algorithms/downwind/models/set_amb_point_results.py +1 -1
  11. foxes/algorithms/iterative/iterative.py +1 -1
  12. foxes/algorithms/iterative/models/farm_wakes_calc.py +1 -1
  13. foxes/algorithms/iterative/models/urelax.py +3 -3
  14. foxes/algorithms/sequential/models/plugin.py +4 -4
  15. foxes/algorithms/sequential/models/seq_state.py +1 -1
  16. foxes/constants.py +5 -5
  17. foxes/core/algorithm.py +2 -2
  18. foxes/core/data_calc_model.py +2 -2
  19. foxes/core/engine.py +20 -10
  20. foxes/core/farm_controller.py +3 -3
  21. foxes/core/farm_data_model.py +1 -1
  22. foxes/core/ground_model.py +2 -2
  23. foxes/core/model.py +122 -108
  24. foxes/core/partial_wakes_model.py +1 -1
  25. foxes/core/point_data_model.py +2 -2
  26. foxes/core/states.py +1 -1
  27. foxes/core/turbine_type.py +2 -2
  28. foxes/core/wake_frame.py +8 -30
  29. foxes/core/wake_model.py +3 -2
  30. foxes/core/wake_superposition.py +1 -1
  31. foxes/data/windio/windio_5turbines_timeseries.yaml +9 -15
  32. foxes/engines/__init__.py +1 -0
  33. foxes/engines/dask.py +13 -6
  34. foxes/engines/multiprocess.py +5 -8
  35. foxes/engines/numpy.py +8 -26
  36. foxes/engines/pool.py +10 -24
  37. foxes/engines/ray.py +79 -0
  38. foxes/engines/single.py +3 -1
  39. foxes/input/farm_layout/from_json.py +1 -1
  40. foxes/input/states/__init__.py +1 -0
  41. foxes/input/states/field_data_nc.py +4 -4
  42. foxes/input/states/multi_height.py +4 -4
  43. foxes/input/states/scan_ws.py +1 -1
  44. foxes/input/states/single.py +1 -1
  45. foxes/input/states/slice_data_nc.py +681 -0
  46. foxes/input/states/states_table.py +3 -3
  47. foxes/input/windio/__init__.py +1 -1
  48. foxes/input/windio/read_attributes.py +8 -2
  49. foxes/input/windio/read_fields.py +3 -0
  50. foxes/input/windio/read_outputs.py +8 -2
  51. foxes/input/windio/windio.py +6 -2
  52. foxes/models/farm_models/turbine2farm.py +1 -1
  53. foxes/models/ground_models/wake_mirror.py +2 -2
  54. foxes/models/model_book.py +29 -2
  55. foxes/models/partial_wakes/axiwake.py +3 -3
  56. foxes/models/partial_wakes/top_hat.py +2 -2
  57. foxes/models/point_models/set_uniform_data.py +1 -1
  58. foxes/models/point_models/tke2ti.py +1 -1
  59. foxes/models/point_models/wake_deltas.py +1 -1
  60. foxes/models/rotor_models/grid.py +2 -2
  61. foxes/models/turbine_models/calculator.py +4 -4
  62. foxes/models/turbine_models/kTI_model.py +22 -6
  63. foxes/models/turbine_models/lookup_table.py +3 -2
  64. foxes/models/turbine_types/PCt_file.py +5 -5
  65. foxes/models/turbine_types/PCt_from_two.py +5 -5
  66. foxes/models/turbine_types/TBL_file.py +80 -0
  67. foxes/models/turbine_types/__init__.py +1 -0
  68. foxes/models/turbine_types/lookup.py +5 -5
  69. foxes/models/turbine_types/null_type.py +3 -3
  70. foxes/models/turbine_types/wsrho2PCt_from_two.py +7 -7
  71. foxes/models/turbine_types/wsti2PCt_from_two.py +9 -9
  72. foxes/models/vertical_profiles/__init__.py +1 -1
  73. foxes/models/wake_frames/dynamic_wakes.py +2 -2
  74. foxes/models/wake_frames/farm_order.py +2 -2
  75. foxes/models/wake_frames/rotor_wd.py +2 -2
  76. foxes/models/wake_frames/seq_dynamic_wakes.py +5 -11
  77. foxes/models/wake_frames/streamlines.py +2 -2
  78. foxes/models/wake_frames/timelines.py +2 -2
  79. foxes/models/wake_frames/yawed_wakes.py +3 -3
  80. foxes/models/wake_models/dist_sliced.py +1 -1
  81. foxes/models/wake_models/induction/rankine_half_body.py +1 -1
  82. foxes/models/wake_models/induction/rathmann.py +76 -22
  83. foxes/models/wake_models/induction/self_similar.py +76 -26
  84. foxes/models/wake_models/induction/vortex_sheet.py +84 -46
  85. foxes/models/wake_models/ti/crespo_hernandez.py +6 -4
  86. foxes/models/wake_models/ti/iec_ti.py +7 -5
  87. foxes/models/wake_models/wind/bastankhah14.py +6 -4
  88. foxes/models/wake_models/wind/bastankhah16.py +9 -9
  89. foxes/models/wake_models/wind/jensen.py +3 -2
  90. foxes/models/wake_models/wind/turbopark.py +14 -11
  91. foxes/models/wake_superpositions/ti_linear.py +1 -1
  92. foxes/models/wake_superpositions/ti_max.py +1 -1
  93. foxes/models/wake_superpositions/ti_pow.py +1 -1
  94. foxes/models/wake_superpositions/ti_quadratic.py +1 -1
  95. foxes/models/wake_superpositions/ws_linear.py +8 -7
  96. foxes/models/wake_superpositions/ws_max.py +8 -7
  97. foxes/models/wake_superpositions/ws_pow.py +8 -7
  98. foxes/models/wake_superpositions/ws_product.py +5 -5
  99. foxes/models/wake_superpositions/ws_quadratic.py +8 -7
  100. foxes/output/farm_layout.py +14 -10
  101. foxes/output/farm_results_eval.py +1 -1
  102. foxes/output/grids.py +1 -1
  103. foxes/output/results_writer.py +2 -2
  104. foxes/output/rose_plot.py +3 -3
  105. foxes/output/seq_plugins/seq_flow_ani_plugin.py +2 -2
  106. foxes/output/seq_plugins/seq_wake_debug_plugin.py +2 -2
  107. foxes/output/state_turbine_map.py +1 -1
  108. foxes/utils/abl/neutral.py +2 -2
  109. foxes/utils/abl/stable.py +2 -2
  110. foxes/utils/abl/unstable.py +2 -2
  111. foxes/utils/data_book.py +1 -1
  112. foxes/utils/dict.py +23 -0
  113. foxes/utils/exec_python.py +1 -1
  114. foxes/utils/factory.py +29 -1
  115. foxes/utils/geom2d/circle.py +1 -1
  116. foxes/utils/geom2d/polygon.py +1 -1
  117. foxes/utils/geopandas_utils.py +2 -2
  118. foxes/utils/load.py +2 -2
  119. foxes/utils/pandas_helpers.py +1 -1
  120. foxes/utils/xarray_utils.py +1 -1
  121. foxes/variables.py +3 -3
  122. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/METADATA +8 -6
  123. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/RECORD +127 -125
  124. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/WHEEL +1 -1
  125. foxes/utils/geopandas_helpers.py +0 -294
  126. /examples/{induction_RHB → induction}/run.py +0 -0
  127. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/LICENSE +0 -0
  128. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/top_level.txt +0 -0
@@ -10,7 +10,10 @@ class VortexSheet(TurbineInductionModel):
10
10
  """
11
11
  The Vortex Sheet model implemented with a radial dependency
12
12
 
13
- Ref: Medici, D., et al. "The upstream flow of a wind turbine: blockage effect." Wind Energy 14.5 (2011): 691-697.
13
+ Notes
14
+ -----
15
+ Reference:
16
+ Medici, D., et al. "The upstream flow of a wind turbine: blockage effect." Wind Energy 14.5 (2011): 691-697.
14
17
  https://doi.org/10.1002/we.451
15
18
 
16
19
  Attributes
@@ -24,29 +27,35 @@ class VortexSheet(TurbineInductionModel):
24
27
 
25
28
  """
26
29
 
27
- def __init__(self, pre_rotor_only=False, induction="Madsen"):
30
+ def __init__(
31
+ self,
32
+ superposition="ws_linear",
33
+ induction="Madsen",
34
+ pre_rotor_only=False,
35
+ ):
28
36
  """
29
37
  Constructor.
30
38
 
31
39
  Parameters
32
40
  ----------
33
- pre_rotor_only: bool
34
- Calculate only the pre-rotor region
41
+ superposition: str
42
+ The wind speed superposition
35
43
  induction: foxes.core.AxialInductionModel or str
36
44
  The induction model
37
-
38
- :group: models.wake_models.induction
45
+ pre_rotor_only: bool
46
+ Calculate only the pre-rotor region
39
47
 
40
48
  """
41
49
  super().__init__()
42
50
  self.induction = induction
43
51
  self.pre_rotor_only = pre_rotor_only
52
+ self._superp_name = superposition
44
53
 
45
54
  def __repr__(self):
46
55
  iname = (
47
56
  self.induction if isinstance(self.induction, str) else self.induction.name
48
57
  )
49
- return f"{type(self).__name__}, induction={iname})"
58
+ return f"{type(self).__name__}({self._superp_name}, induction={iname})"
50
59
 
51
60
  def sub_models(self):
52
61
  """
@@ -58,7 +67,7 @@ class VortexSheet(TurbineInductionModel):
58
67
  All sub models
59
68
 
60
69
  """
61
- return [self.induction]
70
+ return [self._superp, self.induction]
62
71
 
63
72
  def initialize(self, algo, verbosity=0, force=False):
64
73
  """
@@ -74,6 +83,7 @@ class VortexSheet(TurbineInductionModel):
74
83
  Overwrite existing data
75
84
 
76
85
  """
86
+ self._superp = algo.mbook.wake_superpositions[self._superp_name]
77
87
  if isinstance(self.induction, str):
78
88
  self.induction = algo.mbook.axial_induction[self.induction]
79
89
  super().initialize(algo, verbosity, force)
@@ -129,7 +139,7 @@ class VortexSheet(TurbineInductionModel):
129
139
  The target point data
130
140
  downwind_index: int
131
141
  The index of the wake causing turbine
132
- in the downwnd order
142
+ in the downwind order
133
143
  wake_coos: numpy.ndarray
134
144
  The wake frame coordinates of the evaluation
135
145
  points, shape: (n_states, n_targets, n_tpoints, 3)
@@ -159,18 +169,6 @@ class VortexSheet(TurbineInductionModel):
159
169
  downwind_index=downwind_index,
160
170
  )
161
171
 
162
- # get ws
163
- ws = self.get_data(
164
- FV.REWS,
165
- FC.STATE_TARGET_TPOINT,
166
- lookup="w",
167
- algo=algo,
168
- fdata=fdata,
169
- tdata=tdata,
170
- upcast=True,
171
- downwind_index=downwind_index,
172
- )
173
-
174
172
  # get D
175
173
  D = self.get_data(
176
174
  FV.D,
@@ -184,44 +182,84 @@ class VortexSheet(TurbineInductionModel):
184
182
  )
185
183
 
186
184
  sp_sel = (ct > 1e-8) & (x <= 0)
187
- ws_sel = ws[sp_sel]
188
185
  ct_sel = ct[sp_sel]
189
186
  r_sph_sel = r_sph[sp_sel]
190
187
  D_sel = D[sp_sel]
191
188
 
192
189
  if np.any(sp_sel):
193
- blockage = (
194
- ws_sel
195
- * (
196
- 1
197
- - self.induction.ct2a(ct_sel)
198
- * ((1 + 2 * r_sph_sel / D_sel) * (1 + (2 * r_sph_sel / D_sel) ** 2))
199
- ** (-0.5)
200
- )
201
- ) - ws_sel
202
- wake_deltas[FV.WS][sp_sel] += blockage
190
+ blockage = self.induction.ct2a(ct_sel) * (
191
+ (1 + 2 * r_sph_sel / D_sel) * (1 + (2 * r_sph_sel / D_sel) ** 2)
192
+ ) ** (-0.5)
193
+
194
+ self._superp.add_wake(
195
+ algo,
196
+ mdata,
197
+ fdata,
198
+ tdata,
199
+ downwind_index,
200
+ sp_sel,
201
+ FV.WS,
202
+ wake_deltas[FV.WS],
203
+ -blockage,
204
+ )
203
205
 
204
206
  if not self.pre_rotor_only:
205
207
  sp_sel = (
206
208
  (ct > 1e-8) & (x > 0) & (r > D / 2)
207
209
  ) # mirror in rotor plane and inverse blockage, but not directly behind rotor
208
- ws_sel = ws[sp_sel]
209
210
  ct_sel = ct[sp_sel]
210
211
  r_sph_sel = r_sph[sp_sel]
211
212
  D_sel = D[sp_sel]
212
213
  if np.any(sp_sel):
213
- blockage = (
214
- ws_sel
215
- * (
216
- 1
217
- - self.induction.ct2a(ct_sel)
218
- * (
219
- (1 + 2 * r_sph_sel / D_sel)
220
- * (1 + (2 * r_sph_sel / D_sel) ** 2)
221
- )
222
- ** (-0.5)
223
- )
224
- ) - ws_sel
225
- wake_deltas[FV.WS][sp_sel] += -blockage
214
+ blockage = self.induction.ct2a(ct_sel) * (
215
+ (1 + 2 * r_sph_sel / D_sel) * (1 + (2 * r_sph_sel / D_sel) ** 2)
216
+ ) ** (-0.5)
217
+
218
+ self._superp.add_wake(
219
+ algo,
220
+ mdata,
221
+ fdata,
222
+ tdata,
223
+ downwind_index,
224
+ sp_sel,
225
+ FV.WS,
226
+ wake_deltas[FV.WS],
227
+ blockage,
228
+ )
226
229
 
227
230
  return wake_deltas
231
+
232
+ def finalize_wake_deltas(
233
+ self,
234
+ algo,
235
+ mdata,
236
+ fdata,
237
+ amb_results,
238
+ wake_deltas,
239
+ ):
240
+ """
241
+ Finalize the wake calculation.
242
+
243
+ Modifies wake_deltas on the fly.
244
+
245
+ Parameters
246
+ ----------
247
+ algo: foxes.core.Algorithm
248
+ The calculation algorithm
249
+ mdata: foxes.core.MData
250
+ The model data
251
+ fdata: foxes.core.FData
252
+ The farm data
253
+ amb_results: dict
254
+ The ambient results, key: variable name str,
255
+ values: numpy.ndarray with shape
256
+ (n_states, n_targets, n_tpoints)
257
+ wake_deltas: dict
258
+ The wake deltas object at the selected target
259
+ turbines. Key: variable str, value: numpy.ndarray
260
+ with shape (n_states, n_targets, n_tpoints)
261
+
262
+ """
263
+ wake_deltas[FV.WS] = self._superp.calc_final_wake_delta(
264
+ algo, mdata, fdata, FV.WS, amb_results[FV.WS], wake_deltas[FV.WS]
265
+ )
@@ -278,8 +278,9 @@ class CrespoHernandezTIWake(TopHatWakeModel):
278
278
  fdata=fdata,
279
279
  tdata=tdata,
280
280
  downwind_index=downwind_index,
281
- upcast=True,
282
- )[st_sel]
281
+ upcast=False,
282
+ selection=st_sel,
283
+ )
283
284
 
284
285
  # get TI:
285
286
  ti = self.get_data(
@@ -290,8 +291,9 @@ class CrespoHernandezTIWake(TopHatWakeModel):
290
291
  fdata=fdata,
291
292
  tdata=tdata,
292
293
  downwind_index=downwind_index,
293
- upcast=True,
294
- )[st_sel]
294
+ upcast=False,
295
+ selection=st_sel,
296
+ )
295
297
 
296
298
  # calculate induction factor:
297
299
  twoa = 2 * self.induction.ct2a(ct)
@@ -169,7 +169,7 @@ class IECTIWake(TopHatWakeModel):
169
169
  algo=algo,
170
170
  fdata=fdata,
171
171
  tdata=tdata,
172
- upcast=True,
172
+ upcast=False,
173
173
  downwind_index=downwind_index,
174
174
  )
175
175
  return D / 2 + k * x
@@ -228,8 +228,9 @@ class IECTIWake(TopHatWakeModel):
228
228
  fdata=fdata,
229
229
  tdata=tdata,
230
230
  downwind_index=downwind_index,
231
- upcast=True,
232
- )[st_sel]
231
+ upcast=False,
232
+ selection=st_sel,
233
+ )
233
234
 
234
235
  # get ws:
235
236
  ws = self.get_data(
@@ -240,8 +241,9 @@ class IECTIWake(TopHatWakeModel):
240
241
  fdata=fdata,
241
242
  tdata=tdata,
242
243
  downwind_index=downwind_index,
243
- upcast=True,
244
- )[st_sel]
244
+ upcast=False,
245
+ selection=st_sel,
246
+ )
245
247
 
246
248
  # calculate wind deficit:
247
249
  if self.iec_type == "2005":
@@ -157,8 +157,9 @@ class Bastankhah2014(GaussianWakeModel):
157
157
  fdata=fdata,
158
158
  tdata=tdata,
159
159
  downwind_index=downwind_index,
160
- upcast=True,
161
- )[st_sel]
160
+ upcast=False,
161
+ selection=st_sel,
162
+ )
162
163
 
163
164
  # get k:
164
165
  k = self.wake_k(
@@ -167,8 +168,9 @@ class Bastankhah2014(GaussianWakeModel):
167
168
  fdata=fdata,
168
169
  tdata=tdata,
169
170
  downwind_index=downwind_index,
170
- upcast=True,
171
- )[st_sel]
171
+ upcast=False,
172
+ selection=st_sel,
173
+ )
172
174
 
173
175
  # calculate sigma:
174
176
  # beta = 0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct)
@@ -191,7 +191,8 @@ class Bastankhah2016Model(Model):
191
191
  fdata=fdata,
192
192
  tdata=tdata,
193
193
  downwind_index=downwind_index,
194
- upcast=True,
194
+ upcast=False,
195
+ selection=st_sel,
195
196
  )
196
197
 
197
198
  # get TI:
@@ -203,7 +204,8 @@ class Bastankhah2016Model(Model):
203
204
  fdata=fdata,
204
205
  tdata=tdata,
205
206
  downwind_index=downwind_index,
206
- upcast=True,
207
+ upcast=False,
208
+ selection=st_sel,
207
209
  )
208
210
 
209
211
  # get alpha:
@@ -215,7 +217,8 @@ class Bastankhah2016Model(Model):
215
217
  fdata=fdata,
216
218
  tdata=tdata,
217
219
  downwind_index=downwind_index,
218
- upcast=True,
220
+ upcast=False,
221
+ selection=st_sel,
219
222
  )
220
223
 
221
224
  # get beta:
@@ -227,19 +230,16 @@ class Bastankhah2016Model(Model):
227
230
  fdata=fdata,
228
231
  tdata=tdata,
229
232
  downwind_index=downwind_index,
230
- upcast=True,
233
+ upcast=False,
234
+ selection=st_sel,
231
235
  )
232
236
 
233
237
  # apply filter:
234
238
  x = x[st_sel]
235
239
  D = D[st_sel]
236
240
  ct = ct[st_sel]
237
- ws = ws[st_sel]
238
- ti = ti[st_sel]
239
241
  k = k[st_sel]
240
242
  gamma = gamma[st_sel]
241
- alpha = alpha[st_sel]
242
- beta = beta[st_sel]
243
243
 
244
244
  # calc theta_c0, Eq. (6.12):
245
245
  cosg = np.cos(gamma)
@@ -552,7 +552,7 @@ class Bastankhah2016(DistSlicedWakeModel):
552
552
  upcast=True,
553
553
  downwind_index=downwind_index,
554
554
  )
555
- gamma *= np.pi / 180
555
+ gamma = gamma * np.pi / 180
556
556
 
557
557
  # get k:
558
558
  k = self.wake_k(
@@ -156,8 +156,9 @@ class JensenWake(TopHatWakeModel):
156
156
  fdata=fdata,
157
157
  tdata=tdata,
158
158
  downwind_index=downwind_index,
159
- upcast=True,
160
- )[st_sel]
159
+ upcast=False,
160
+ selection=st_sel,
161
+ )
161
162
  / 2
162
163
  )
163
164
 
@@ -175,8 +175,9 @@ class TurbOParkWake(GaussianWakeModel):
175
175
  fdata=fdata,
176
176
  tdata=tdata,
177
177
  downwind_index=downwind_index,
178
- upcast=True,
179
- )[st_sel]
178
+ upcast=False,
179
+ selection=st_sel,
180
+ )
180
181
 
181
182
  # get TI:
182
183
  ati = self.get_data(
@@ -187,7 +188,8 @@ class TurbOParkWake(GaussianWakeModel):
187
188
  fdata=fdata,
188
189
  tdata=tdata,
189
190
  downwind_index=downwind_index,
190
- upcast=True,
191
+ upcast=False,
192
+ selection=st_sel,
191
193
  )
192
194
 
193
195
  # get k:
@@ -197,11 +199,10 @@ class TurbOParkWake(GaussianWakeModel):
197
199
  fdata=fdata,
198
200
  tdata=tdata,
199
201
  downwind_index=downwind_index,
200
- upcast=True,
201
202
  amb_ti=ati,
202
- )[st_sel]
203
-
204
- ati = ati[st_sel]
203
+ upcast=False,
204
+ selection=st_sel,
205
+ )
205
206
 
206
207
  # calculate sigma:
207
208
  # beta = np.sqrt(0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct))
@@ -458,8 +459,9 @@ class TurbOParkWakeIX(GaussianWakeModel):
458
459
  fdata=fdata,
459
460
  tdata=tdata,
460
461
  downwind_index=downwind_index,
461
- upcast=True,
462
- )[st_sel]
462
+ upcast=False,
463
+ selection=st_sel,
464
+ )
463
465
 
464
466
  # get k:
465
467
  k = self.wake_k(
@@ -468,8 +470,9 @@ class TurbOParkWakeIX(GaussianWakeModel):
468
470
  fdata=fdata,
469
471
  tdata=tdata,
470
472
  downwind_index=downwind_index,
471
- upcast=True,
472
- )[st_sel]
473
+ upcast=False,
474
+ selection=st_sel,
475
+ )
473
476
 
474
477
  # calculate sigma:
475
478
  # beta = np.sqrt(0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct))
@@ -63,7 +63,7 @@ class TILinear(WakeSuperposition):
63
63
  The target point data
64
64
  downwind_index: int
65
65
  The index of the wake causing turbine
66
- in the downwnd order
66
+ in the downwind order
67
67
  st_sel: numpy.ndarray of bool
68
68
  The selection of targets, shape: (n_states, n_targets)
69
69
  variable: str
@@ -63,7 +63,7 @@ class TIMax(WakeSuperposition):
63
63
  The target point data
64
64
  downwind_index: int
65
65
  The index of the wake causing turbine
66
- in the downwnd order
66
+ in the downwind order
67
67
  st_sel: numpy.ndarray of bool
68
68
  The selection of targets, shape: (n_states, n_targets)
69
69
  variable: str
@@ -70,7 +70,7 @@ class TIPow(WakeSuperposition):
70
70
  The target point data
71
71
  downwind_index: int
72
72
  The index of the wake causing turbine
73
- in the downwnd order
73
+ in the downwind order
74
74
  st_sel: numpy.ndarray of bool
75
75
  The selection of targets, shape: (n_states, n_targets)
76
76
  variable: str
@@ -63,7 +63,7 @@ class TIQuadratic(WakeSuperposition):
63
63
  The target point data
64
64
  downwind_index: int
65
65
  The index of the wake causing turbine
66
- in the downwnd order
66
+ in the downwind order
67
67
  st_sel: numpy.ndarray of bool
68
68
  The selection of targets, shape: (n_states, n_targets)
69
69
  variable: str
@@ -7,7 +7,7 @@ import foxes.constants as FC
7
7
 
8
8
  class WSLinear(WakeSuperposition):
9
9
  """
10
- Linear supersposition of wind deficit results
10
+ Linear superposition of wind deficit results
11
11
 
12
12
  Attributes
13
13
  ----------
@@ -94,7 +94,7 @@ class WSLinear(WakeSuperposition):
94
94
  The target point data
95
95
  downwind_index: int
96
96
  The index of the wake causing turbine
97
- in the downwnd order
97
+ in the downwind order
98
98
  st_sel: numpy.ndarray of bool
99
99
  The selection of targets, shape: (n_states, n_targets)
100
100
  variable: str
@@ -121,14 +121,15 @@ class WSLinear(WakeSuperposition):
121
121
  if np.any(st_sel):
122
122
  scale = self.get_data(
123
123
  FV.AMB_REWS if self.scale_amb else FV.REWS,
124
- FC.STATE_TARGET,
124
+ FC.STATE_TARGET_TPOINT,
125
125
  lookup="w",
126
126
  algo=algo,
127
127
  fdata=fdata,
128
128
  tdata=tdata,
129
129
  downwind_index=downwind_index,
130
- upcast=True,
131
- )[st_sel, None]
130
+ upcast=False,
131
+ selection=st_sel,
132
+ )
132
133
 
133
134
  wake_delta[st_sel] += scale * wake_model_result
134
135
 
@@ -182,7 +183,7 @@ class WSLinear(WakeSuperposition):
182
183
 
183
184
  class WSLinearLocal(WakeSuperposition):
184
185
  """
185
- Local linear supersposition of wind deficit results
186
+ Local linear superposition of wind deficit results
186
187
 
187
188
  Attributes
188
189
  ----------
@@ -261,7 +262,7 @@ class WSLinearLocal(WakeSuperposition):
261
262
  The target point data
262
263
  downwind_index: int
263
264
  The index of the wake causing turbine
264
- in the downwnd order
265
+ in the downwind order
265
266
  st_sel: numpy.ndarray of bool
266
267
  The selection of targets, shape: (n_states, n_targets)
267
268
  variable: str
@@ -7,7 +7,7 @@ import foxes.constants as FC
7
7
 
8
8
  class WSMax(WakeSuperposition):
9
9
  """
10
- Max supersposition of wind deficit results
10
+ Max superposition of wind deficit results
11
11
 
12
12
  Attributes
13
13
  ----------
@@ -94,7 +94,7 @@ class WSMax(WakeSuperposition):
94
94
  The target point data
95
95
  downwind_index: int
96
96
  The index of the wake causing turbine
97
- in the downwnd order
97
+ in the downwind order
98
98
  st_sel: numpy.ndarray of bool
99
99
  The selection of targets, shape: (n_states, n_targets)
100
100
  variable: str
@@ -121,14 +121,15 @@ class WSMax(WakeSuperposition):
121
121
  if np.any(st_sel):
122
122
  scale = self.get_data(
123
123
  FV.AMB_REWS if self.scale_amb else FV.REWS,
124
- FC.STATE_TARGET,
124
+ FC.STATE_TARGET_TPOINT,
125
125
  lookup="w",
126
126
  algo=algo,
127
127
  fdata=fdata,
128
128
  tdata=tdata,
129
129
  downwind_index=downwind_index,
130
- upcast=True,
131
- )[st_sel, None]
130
+ upcast=False,
131
+ selection=st_sel,
132
+ )
132
133
 
133
134
  wake_model_result = np.abs(scale * wake_model_result)
134
135
  odelta = wake_delta[st_sel]
@@ -185,7 +186,7 @@ class WSMax(WakeSuperposition):
185
186
 
186
187
  class WSMaxLocal(WakeSuperposition):
187
188
  """
188
- Local max supersposition of wind deficit results
189
+ Local max superposition of wind deficit results
189
190
 
190
191
  Attributes
191
192
  ----------
@@ -264,7 +265,7 @@ class WSMaxLocal(WakeSuperposition):
264
265
  The target point data
265
266
  downwind_index: int
266
267
  The index of the wake causing turbine
267
- in the downwnd order
268
+ in the downwind order
268
269
  st_sel: numpy.ndarray of bool
269
270
  The selection of targets, shape: (n_states, n_targets)
270
271
  variable: str
@@ -7,7 +7,7 @@ import foxes.constants as FC
7
7
 
8
8
  class WSPow(WakeSuperposition):
9
9
  """
10
- Power supersposition of wind deficit results
10
+ Power superposition of wind deficit results
11
11
 
12
12
  Attributes
13
13
  ----------
@@ -99,7 +99,7 @@ class WSPow(WakeSuperposition):
99
99
  The target point data
100
100
  downwind_index: int
101
101
  The index of the wake causing turbine
102
- in the downwnd order
102
+ in the downwind order
103
103
  st_sel: numpy.ndarray of bool
104
104
  The selection of targets, shape: (n_states, n_targets)
105
105
  variable: str
@@ -126,14 +126,15 @@ class WSPow(WakeSuperposition):
126
126
  if np.any(st_sel):
127
127
  scale = self.get_data(
128
128
  FV.AMB_REWS if self.scale_amb else FV.REWS,
129
- FC.STATE_TARGET,
129
+ FC.STATE_TARGET_TPOINT,
130
130
  lookup="w",
131
131
  algo=algo,
132
132
  fdata=fdata,
133
133
  tdata=tdata,
134
134
  downwind_index=downwind_index,
135
- upcast=True,
136
- )[st_sel, None]
135
+ upcast=False,
136
+ selection=st_sel,
137
+ )
137
138
 
138
139
  wake_delta[st_sel] += np.abs(scale * wake_model_result) ** self.pow
139
140
 
@@ -187,7 +188,7 @@ class WSPow(WakeSuperposition):
187
188
 
188
189
  class WSPowLocal(WakeSuperposition):
189
190
  """
190
- Local power supersposition of wind deficit results
191
+ Local power superposition of wind deficit results
191
192
 
192
193
  Attributes
193
194
  ----------
@@ -272,7 +273,7 @@ class WSPowLocal(WakeSuperposition):
272
273
  The target point data
273
274
  downwind_index: int
274
275
  The index of the wake causing turbine
275
- in the downwnd order
276
+ in the downwind order
276
277
  st_sel: numpy.ndarray of bool
277
278
  The selection of targets, shape: (n_states, n_targets)
278
279
  variable: str
@@ -7,7 +7,7 @@ import foxes.constants as FC
7
7
 
8
8
  class WSProduct(WakeSuperposition):
9
9
  """
10
- Product supersposition of wind deficit results
10
+ Product superposition of wind deficit results
11
11
 
12
12
  This is based on the idea that the dimensionless
13
13
  wind deficit should be rescaled with the wake
@@ -95,7 +95,7 @@ class WSProduct(WakeSuperposition):
95
95
  The target point data
96
96
  downwind_index: int
97
97
  The index of the wake causing turbine
98
- in the downwnd order
98
+ in the downwind order
99
99
  st_sel: numpy.ndarray of bool
100
100
  The selection of targets, shape: (n_states, n_targets)
101
101
  variable: str
@@ -119,10 +119,10 @@ class WSProduct(WakeSuperposition):
119
119
  f"Superposition '{self.name}': Expecting wind speed variable, got {variable}"
120
120
  )
121
121
 
122
- if np.any(st_sel):
123
- if np.max(np.abs(wake_delta)) < 1e-14:
124
- wake_delta[:] = 1
122
+ if np.max(np.abs(wake_delta)) < 1e-14:
123
+ wake_delta[:] = 1
125
124
 
125
+ if np.any(st_sel):
126
126
  wake_delta[st_sel] *= 1 + wake_model_result
127
127
 
128
128
  return wake_delta