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.
- docs/source/conf.py +0 -1
- examples/states_lookup_table/run.py +1 -1
- examples/timeseries/run.py +11 -4
- foxes/algorithms/downwind/downwind.py +18 -13
- foxes/algorithms/downwind/models/farm_wakes_calc.py +1 -1
- foxes/algorithms/downwind/models/init_farm_data.py +1 -1
- foxes/algorithms/downwind/models/point_wakes_calc.py +1 -1
- foxes/algorithms/downwind/models/reorder_farm_output.py +1 -1
- foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
- foxes/algorithms/downwind/models/set_amb_point_results.py +1 -1
- foxes/algorithms/iterative/iterative.py +1 -1
- foxes/algorithms/iterative/models/farm_wakes_calc.py +1 -1
- foxes/algorithms/iterative/models/urelax.py +3 -3
- foxes/algorithms/sequential/models/plugin.py +4 -4
- foxes/algorithms/sequential/models/seq_state.py +1 -1
- foxes/constants.py +5 -5
- foxes/core/algorithm.py +2 -2
- foxes/core/data_calc_model.py +2 -2
- foxes/core/engine.py +20 -10
- foxes/core/farm_controller.py +3 -3
- foxes/core/farm_data_model.py +1 -1
- foxes/core/ground_model.py +2 -2
- foxes/core/model.py +122 -108
- foxes/core/partial_wakes_model.py +1 -1
- foxes/core/point_data_model.py +2 -2
- foxes/core/states.py +1 -1
- foxes/core/turbine_type.py +2 -2
- foxes/core/wake_frame.py +8 -30
- foxes/core/wake_model.py +3 -2
- foxes/core/wake_superposition.py +1 -1
- foxes/data/windio/windio_5turbines_timeseries.yaml +9 -15
- foxes/engines/__init__.py +1 -0
- foxes/engines/dask.py +13 -6
- foxes/engines/multiprocess.py +5 -8
- foxes/engines/numpy.py +8 -26
- foxes/engines/pool.py +10 -24
- foxes/engines/ray.py +79 -0
- foxes/engines/single.py +3 -1
- foxes/input/farm_layout/from_json.py +1 -1
- foxes/input/states/__init__.py +1 -0
- foxes/input/states/field_data_nc.py +4 -4
- foxes/input/states/multi_height.py +4 -4
- foxes/input/states/scan_ws.py +1 -1
- foxes/input/states/single.py +1 -1
- foxes/input/states/slice_data_nc.py +681 -0
- foxes/input/states/states_table.py +3 -3
- foxes/input/windio/__init__.py +1 -1
- foxes/input/windio/read_attributes.py +8 -2
- foxes/input/windio/read_fields.py +3 -0
- foxes/input/windio/read_outputs.py +8 -2
- foxes/input/windio/windio.py +6 -2
- foxes/models/farm_models/turbine2farm.py +1 -1
- foxes/models/ground_models/wake_mirror.py +2 -2
- foxes/models/model_book.py +29 -2
- foxes/models/partial_wakes/axiwake.py +3 -3
- foxes/models/partial_wakes/top_hat.py +2 -2
- foxes/models/point_models/set_uniform_data.py +1 -1
- foxes/models/point_models/tke2ti.py +1 -1
- foxes/models/point_models/wake_deltas.py +1 -1
- foxes/models/rotor_models/grid.py +2 -2
- foxes/models/turbine_models/calculator.py +4 -4
- foxes/models/turbine_models/kTI_model.py +22 -6
- foxes/models/turbine_models/lookup_table.py +3 -2
- foxes/models/turbine_types/PCt_file.py +5 -5
- foxes/models/turbine_types/PCt_from_two.py +5 -5
- foxes/models/turbine_types/TBL_file.py +80 -0
- foxes/models/turbine_types/__init__.py +1 -0
- foxes/models/turbine_types/lookup.py +5 -5
- foxes/models/turbine_types/null_type.py +3 -3
- foxes/models/turbine_types/wsrho2PCt_from_two.py +7 -7
- foxes/models/turbine_types/wsti2PCt_from_two.py +9 -9
- foxes/models/vertical_profiles/__init__.py +1 -1
- foxes/models/wake_frames/dynamic_wakes.py +2 -2
- foxes/models/wake_frames/farm_order.py +2 -2
- foxes/models/wake_frames/rotor_wd.py +2 -2
- foxes/models/wake_frames/seq_dynamic_wakes.py +5 -11
- foxes/models/wake_frames/streamlines.py +2 -2
- foxes/models/wake_frames/timelines.py +2 -2
- foxes/models/wake_frames/yawed_wakes.py +3 -3
- foxes/models/wake_models/dist_sliced.py +1 -1
- foxes/models/wake_models/induction/rankine_half_body.py +1 -1
- foxes/models/wake_models/induction/rathmann.py +76 -22
- foxes/models/wake_models/induction/self_similar.py +76 -26
- foxes/models/wake_models/induction/vortex_sheet.py +84 -46
- foxes/models/wake_models/ti/crespo_hernandez.py +6 -4
- foxes/models/wake_models/ti/iec_ti.py +7 -5
- foxes/models/wake_models/wind/bastankhah14.py +6 -4
- foxes/models/wake_models/wind/bastankhah16.py +9 -9
- foxes/models/wake_models/wind/jensen.py +3 -2
- foxes/models/wake_models/wind/turbopark.py +14 -11
- foxes/models/wake_superpositions/ti_linear.py +1 -1
- foxes/models/wake_superpositions/ti_max.py +1 -1
- foxes/models/wake_superpositions/ti_pow.py +1 -1
- foxes/models/wake_superpositions/ti_quadratic.py +1 -1
- foxes/models/wake_superpositions/ws_linear.py +8 -7
- foxes/models/wake_superpositions/ws_max.py +8 -7
- foxes/models/wake_superpositions/ws_pow.py +8 -7
- foxes/models/wake_superpositions/ws_product.py +5 -5
- foxes/models/wake_superpositions/ws_quadratic.py +8 -7
- foxes/output/farm_layout.py +14 -10
- foxes/output/farm_results_eval.py +1 -1
- foxes/output/grids.py +1 -1
- foxes/output/results_writer.py +2 -2
- foxes/output/rose_plot.py +3 -3
- foxes/output/seq_plugins/seq_flow_ani_plugin.py +2 -2
- foxes/output/seq_plugins/seq_wake_debug_plugin.py +2 -2
- foxes/output/state_turbine_map.py +1 -1
- foxes/utils/abl/neutral.py +2 -2
- foxes/utils/abl/stable.py +2 -2
- foxes/utils/abl/unstable.py +2 -2
- foxes/utils/data_book.py +1 -1
- foxes/utils/dict.py +23 -0
- foxes/utils/exec_python.py +1 -1
- foxes/utils/factory.py +29 -1
- foxes/utils/geom2d/circle.py +1 -1
- foxes/utils/geom2d/polygon.py +1 -1
- foxes/utils/geopandas_utils.py +2 -2
- foxes/utils/load.py +2 -2
- foxes/utils/pandas_helpers.py +1 -1
- foxes/utils/xarray_utils.py +1 -1
- foxes/variables.py +3 -3
- {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/METADATA +8 -6
- {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/RECORD +127 -125
- {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/WHEEL +1 -1
- foxes/utils/geopandas_helpers.py +0 -294
- /examples/{induction_RHB → induction}/run.py +0 -0
- {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/LICENSE +0 -0
- {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
|
-
|
|
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__(
|
|
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
|
-
|
|
34
|
-
|
|
41
|
+
superposition: str
|
|
42
|
+
The wind speed superposition
|
|
35
43
|
induction: foxes.core.AxialInductionModel or str
|
|
36
44
|
The induction model
|
|
37
|
-
|
|
38
|
-
|
|
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
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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=
|
|
282
|
-
|
|
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=
|
|
294
|
-
|
|
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=
|
|
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=
|
|
232
|
-
|
|
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=
|
|
244
|
-
|
|
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=
|
|
161
|
-
|
|
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=
|
|
171
|
-
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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
|
|
555
|
+
gamma = gamma * np.pi / 180
|
|
556
556
|
|
|
557
557
|
# get k:
|
|
558
558
|
k = self.wake_k(
|
|
@@ -175,8 +175,9 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
175
175
|
fdata=fdata,
|
|
176
176
|
tdata=tdata,
|
|
177
177
|
downwind_index=downwind_index,
|
|
178
|
-
upcast=
|
|
179
|
-
|
|
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=
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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=
|
|
462
|
-
|
|
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=
|
|
472
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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=
|
|
131
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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=
|
|
131
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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=
|
|
136
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
123
|
-
|
|
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
|