foxes 0.6.1__py3-none-any.whl → 0.7__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 +131 -65
- foxes/algorithms/downwind/models/__init__.py +2 -1
- foxes/algorithms/downwind/models/farm_wakes_calc.py +87 -55
- foxes/algorithms/downwind/models/init_farm_data.py +134 -0
- foxes/algorithms/downwind/models/point_wakes_calc.py +54 -65
- foxes/algorithms/downwind/models/{calc_order.py → reorder_farm_output.py} +28 -26
- foxes/algorithms/iterative/iterative.py +100 -51
- foxes/algorithms/iterative/models/convergence.py +3 -3
- foxes/algorithms/iterative/models/farm_wakes_calc.py +55 -48
- foxes/algorithms/sequential/models/seq_state.py +7 -6
- foxes/algorithms/sequential/sequential.py +81 -44
- foxes/constants.py +33 -18
- foxes/core/__init__.py +2 -2
- foxes/core/algorithm.py +31 -12
- foxes/core/data.py +335 -41
- foxes/core/data_calc_model.py +27 -23
- foxes/core/farm_controller.py +27 -28
- foxes/core/farm_data_model.py +26 -4
- foxes/core/model.py +186 -129
- foxes/core/partial_wakes_model.py +84 -81
- foxes/core/point_data_model.py +51 -18
- foxes/core/rotor_model.py +59 -77
- foxes/core/states.py +6 -6
- foxes/core/turbine_model.py +4 -4
- foxes/core/turbine_type.py +24 -0
- foxes/core/vertical_profile.py +3 -3
- foxes/core/wake_frame.py +91 -50
- foxes/core/wake_model.py +74 -43
- foxes/core/wake_superposition.py +29 -26
- foxes/input/farm_layout/__init__.py +1 -0
- foxes/input/farm_layout/from_random.py +49 -0
- foxes/input/states/__init__.py +1 -1
- foxes/input/states/create/__init__.py +1 -0
- foxes/input/states/create/random_abl_states.py +6 -2
- foxes/input/states/create/random_timeseries.py +56 -0
- foxes/input/states/field_data_nc.py +12 -8
- foxes/input/states/multi_height.py +24 -14
- foxes/input/states/scan_ws.py +13 -17
- foxes/input/states/single.py +28 -20
- foxes/input/states/states_table.py +22 -18
- foxes/models/axial_induction_models/betz.py +1 -1
- foxes/models/farm_models/turbine2farm.py +2 -2
- foxes/models/model_book.py +40 -14
- foxes/models/partial_wakes/__init__.py +2 -2
- foxes/models/partial_wakes/axiwake.py +73 -200
- foxes/models/partial_wakes/centre.py +40 -0
- foxes/models/partial_wakes/grid.py +7 -63
- foxes/models/partial_wakes/rotor_points.py +53 -147
- foxes/models/partial_wakes/segregated.py +158 -0
- foxes/models/partial_wakes/top_hat.py +88 -196
- foxes/models/point_models/set_uniform_data.py +4 -4
- foxes/models/point_models/tke2ti.py +4 -4
- foxes/models/point_models/wake_deltas.py +4 -4
- foxes/models/rotor_models/centre.py +15 -19
- foxes/models/rotor_models/grid.py +2 -1
- foxes/models/rotor_models/levels.py +2 -1
- foxes/models/turbine_models/__init__.py +0 -1
- foxes/models/turbine_models/calculator.py +11 -7
- foxes/models/turbine_models/kTI_model.py +13 -11
- foxes/models/turbine_models/lookup_table.py +22 -9
- foxes/models/turbine_models/power_mask.py +81 -51
- foxes/models/turbine_models/rotor_centre_calc.py +17 -20
- foxes/models/turbine_models/sector_management.py +5 -6
- foxes/models/turbine_models/set_farm_vars.py +49 -20
- foxes/models/turbine_models/table_factors.py +5 -5
- foxes/models/turbine_models/thrust2ct.py +9 -5
- foxes/models/turbine_models/yaw2yawm.py +7 -13
- foxes/models/turbine_models/yawm2yaw.py +7 -11
- foxes/models/turbine_types/PCt_file.py +84 -3
- foxes/models/turbine_types/PCt_from_two.py +7 -3
- foxes/models/turbine_types/null_type.py +2 -2
- foxes/models/turbine_types/wsrho2PCt_from_two.py +2 -2
- foxes/models/turbine_types/wsti2PCt_from_two.py +6 -2
- foxes/models/wake_frames/farm_order.py +26 -22
- foxes/models/wake_frames/rotor_wd.py +32 -31
- foxes/models/wake_frames/seq_dynamic_wakes.py +112 -64
- foxes/models/wake_frames/streamlines.py +51 -47
- foxes/models/wake_frames/timelines.py +59 -47
- foxes/models/wake_frames/yawed_wakes.py +63 -40
- foxes/models/wake_models/axisymmetric.py +31 -35
- foxes/models/wake_models/dist_sliced.py +50 -56
- foxes/models/wake_models/gaussian.py +33 -35
- foxes/models/wake_models/induction/rankine_half_body.py +79 -87
- foxes/models/wake_models/induction/rathmann.py +56 -63
- foxes/models/wake_models/induction/self_similar.py +59 -62
- foxes/models/wake_models/ti/crespo_hernandez.py +83 -74
- foxes/models/wake_models/ti/iec_ti.py +65 -75
- foxes/models/wake_models/top_hat.py +60 -69
- foxes/models/wake_models/wake_mirror.py +49 -54
- foxes/models/wake_models/wind/bastankhah14.py +44 -66
- foxes/models/wake_models/wind/bastankhah16.py +84 -111
- foxes/models/wake_models/wind/jensen.py +67 -89
- foxes/models/wake_models/wind/turbopark.py +93 -133
- foxes/models/wake_superpositions/ti_linear.py +33 -27
- foxes/models/wake_superpositions/ti_max.py +33 -27
- foxes/models/wake_superpositions/ti_pow.py +35 -27
- foxes/models/wake_superpositions/ti_quadratic.py +33 -27
- foxes/models/wake_superpositions/ws_linear.py +39 -32
- foxes/models/wake_superpositions/ws_max.py +40 -33
- foxes/models/wake_superpositions/ws_pow.py +39 -32
- foxes/models/wake_superpositions/ws_product.py +35 -28
- foxes/models/wake_superpositions/ws_quadratic.py +39 -32
- foxes/opt/constraints/min_dist.py +1 -1
- foxes/opt/objectives/farm_vars.py +1 -1
- foxes/opt/problems/layout/farm_layout.py +38 -97
- foxes/output/__init__.py +1 -0
- foxes/output/farm_results_eval.py +1 -1
- foxes/output/flow_plots_2d/flow_plots.py +2 -0
- foxes/output/flow_plots_2d/get_fig.py +2 -0
- foxes/output/grids.py +1 -1
- foxes/output/rose_plot.py +3 -3
- foxes/output/rotor_point_plots.py +117 -0
- foxes/output/turbine_type_curves.py +2 -2
- foxes/utils/__init__.py +2 -1
- foxes/utils/load.py +29 -0
- foxes/utils/random_xy.py +56 -0
- foxes/utils/runners/runners.py +13 -1
- foxes/utils/windrose_plot.py +1 -1
- foxes/variables.py +10 -0
- {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/METADATA +13 -7
- {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/RECORD +126 -122
- {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/WHEEL +1 -1
- foxes/models/partial_wakes/distsliced.py +0 -322
- foxes/models/partial_wakes/mapped.py +0 -252
- foxes/models/turbine_models/set_XYHD.py +0 -130
- {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/LICENSE +0 -0
- {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/top_level.txt +0 -0
- {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/zip-safe +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.models.wake_models.gaussian import GaussianWakeModel
|
|
4
|
-
from foxes.utils import sqrt_reg
|
|
5
4
|
import foxes.variables as FV
|
|
6
5
|
import foxes.constants as FC
|
|
7
6
|
|
|
@@ -48,10 +47,8 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
48
47
|
|
|
49
48
|
Parameters
|
|
50
49
|
----------
|
|
51
|
-
|
|
52
|
-
The
|
|
53
|
-
value: The wake superposition model name,
|
|
54
|
-
will be looked up in model book
|
|
50
|
+
superposition: str
|
|
51
|
+
The wind deficit superposition
|
|
55
52
|
A: float
|
|
56
53
|
The wake growth parameter A.
|
|
57
54
|
sbeta_factor: float
|
|
@@ -73,8 +70,11 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
73
70
|
self.induction = induction
|
|
74
71
|
|
|
75
72
|
def __repr__(self):
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
iname = (
|
|
74
|
+
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
75
|
+
)
|
|
76
|
+
s = f"{type(self).__name__}"
|
|
77
|
+
s += f"({self.superpositions[FV.WS]}, A={self.A}, induction={iname})"
|
|
78
78
|
return s
|
|
79
79
|
|
|
80
80
|
def sub_models(self):
|
|
@@ -107,39 +107,13 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
107
107
|
self.induction = algo.mbook.axial_induction[self.induction]
|
|
108
108
|
super().initialize(algo, verbosity, force)
|
|
109
109
|
|
|
110
|
-
def
|
|
111
|
-
"""
|
|
112
|
-
Initialize wake delta storage.
|
|
113
|
-
|
|
114
|
-
They are added on the fly to the wake_deltas dict.
|
|
115
|
-
|
|
116
|
-
Parameters
|
|
117
|
-
----------
|
|
118
|
-
algo: foxes.core.Algorithm
|
|
119
|
-
The calculation algorithm
|
|
120
|
-
mdata: foxes.core.Data
|
|
121
|
-
The model data
|
|
122
|
-
fdata: foxes.core.Data
|
|
123
|
-
The farm data
|
|
124
|
-
pdata: foxes.core.Data
|
|
125
|
-
The evaluation point data
|
|
126
|
-
wake_deltas: dict
|
|
127
|
-
The wake deltas storage, add wake deltas
|
|
128
|
-
on the fly. Keys: Variable name str, for which the
|
|
129
|
-
wake delta applies, values: numpy.ndarray with
|
|
130
|
-
shape (n_states, n_points, ...)
|
|
131
|
-
|
|
132
|
-
"""
|
|
133
|
-
n_states = mdata.n_states
|
|
134
|
-
wake_deltas[FV.WS] = np.zeros((n_states, pdata.n_points), dtype=FC.DTYPE)
|
|
135
|
-
|
|
136
|
-
def calc_amplitude_sigma_spsel(
|
|
110
|
+
def calc_amplitude_sigma(
|
|
137
111
|
self,
|
|
138
112
|
algo,
|
|
139
113
|
mdata,
|
|
140
114
|
fdata,
|
|
141
|
-
|
|
142
|
-
|
|
115
|
+
tdata,
|
|
116
|
+
downwind_index,
|
|
143
117
|
x,
|
|
144
118
|
):
|
|
145
119
|
"""
|
|
@@ -150,73 +124,69 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
150
124
|
----------
|
|
151
125
|
algo: foxes.core.Algorithm
|
|
152
126
|
The calculation algorithm
|
|
153
|
-
mdata: foxes.core.
|
|
127
|
+
mdata: foxes.core.MData
|
|
154
128
|
The model data
|
|
155
|
-
fdata: foxes.core.
|
|
129
|
+
fdata: foxes.core.FData
|
|
156
130
|
The farm data
|
|
157
|
-
|
|
158
|
-
The
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
wake causing turbine. Shape: (n_states,)
|
|
131
|
+
tdata: foxes.core.TData
|
|
132
|
+
The target point data
|
|
133
|
+
downwind_index: int
|
|
134
|
+
The index in the downwind order
|
|
162
135
|
x: numpy.ndarray
|
|
163
|
-
The x values, shape: (n_states,
|
|
136
|
+
The x values, shape: (n_states, n_targets)
|
|
164
137
|
|
|
165
138
|
Returns
|
|
166
139
|
-------
|
|
167
140
|
amsi: tuple
|
|
168
141
|
The amplitude and sigma, both numpy.ndarray
|
|
169
|
-
with shape (
|
|
170
|
-
|
|
171
|
-
The state-
|
|
172
|
-
is non-zero, shape: (n_states,
|
|
142
|
+
with shape (n_st_sel,)
|
|
143
|
+
st_sel: numpy.ndarray of bool
|
|
144
|
+
The state-target selection, for which the wake
|
|
145
|
+
is non-zero, shape: (n_states, n_targets)
|
|
173
146
|
|
|
174
147
|
"""
|
|
175
|
-
|
|
176
148
|
# get ct:
|
|
177
149
|
ct = self.get_data(
|
|
178
150
|
FV.CT,
|
|
179
|
-
FC.
|
|
151
|
+
FC.STATE_TARGET,
|
|
180
152
|
lookup="w",
|
|
181
153
|
algo=algo,
|
|
182
154
|
fdata=fdata,
|
|
183
|
-
|
|
155
|
+
tdata=tdata,
|
|
156
|
+
downwind_index=downwind_index,
|
|
184
157
|
upcast=True,
|
|
185
|
-
states_source_turbine=states_source_turbine,
|
|
186
158
|
)
|
|
187
159
|
|
|
188
160
|
# select targets:
|
|
189
|
-
|
|
190
|
-
if np.any(
|
|
161
|
+
st_sel = (x > 1e-5) & (ct > 0.0)
|
|
162
|
+
if np.any(st_sel):
|
|
191
163
|
# apply selection:
|
|
192
|
-
x = x[
|
|
193
|
-
ct = ct[
|
|
164
|
+
x = x[st_sel]
|
|
165
|
+
ct = ct[st_sel]
|
|
194
166
|
|
|
195
167
|
# get D:
|
|
196
168
|
D = self.get_data(
|
|
197
169
|
FV.D,
|
|
198
|
-
FC.
|
|
170
|
+
FC.STATE_TARGET,
|
|
199
171
|
lookup="w",
|
|
200
172
|
algo=algo,
|
|
201
173
|
fdata=fdata,
|
|
202
|
-
|
|
174
|
+
tdata=tdata,
|
|
175
|
+
downwind_index=downwind_index,
|
|
203
176
|
upcast=True,
|
|
204
|
-
|
|
205
|
-
)
|
|
206
|
-
D = D[sp_sel]
|
|
177
|
+
)[st_sel]
|
|
207
178
|
|
|
208
179
|
# get TI:
|
|
209
180
|
ati = self.get_data(
|
|
210
181
|
FV.AMB_TI,
|
|
211
|
-
FC.
|
|
182
|
+
FC.STATE_TARGET,
|
|
212
183
|
lookup="w",
|
|
213
184
|
algo=algo,
|
|
214
185
|
fdata=fdata,
|
|
215
|
-
|
|
186
|
+
tdata=tdata,
|
|
187
|
+
downwind_index=downwind_index,
|
|
216
188
|
upcast=True,
|
|
217
|
-
|
|
218
|
-
)
|
|
219
|
-
ati = ati[sp_sel]
|
|
189
|
+
)[st_sel]
|
|
220
190
|
|
|
221
191
|
# calculate sigma:
|
|
222
192
|
# beta = np.sqrt(0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct))
|
|
@@ -258,12 +228,12 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
258
228
|
|
|
259
229
|
# case no targets:
|
|
260
230
|
else:
|
|
261
|
-
|
|
262
|
-
n_sp = np.sum(
|
|
231
|
+
st_sel = np.zeros_like(x, dtype=bool)
|
|
232
|
+
n_sp = np.sum(st_sel)
|
|
263
233
|
ampld = np.zeros(n_sp, dtype=FC.DTYPE)
|
|
264
234
|
sigma = np.zeros(n_sp, dtype=FC.DTYPE)
|
|
265
235
|
|
|
266
|
-
return {FV.WS: (ampld, sigma)},
|
|
236
|
+
return {FV.WS: (ampld, sigma)}, st_sel
|
|
267
237
|
|
|
268
238
|
|
|
269
239
|
class TurbOParkWakeIX(GaussianWakeModel):
|
|
@@ -309,10 +279,8 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
309
279
|
|
|
310
280
|
Parameters
|
|
311
281
|
----------
|
|
312
|
-
|
|
313
|
-
The
|
|
314
|
-
value: The wake superposition model name,
|
|
315
|
-
will be looked up in model book
|
|
282
|
+
superposition: str
|
|
283
|
+
The wind deficit superposition
|
|
316
284
|
dx: float
|
|
317
285
|
The step size of the integral
|
|
318
286
|
A: float, optional
|
|
@@ -341,8 +309,11 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
341
309
|
self.induction = induction
|
|
342
310
|
|
|
343
311
|
def __repr__(self):
|
|
344
|
-
|
|
345
|
-
|
|
312
|
+
iname = (
|
|
313
|
+
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
314
|
+
)
|
|
315
|
+
s = f"{type(self).__name__}({self.superpositions[FV.WS]}"
|
|
316
|
+
s += f", ti={self.ti_var}, dx={self.dx}, A={self.A}, induction={iname})"
|
|
346
317
|
return s
|
|
347
318
|
|
|
348
319
|
def sub_models(self):
|
|
@@ -375,38 +346,33 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
375
346
|
self.induction = algo.mbook.axial_induction[self.induction]
|
|
376
347
|
super().initialize(algo, verbosity, force)
|
|
377
348
|
|
|
378
|
-
def
|
|
349
|
+
def new_wake_deltas(self, algo, mdata, fdata, tdata):
|
|
379
350
|
"""
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
They are added on the fly to the wake_deltas dict.
|
|
351
|
+
Creates new empty wake delta arrays.
|
|
383
352
|
|
|
384
353
|
Parameters
|
|
385
354
|
----------
|
|
386
355
|
algo: foxes.core.Algorithm
|
|
387
356
|
The calculation algorithm
|
|
388
|
-
mdata: foxes.core.
|
|
357
|
+
mdata: foxes.core.MData
|
|
389
358
|
The model data
|
|
390
|
-
fdata: foxes.core.
|
|
359
|
+
fdata: foxes.core.FData
|
|
391
360
|
The farm data
|
|
392
|
-
|
|
393
|
-
The
|
|
361
|
+
tdata: foxes.core.TData
|
|
362
|
+
The target point data
|
|
363
|
+
|
|
364
|
+
Returns
|
|
365
|
+
-------
|
|
394
366
|
wake_deltas: dict
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
wake delta applies, values: numpy.ndarray with
|
|
398
|
-
shape (n_states, n_points, ...)
|
|
367
|
+
Key: variable name, value: The zero filled
|
|
368
|
+
wake deltas, shape: (n_states, n_turbines, n_rpoints, ...)
|
|
399
369
|
|
|
400
370
|
"""
|
|
401
|
-
|
|
402
|
-
wake_deltas[FV.WS] = np.zeros((n_states, pdata.n_points), dtype=FC.DTYPE)
|
|
403
|
-
|
|
404
|
-
# find TI wake models:
|
|
371
|
+
# find TI wake model:
|
|
405
372
|
self._tiwakes = []
|
|
406
|
-
for w in algo.wake_models:
|
|
373
|
+
for w in algo.wake_models.values():
|
|
407
374
|
if w is not self:
|
|
408
|
-
wdel =
|
|
409
|
-
w.init_wake_deltas(algo, mdata, fdata, pdata, wdel)
|
|
375
|
+
wdel = w.new_wake_deltas(algo, mdata, fdata, tdata)
|
|
410
376
|
if self.ti_var in wdel:
|
|
411
377
|
self._tiwakes.append(w)
|
|
412
378
|
if self.ti_var not in FV.amb2var and len(self._tiwakes) == 0:
|
|
@@ -414,13 +380,15 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
414
380
|
f"Model '{self.name}': Missing wake model that computes wake delta for variable {self.ti_var}"
|
|
415
381
|
)
|
|
416
382
|
|
|
417
|
-
|
|
383
|
+
return super().new_wake_deltas(algo, mdata, fdata, tdata)
|
|
384
|
+
|
|
385
|
+
def calc_amplitude_sigma(
|
|
418
386
|
self,
|
|
419
387
|
algo,
|
|
420
388
|
mdata,
|
|
421
389
|
fdata,
|
|
422
|
-
|
|
423
|
-
|
|
390
|
+
tdata,
|
|
391
|
+
downwind_index,
|
|
424
392
|
x,
|
|
425
393
|
):
|
|
426
394
|
"""
|
|
@@ -431,60 +399,57 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
431
399
|
----------
|
|
432
400
|
algo: foxes.core.Algorithm
|
|
433
401
|
The calculation algorithm
|
|
434
|
-
mdata: foxes.core.
|
|
402
|
+
mdata: foxes.core.MData
|
|
435
403
|
The model data
|
|
436
|
-
fdata: foxes.core.
|
|
404
|
+
fdata: foxes.core.FData
|
|
437
405
|
The farm data
|
|
438
|
-
|
|
439
|
-
The
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
wake causing turbine. Shape: (n_states,)
|
|
406
|
+
tdata: foxes.core.TData
|
|
407
|
+
The target point data
|
|
408
|
+
downwind_index: int
|
|
409
|
+
The index in the downwind order
|
|
443
410
|
x: numpy.ndarray
|
|
444
|
-
The x values, shape: (n_states,
|
|
411
|
+
The x values, shape: (n_states, n_targets)
|
|
445
412
|
|
|
446
413
|
Returns
|
|
447
414
|
-------
|
|
448
415
|
amsi: tuple
|
|
449
416
|
The amplitude and sigma, both numpy.ndarray
|
|
450
|
-
with shape (
|
|
451
|
-
|
|
452
|
-
The state-
|
|
453
|
-
is non-zero, shape: (n_states,
|
|
417
|
+
with shape (n_st_sel,)
|
|
418
|
+
st_sel: numpy.ndarray of bool
|
|
419
|
+
The state-target selection, for which the wake
|
|
420
|
+
is non-zero, shape: (n_states, n_targets)
|
|
454
421
|
|
|
455
422
|
"""
|
|
456
|
-
|
|
457
423
|
# get ct:
|
|
458
424
|
ct = self.get_data(
|
|
459
425
|
FV.CT,
|
|
460
|
-
FC.
|
|
426
|
+
FC.STATE_TARGET,
|
|
461
427
|
lookup="w",
|
|
462
428
|
algo=algo,
|
|
463
429
|
fdata=fdata,
|
|
464
|
-
|
|
430
|
+
tdata=tdata,
|
|
431
|
+
downwind_index=downwind_index,
|
|
465
432
|
upcast=True,
|
|
466
|
-
states_source_turbine=states_source_turbine,
|
|
467
433
|
)
|
|
468
434
|
|
|
469
435
|
# select targets:
|
|
470
|
-
|
|
471
|
-
if np.any(
|
|
436
|
+
st_sel = (x > 1e-5) & (ct > 0.0)
|
|
437
|
+
if np.any(st_sel):
|
|
472
438
|
# apply selection:
|
|
473
|
-
# x = x[
|
|
474
|
-
ct = ct[
|
|
439
|
+
# x = x[st_sel]
|
|
440
|
+
ct = ct[st_sel]
|
|
475
441
|
|
|
476
442
|
# get D:
|
|
477
443
|
D = self.get_data(
|
|
478
444
|
FV.D,
|
|
479
|
-
FC.
|
|
445
|
+
FC.STATE_TARGET,
|
|
480
446
|
lookup="w",
|
|
481
447
|
algo=algo,
|
|
482
448
|
fdata=fdata,
|
|
483
|
-
|
|
449
|
+
tdata=tdata,
|
|
450
|
+
downwind_index=downwind_index,
|
|
484
451
|
upcast=True,
|
|
485
|
-
|
|
486
|
-
)
|
|
487
|
-
D = D[sp_sel]
|
|
452
|
+
)[st_sel]
|
|
488
453
|
|
|
489
454
|
# calculate sigma:
|
|
490
455
|
# beta = np.sqrt(0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct))
|
|
@@ -498,7 +463,7 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
498
463
|
algo,
|
|
499
464
|
mdata,
|
|
500
465
|
fdata,
|
|
501
|
-
|
|
466
|
+
downwind_index,
|
|
502
467
|
[self.ti_var],
|
|
503
468
|
x,
|
|
504
469
|
dx=self.dx,
|
|
@@ -508,13 +473,8 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
508
473
|
)[:, :, 0]
|
|
509
474
|
|
|
510
475
|
# calculate sigma (eqn 1, plus epsilon from eqn 4 for x = 0)
|
|
511
|
-
sigma = D * epsilon + self.A * ti_ix[
|
|
512
|
-
|
|
513
|
-
del (
|
|
514
|
-
x,
|
|
515
|
-
sbeta,
|
|
516
|
-
epsilon,
|
|
517
|
-
)
|
|
476
|
+
sigma = D * epsilon + self.A * ti_ix[st_sel]
|
|
477
|
+
del x, epsilon
|
|
518
478
|
|
|
519
479
|
# calculate amplitude, same as in Bastankhah model (eqn 7)
|
|
520
480
|
ct_eff = ct / (8 * (sigma / D) ** 2)
|
|
@@ -522,12 +482,12 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
522
482
|
|
|
523
483
|
# case no targets:
|
|
524
484
|
else:
|
|
525
|
-
|
|
526
|
-
n_sp = np.sum(
|
|
485
|
+
st_sel = np.zeros_like(x, dtype=bool)
|
|
486
|
+
n_sp = np.sum(st_sel)
|
|
527
487
|
ampld = np.zeros(n_sp, dtype=FC.DTYPE)
|
|
528
488
|
sigma = np.zeros(n_sp, dtype=FC.DTYPE)
|
|
529
489
|
|
|
530
|
-
return {FV.WS: (ampld, sigma)},
|
|
490
|
+
return {FV.WS: (ampld, sigma)}, st_sel
|
|
531
491
|
|
|
532
492
|
def finalize(self, algo, verbosity=0):
|
|
533
493
|
"""
|
|
@@ -32,48 +32,54 @@ class TILinear(WakeSuperposition):
|
|
|
32
32
|
super().__init__()
|
|
33
33
|
self.superp_to_amb = superp_to_amb
|
|
34
34
|
|
|
35
|
-
def
|
|
35
|
+
def __repr__(self):
|
|
36
|
+
return f"{type(self).__name__}(superp_to_amb={self.superp_to_amb})"
|
|
37
|
+
|
|
38
|
+
def add_wake(
|
|
36
39
|
self,
|
|
37
40
|
algo,
|
|
38
41
|
mdata,
|
|
39
42
|
fdata,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
tdata,
|
|
44
|
+
downwind_index,
|
|
45
|
+
st_sel,
|
|
43
46
|
variable,
|
|
44
47
|
wake_delta,
|
|
45
48
|
wake_model_result,
|
|
46
49
|
):
|
|
47
50
|
"""
|
|
48
|
-
Add a wake delta to previous wake deltas
|
|
51
|
+
Add a wake delta to previous wake deltas,
|
|
52
|
+
at rotor points.
|
|
49
53
|
|
|
50
54
|
Parameters
|
|
51
55
|
----------
|
|
52
56
|
algo: foxes.core.Algorithm
|
|
53
57
|
The calculation algorithm
|
|
54
|
-
mdata: foxes.core.
|
|
58
|
+
mdata: foxes.core.MData
|
|
55
59
|
The model data
|
|
56
|
-
fdata: foxes.core.
|
|
60
|
+
fdata: foxes.core.FData
|
|
57
61
|
The farm data
|
|
58
|
-
|
|
59
|
-
The
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
The selection of
|
|
62
|
+
tdata: foxes.core.TData
|
|
63
|
+
The target point data
|
|
64
|
+
downwind_index: int
|
|
65
|
+
The index of the wake causing turbine
|
|
66
|
+
in the downwnd order
|
|
67
|
+
st_sel: numpy.ndarray of bool
|
|
68
|
+
The selection of targets, shape: (n_states, n_targets)
|
|
65
69
|
variable: str
|
|
66
70
|
The variable name for which the wake deltas applies
|
|
67
71
|
wake_delta: numpy.ndarray
|
|
68
|
-
The original wake deltas, shape:
|
|
72
|
+
The original wake deltas, shape:
|
|
73
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
69
74
|
wake_model_result: numpy.ndarray
|
|
70
|
-
The new wake deltas of the selected
|
|
71
|
-
shape: (
|
|
75
|
+
The new wake deltas of the selected rotors,
|
|
76
|
+
shape: (n_st_sel, n_tpoints, ...)
|
|
72
77
|
|
|
73
78
|
Returns
|
|
74
79
|
-------
|
|
75
80
|
wdelta: numpy.ndarray
|
|
76
|
-
The updated wake deltas, shape:
|
|
81
|
+
The updated wake deltas, shape:
|
|
82
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
77
83
|
|
|
78
84
|
"""
|
|
79
85
|
if variable != FV.TI:
|
|
@@ -81,7 +87,7 @@ class TILinear(WakeSuperposition):
|
|
|
81
87
|
f"Superposition '{self.name}': Expecting wake variable {FV.TI}, got {variable}"
|
|
82
88
|
)
|
|
83
89
|
|
|
84
|
-
wake_delta[
|
|
90
|
+
wake_delta[st_sel] += wake_model_result
|
|
85
91
|
return wake_delta
|
|
86
92
|
|
|
87
93
|
def calc_final_wake_delta(
|
|
@@ -89,7 +95,6 @@ class TILinear(WakeSuperposition):
|
|
|
89
95
|
algo,
|
|
90
96
|
mdata,
|
|
91
97
|
fdata,
|
|
92
|
-
pdata,
|
|
93
98
|
variable,
|
|
94
99
|
amb_results,
|
|
95
100
|
wake_delta,
|
|
@@ -102,24 +107,25 @@ class TILinear(WakeSuperposition):
|
|
|
102
107
|
----------
|
|
103
108
|
algo: foxes.core.Algorithm
|
|
104
109
|
The calculation algorithm
|
|
105
|
-
mdata: foxes.core.
|
|
110
|
+
mdata: foxes.core.MData
|
|
106
111
|
The model data
|
|
107
|
-
fdata: foxes.core.
|
|
112
|
+
fdata: foxes.core.FData
|
|
108
113
|
The farm data
|
|
109
|
-
pdata: foxes.core.Data
|
|
110
|
-
The evaluation point data
|
|
111
114
|
variable: str
|
|
112
115
|
The variable name for which the wake deltas applies
|
|
113
116
|
amb_results: numpy.ndarray
|
|
114
|
-
The ambient results
|
|
117
|
+
The ambient results at targets,
|
|
118
|
+
shape: (n_states, n_targets, n_tpoints)
|
|
115
119
|
wake_delta: numpy.ndarray
|
|
116
|
-
The wake deltas, shape:
|
|
120
|
+
The wake deltas at targets, shape:
|
|
121
|
+
(n_states, n_targets, n_tpoints)
|
|
117
122
|
|
|
118
123
|
Returns
|
|
119
124
|
-------
|
|
120
125
|
final_wake_delta: numpy.ndarray
|
|
121
126
|
The final wake delta, which will be added to the ambient
|
|
122
|
-
results by simple plus operation. Shape:
|
|
127
|
+
results by simple plus operation. Shape:
|
|
128
|
+
(n_states, n_targets, n_tpoints)
|
|
123
129
|
|
|
124
130
|
"""
|
|
125
131
|
# linear superposition to ambient:
|
|
@@ -32,48 +32,54 @@ class TIMax(WakeSuperposition):
|
|
|
32
32
|
super().__init__()
|
|
33
33
|
self.superp_to_amb = superp_to_amb
|
|
34
34
|
|
|
35
|
-
def
|
|
35
|
+
def __repr__(self):
|
|
36
|
+
return f"{type(self).__name__}(superp_to_amb={self.superp_to_amb})"
|
|
37
|
+
|
|
38
|
+
def add_wake(
|
|
36
39
|
self,
|
|
37
40
|
algo,
|
|
38
41
|
mdata,
|
|
39
42
|
fdata,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
tdata,
|
|
44
|
+
downwind_index,
|
|
45
|
+
st_sel,
|
|
43
46
|
variable,
|
|
44
47
|
wake_delta,
|
|
45
48
|
wake_model_result,
|
|
46
49
|
):
|
|
47
50
|
"""
|
|
48
|
-
Add a wake delta to previous wake deltas
|
|
51
|
+
Add a wake delta to previous wake deltas,
|
|
52
|
+
at rotor points.
|
|
49
53
|
|
|
50
54
|
Parameters
|
|
51
55
|
----------
|
|
52
56
|
algo: foxes.core.Algorithm
|
|
53
57
|
The calculation algorithm
|
|
54
|
-
mdata: foxes.core.
|
|
58
|
+
mdata: foxes.core.MData
|
|
55
59
|
The model data
|
|
56
|
-
fdata: foxes.core.
|
|
60
|
+
fdata: foxes.core.FData
|
|
57
61
|
The farm data
|
|
58
|
-
|
|
59
|
-
The
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
The selection of
|
|
62
|
+
tdata: foxes.core.TData
|
|
63
|
+
The target point data
|
|
64
|
+
downwind_index: int
|
|
65
|
+
The index of the wake causing turbine
|
|
66
|
+
in the downwnd order
|
|
67
|
+
st_sel: numpy.ndarray of bool
|
|
68
|
+
The selection of targets, shape: (n_states, n_targets)
|
|
65
69
|
variable: str
|
|
66
70
|
The variable name for which the wake deltas applies
|
|
67
71
|
wake_delta: numpy.ndarray
|
|
68
|
-
The original wake deltas, shape:
|
|
72
|
+
The original wake deltas, shape:
|
|
73
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
69
74
|
wake_model_result: numpy.ndarray
|
|
70
|
-
The new wake deltas of the selected
|
|
71
|
-
shape: (
|
|
75
|
+
The new wake deltas of the selected rotors,
|
|
76
|
+
shape: (n_st_sel, n_tpoints, ...)
|
|
72
77
|
|
|
73
78
|
Returns
|
|
74
79
|
-------
|
|
75
80
|
wdelta: numpy.ndarray
|
|
76
|
-
The updated wake deltas, shape:
|
|
81
|
+
The updated wake deltas, shape:
|
|
82
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
77
83
|
|
|
78
84
|
"""
|
|
79
85
|
if variable != FV.TI:
|
|
@@ -81,7 +87,7 @@ class TIMax(WakeSuperposition):
|
|
|
81
87
|
f"Superposition '{self.name}': Expecting wake variable {FV.TI}, got {variable}"
|
|
82
88
|
)
|
|
83
89
|
|
|
84
|
-
wake_delta[
|
|
90
|
+
wake_delta[st_sel] = np.maximum(wake_model_result, wake_delta[st_sel])
|
|
85
91
|
return wake_delta
|
|
86
92
|
|
|
87
93
|
def calc_final_wake_delta(
|
|
@@ -89,7 +95,6 @@ class TIMax(WakeSuperposition):
|
|
|
89
95
|
algo,
|
|
90
96
|
mdata,
|
|
91
97
|
fdata,
|
|
92
|
-
pdata,
|
|
93
98
|
variable,
|
|
94
99
|
amb_results,
|
|
95
100
|
wake_delta,
|
|
@@ -102,24 +107,25 @@ class TIMax(WakeSuperposition):
|
|
|
102
107
|
----------
|
|
103
108
|
algo: foxes.core.Algorithm
|
|
104
109
|
The calculation algorithm
|
|
105
|
-
mdata: foxes.core.
|
|
110
|
+
mdata: foxes.core.MData
|
|
106
111
|
The model data
|
|
107
|
-
fdata: foxes.core.
|
|
112
|
+
fdata: foxes.core.FData
|
|
108
113
|
The farm data
|
|
109
|
-
pdata: foxes.core.Data
|
|
110
|
-
The evaluation point data
|
|
111
114
|
variable: str
|
|
112
115
|
The variable name for which the wake deltas applies
|
|
113
116
|
amb_results: numpy.ndarray
|
|
114
|
-
The ambient results
|
|
117
|
+
The ambient results at targets,
|
|
118
|
+
shape: (n_states, n_targets, n_tpoints)
|
|
115
119
|
wake_delta: numpy.ndarray
|
|
116
|
-
The wake deltas, shape:
|
|
120
|
+
The wake deltas at targets, shape:
|
|
121
|
+
(n_states, n_targets, n_tpoints)
|
|
117
122
|
|
|
118
123
|
Returns
|
|
119
124
|
-------
|
|
120
125
|
final_wake_delta: numpy.ndarray
|
|
121
126
|
The final wake delta, which will be added to the ambient
|
|
122
|
-
results by simple plus operation. Shape:
|
|
127
|
+
results by simple plus operation. Shape:
|
|
128
|
+
(n_states, n_targets, n_tpoints)
|
|
123
129
|
|
|
124
130
|
"""
|
|
125
131
|
# linear superposition to ambient:
|