foxes 0.6.2__py3-none-any.whl → 0.7.0.2__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/from_random.py +10 -9
- foxes/input/states/create/random_timeseries.py +17 -19
- 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 +39 -14
- foxes/models/partial_wakes/__init__.py +2 -3
- foxes/models/partial_wakes/axiwake.py +73 -200
- foxes/models/partial_wakes/centre.py +11 -79
- 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/problems/layout/farm_layout.py +38 -97
- foxes/output/__init__.py +1 -0
- foxes/output/flow_plots_2d/flow_plots.py +2 -0
- 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 +1 -1
- foxes/utils/load.py +29 -0
- foxes/utils/random_xy.py +11 -10
- foxes/utils/runners/runners.py +3 -4
- foxes/utils/windrose_plot.py +1 -1
- foxes/variables.py +10 -0
- {foxes-0.6.2.dist-info → foxes-0.7.0.2.dist-info}/METADATA +13 -7
- {foxes-0.6.2.dist-info → foxes-0.7.0.2.dist-info}/RECORD +117 -117
- 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.2.dist-info → foxes-0.7.0.2.dist-info}/LICENSE +0 -0
- {foxes-0.6.2.dist-info → foxes-0.7.0.2.dist-info}/WHEEL +0 -0
- {foxes-0.6.2.dist-info → foxes-0.7.0.2.dist-info}/top_level.txt +0 -0
- {foxes-0.6.2.dist-info → foxes-0.7.0.2.dist-info}/zip-safe +0 -0
|
@@ -2,7 +2,7 @@ import numpy as np
|
|
|
2
2
|
|
|
3
3
|
from foxes.core import WakeFrame
|
|
4
4
|
from foxes.utils import wd2uv
|
|
5
|
-
from foxes.core.data import
|
|
5
|
+
from foxes.core.data import MData, FData, TData
|
|
6
6
|
import foxes.variables as FV
|
|
7
7
|
import foxes.constants as FC
|
|
8
8
|
|
|
@@ -47,6 +47,9 @@ class Timelines(WakeFrame):
|
|
|
47
47
|
self.cl_ipars = cl_ipars
|
|
48
48
|
self.dt_min = dt_min
|
|
49
49
|
|
|
50
|
+
def __repr__(self):
|
|
51
|
+
return f"{type(self).__name__}(dt_min={self.dt_min})"
|
|
52
|
+
|
|
50
53
|
def initialize(self, algo, verbosity=0):
|
|
51
54
|
"""
|
|
52
55
|
Initializes the model.
|
|
@@ -87,28 +90,30 @@ class Timelines(WakeFrame):
|
|
|
87
90
|
mdata = algo.get_model_data(algo.states)["data_vars"]
|
|
88
91
|
mdict = {v: d[1] for v, d in mdata.items()}
|
|
89
92
|
mdims = {v: d[0] for v, d in mdata.items()}
|
|
90
|
-
mdata =
|
|
93
|
+
mdata = MData(mdict, mdims, loop_dims=[FC.STATE])
|
|
91
94
|
del mdict, mdims
|
|
92
95
|
|
|
93
96
|
# prepare fdata:
|
|
94
|
-
fdata =
|
|
97
|
+
fdata = FData({}, {}, loop_dims=[FC.STATE])
|
|
95
98
|
|
|
96
|
-
# prepare
|
|
97
|
-
|
|
98
|
-
v: np.zeros((algo.n_states, 1), dtype=FC.DTYPE)
|
|
99
|
+
# prepare tdata:
|
|
100
|
+
tdata = {
|
|
101
|
+
v: np.zeros((algo.n_states, 1, 1), dtype=FC.DTYPE)
|
|
99
102
|
for v in algo.states.output_point_vars(algo)
|
|
100
103
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
pdims = {v: (FC.STATE, FC.TARGET, FC.TPOINT) for v in tdata.keys()}
|
|
105
|
+
tdata = TData.from_points(
|
|
106
|
+
points=np.zeros((algo.n_states, 1, 3), dtype=FC.DTYPE),
|
|
107
|
+
data=tdata,
|
|
108
|
+
dims=pdims,
|
|
109
|
+
)
|
|
105
110
|
|
|
106
111
|
# calculate:
|
|
107
|
-
res = algo.states.calculate(algo, mdata, fdata,
|
|
112
|
+
res = algo.states.calculate(algo, mdata, fdata, tdata)
|
|
108
113
|
if len(dt) == 1:
|
|
109
|
-
self._dxy = wd2uv(res[FV.WD], res[FV.WS])[:, 0, :2] * dt[:, None]
|
|
114
|
+
self._dxy = wd2uv(res[FV.WD], res[FV.WS])[:, 0, 0, :2] * dt[:, None]
|
|
110
115
|
else:
|
|
111
|
-
self._dxy = wd2uv(res[FV.WD], res[FV.WS])[:-1, 0, :2] * dt[:, None]
|
|
116
|
+
self._dxy = wd2uv(res[FV.WD], res[FV.WS])[:-1, 0, 0, :2] * dt[:, None]
|
|
112
117
|
self._dxy = np.insert(self._dxy, 0, self._dxy[0], axis=0)
|
|
113
118
|
|
|
114
119
|
""" DEBUG
|
|
@@ -131,9 +136,9 @@ class Timelines(WakeFrame):
|
|
|
131
136
|
----------
|
|
132
137
|
algo: foxes.core.Algorithm
|
|
133
138
|
The calculation algorithm
|
|
134
|
-
mdata: foxes.core.
|
|
139
|
+
mdata: foxes.core.MData
|
|
135
140
|
The model data
|
|
136
|
-
fdata: foxes.core.
|
|
141
|
+
fdata: foxes.core.FData
|
|
137
142
|
The farm data
|
|
138
143
|
|
|
139
144
|
Returns
|
|
@@ -142,19 +147,18 @@ class Timelines(WakeFrame):
|
|
|
142
147
|
The turbine order, shape: (n_states, n_turbines)
|
|
143
148
|
|
|
144
149
|
"""
|
|
145
|
-
|
|
146
150
|
# prepare:
|
|
147
151
|
n_states = fdata.n_states
|
|
148
152
|
n_turbines = algo.n_turbines
|
|
149
|
-
|
|
153
|
+
tdata = TData.from_points(points=fdata[FV.TXYH])
|
|
150
154
|
|
|
151
155
|
# calculate streamline x coordinates for turbines rotor centre points:
|
|
152
156
|
# n_states, n_turbines_source, n_turbines_target
|
|
153
157
|
coosx = np.zeros((n_states, n_turbines, n_turbines), dtype=FC.DTYPE)
|
|
154
158
|
for ti in range(n_turbines):
|
|
155
|
-
coosx[:, ti, :] = self.get_wake_coos(
|
|
156
|
-
|
|
157
|
-
|
|
159
|
+
coosx[:, ti, :] = self.get_wake_coos(algo, mdata, fdata, tdata, ti)[
|
|
160
|
+
:, :, 0, 0
|
|
161
|
+
]
|
|
158
162
|
|
|
159
163
|
# derive turbine order:
|
|
160
164
|
# TODO: Remove loop over states
|
|
@@ -164,41 +168,47 @@ class Timelines(WakeFrame):
|
|
|
164
168
|
|
|
165
169
|
return order
|
|
166
170
|
|
|
167
|
-
def get_wake_coos(
|
|
171
|
+
def get_wake_coos(
|
|
172
|
+
self,
|
|
173
|
+
algo,
|
|
174
|
+
mdata,
|
|
175
|
+
fdata,
|
|
176
|
+
tdata,
|
|
177
|
+
downwind_index,
|
|
178
|
+
):
|
|
168
179
|
"""
|
|
169
|
-
Calculate wake coordinates.
|
|
180
|
+
Calculate wake coordinates of rotor points.
|
|
170
181
|
|
|
171
182
|
Parameters
|
|
172
183
|
----------
|
|
173
184
|
algo: foxes.core.Algorithm
|
|
174
185
|
The calculation algorithm
|
|
175
|
-
mdata: foxes.core.
|
|
186
|
+
mdata: foxes.core.MData
|
|
176
187
|
The model data
|
|
177
|
-
fdata: foxes.core.
|
|
188
|
+
fdata: foxes.core.FData
|
|
178
189
|
The farm data
|
|
179
|
-
|
|
180
|
-
The
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
190
|
+
tdata: foxes.core.TData
|
|
191
|
+
The target point data
|
|
192
|
+
downwind_index: int
|
|
193
|
+
The index of the wake causing turbine
|
|
194
|
+
in the downwnd order
|
|
184
195
|
|
|
185
196
|
Returns
|
|
186
197
|
-------
|
|
187
198
|
wake_coos: numpy.ndarray
|
|
188
199
|
The wake frame coordinates of the evaluation
|
|
189
|
-
points, shape: (n_states,
|
|
200
|
+
points, shape: (n_states, n_targets, n_tpoints, 3)
|
|
190
201
|
|
|
191
202
|
"""
|
|
192
|
-
|
|
193
203
|
# prepare:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
rxyz = fdata[FV.TXYH][
|
|
204
|
+
targets = tdata[FC.TARGETS]
|
|
205
|
+
n_states, n_targets, n_tpoints = targets.shape[:3]
|
|
206
|
+
n_points = n_targets * n_tpoints
|
|
207
|
+
points = targets.reshape(n_states, n_points, 3)
|
|
208
|
+
rxyz = fdata[FV.TXYH][:, downwind_index]
|
|
199
209
|
|
|
200
210
|
D = np.zeros((n_states, n_points), dtype=FC.DTYPE)
|
|
201
|
-
D[:] = fdata[FV.D][
|
|
211
|
+
D[:] = fdata[FV.D][:, downwind_index, None]
|
|
202
212
|
|
|
203
213
|
i0 = mdata.states_i0(counter=True, algo=algo)
|
|
204
214
|
i1 = i0 + mdata.n_states
|
|
@@ -256,14 +266,18 @@ class Timelines(WakeFrame):
|
|
|
256
266
|
break
|
|
257
267
|
|
|
258
268
|
# turbines that cause wake:
|
|
259
|
-
|
|
269
|
+
tdata[FC.STATE_SOURCE_ORDERI] = downwind_index
|
|
260
270
|
|
|
261
271
|
# states that cause wake for each target point:
|
|
262
|
-
|
|
272
|
+
tdata.add(
|
|
273
|
+
FC.STATES_SEL,
|
|
274
|
+
trace_si.reshape(n_states, n_targets, n_tpoints),
|
|
275
|
+
(FC.STATE, FC.TARGET, FC.TPOINT),
|
|
276
|
+
)
|
|
263
277
|
|
|
264
|
-
return wcoos
|
|
278
|
+
return wcoos.reshape(n_states, n_targets, n_tpoints, 3)
|
|
265
279
|
|
|
266
|
-
def get_centreline_points(self, algo, mdata, fdata,
|
|
280
|
+
def get_centreline_points(self, algo, mdata, fdata, downwind_index, x):
|
|
267
281
|
"""
|
|
268
282
|
Gets the points along the centreline for given
|
|
269
283
|
values of x.
|
|
@@ -272,13 +286,12 @@ class Timelines(WakeFrame):
|
|
|
272
286
|
----------
|
|
273
287
|
algo: foxes.core.Algorithm
|
|
274
288
|
The calculation algorithm
|
|
275
|
-
mdata: foxes.core.
|
|
289
|
+
mdata: foxes.core.MData
|
|
276
290
|
The model data
|
|
277
|
-
fdata: foxes.core.
|
|
291
|
+
fdata: foxes.core.FData
|
|
278
292
|
The farm data
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
wake causing turbine. Shape: (n_states,)
|
|
293
|
+
downwind_index: int
|
|
294
|
+
The index in the downwind order
|
|
282
295
|
x: numpy.ndarray
|
|
283
296
|
The wake frame x coordinates, shape: (n_states, n_points)
|
|
284
297
|
|
|
@@ -288,5 +301,4 @@ class Timelines(WakeFrame):
|
|
|
288
301
|
The centreline points, shape: (n_states, n_points, 3)
|
|
289
302
|
|
|
290
303
|
"""
|
|
291
|
-
|
|
292
304
|
raise NotImplementedError
|
|
@@ -77,6 +77,16 @@ class YawedWakes(WakeFrame):
|
|
|
77
77
|
setattr(self, k_var, k)
|
|
78
78
|
setattr(self, FV.YAWM, 0.0)
|
|
79
79
|
|
|
80
|
+
def __repr__(self):
|
|
81
|
+
k = getattr(self, self.k_var)
|
|
82
|
+
s = f"{type(self).__name__}("
|
|
83
|
+
if k is None:
|
|
84
|
+
s += f"k_var={self.k_var}"
|
|
85
|
+
else:
|
|
86
|
+
s += f"{self.k_var}={k}"
|
|
87
|
+
s += ")"
|
|
88
|
+
return s
|
|
89
|
+
|
|
80
90
|
def sub_models(self):
|
|
81
91
|
"""
|
|
82
92
|
List of all sub-models
|
|
@@ -132,9 +142,9 @@ class YawedWakes(WakeFrame):
|
|
|
132
142
|
----------
|
|
133
143
|
algo: foxes.core.Algorithm
|
|
134
144
|
The calculation algorithm
|
|
135
|
-
mdata: foxes.core.
|
|
145
|
+
mdata: foxes.core.MData
|
|
136
146
|
The model data
|
|
137
|
-
fdata: foxes.core.
|
|
147
|
+
fdata: foxes.core.FData
|
|
138
148
|
The farm data
|
|
139
149
|
|
|
140
150
|
Returns
|
|
@@ -145,7 +155,7 @@ class YawedWakes(WakeFrame):
|
|
|
145
155
|
"""
|
|
146
156
|
return self.base_frame.calc_order(algo, mdata, fdata)
|
|
147
157
|
|
|
148
|
-
def _update_y(self, algo, mdata, fdata,
|
|
158
|
+
def _update_y(self, algo, mdata, fdata, tdata, downwind_index, x, y):
|
|
149
159
|
"""
|
|
150
160
|
Helper function for y deflection
|
|
151
161
|
"""
|
|
@@ -153,39 +163,39 @@ class YawedWakes(WakeFrame):
|
|
|
153
163
|
# get gamma:
|
|
154
164
|
gamma = self.get_data(
|
|
155
165
|
FV.YAWM,
|
|
156
|
-
FC.
|
|
166
|
+
FC.STATE_TARGET,
|
|
157
167
|
lookup="wfs",
|
|
158
168
|
algo=algo,
|
|
159
169
|
fdata=fdata,
|
|
160
|
-
|
|
170
|
+
tdata=tdata,
|
|
161
171
|
upcast=True,
|
|
162
|
-
|
|
172
|
+
downwind_index=downwind_index,
|
|
173
|
+
accept_nan=False,
|
|
163
174
|
)
|
|
164
175
|
gamma *= np.pi / 180
|
|
165
176
|
|
|
166
177
|
# get k:
|
|
167
178
|
k = self.get_data(
|
|
168
179
|
self.k_var,
|
|
169
|
-
FC.
|
|
180
|
+
FC.STATE_TARGET,
|
|
170
181
|
lookup="sf",
|
|
171
182
|
algo=algo,
|
|
172
183
|
fdata=fdata,
|
|
173
|
-
|
|
184
|
+
tdata=tdata,
|
|
174
185
|
upcast=True,
|
|
175
|
-
|
|
186
|
+
downwind_index=downwind_index,
|
|
187
|
+
accept_nan=False,
|
|
176
188
|
)
|
|
177
189
|
|
|
178
190
|
# run model calculation:
|
|
179
|
-
self.model.calc_data(
|
|
180
|
-
algo, mdata, fdata, pdata, states_source_turbine, x, gamma, k
|
|
181
|
-
)
|
|
191
|
+
self.model.calc_data(algo, mdata, fdata, tdata, downwind_index, x, gamma, k)
|
|
182
192
|
|
|
183
193
|
# select targets:
|
|
184
|
-
|
|
185
|
-
if np.any(
|
|
194
|
+
st_sel = self.model.get_data(Bastankhah2016Model.ST_SEL, mdata)
|
|
195
|
+
if np.any(st_sel):
|
|
186
196
|
# prepare:
|
|
187
|
-
|
|
188
|
-
ydef = np.zeros((
|
|
197
|
+
n_st_sel = np.sum(st_sel)
|
|
198
|
+
ydef = np.zeros((n_st_sel,), dtype=FC.DTYPE)
|
|
189
199
|
|
|
190
200
|
# collect data:
|
|
191
201
|
near = self.model.get_data(Bastankhah2016Model.NEAR, mdata)
|
|
@@ -208,47 +218,61 @@ class YawedWakes(WakeFrame):
|
|
|
208
218
|
ydef[far] = delta
|
|
209
219
|
|
|
210
220
|
# apply deflection:
|
|
211
|
-
y[
|
|
221
|
+
y[st_sel] -= ydef
|
|
212
222
|
|
|
213
|
-
def get_wake_coos(
|
|
223
|
+
def get_wake_coos(
|
|
224
|
+
self,
|
|
225
|
+
algo,
|
|
226
|
+
mdata,
|
|
227
|
+
fdata,
|
|
228
|
+
tdata,
|
|
229
|
+
downwind_index,
|
|
230
|
+
):
|
|
214
231
|
"""
|
|
215
|
-
Calculate wake coordinates.
|
|
232
|
+
Calculate wake coordinates of rotor points.
|
|
216
233
|
|
|
217
234
|
Parameters
|
|
218
235
|
----------
|
|
219
236
|
algo: foxes.core.Algorithm
|
|
220
237
|
The calculation algorithm
|
|
221
|
-
mdata: foxes.core.
|
|
238
|
+
mdata: foxes.core.MData
|
|
222
239
|
The model data
|
|
223
|
-
fdata: foxes.core.
|
|
240
|
+
fdata: foxes.core.FData
|
|
224
241
|
The farm data
|
|
225
|
-
|
|
226
|
-
The
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
242
|
+
tdata: foxes.core.TData
|
|
243
|
+
The target point data
|
|
244
|
+
downwind_index: int
|
|
245
|
+
The index of the wake causing turbine
|
|
246
|
+
in the downwnd order
|
|
230
247
|
|
|
231
248
|
Returns
|
|
232
249
|
-------
|
|
233
250
|
wake_coos: numpy.ndarray
|
|
234
251
|
The wake frame coordinates of the evaluation
|
|
235
|
-
points, shape: (n_states,
|
|
252
|
+
points, shape: (n_states, n_targets, n_tpoints, 3)
|
|
236
253
|
|
|
237
254
|
"""
|
|
238
|
-
|
|
239
255
|
# get unyawed results:
|
|
240
256
|
xyz = self.base_frame.get_wake_coos(
|
|
241
|
-
algo,
|
|
257
|
+
algo,
|
|
258
|
+
mdata,
|
|
259
|
+
fdata,
|
|
260
|
+
tdata,
|
|
261
|
+
downwind_index,
|
|
242
262
|
)
|
|
243
|
-
|
|
244
|
-
|
|
263
|
+
|
|
264
|
+
# take rotor average:
|
|
265
|
+
xy = np.einsum("stpd,p->std", xyz[..., :2], tdata[FC.TWEIGHTS])
|
|
266
|
+
x = xy[:, :, 0]
|
|
267
|
+
y = xy[:, :, 1]
|
|
245
268
|
|
|
246
269
|
# apply deflection:
|
|
247
|
-
self._update_y(algo, mdata, fdata,
|
|
270
|
+
self._update_y(algo, mdata, fdata, tdata, downwind_index, x, y)
|
|
271
|
+
xyz[..., 1] = y[:, :, None]
|
|
248
272
|
|
|
249
273
|
return xyz
|
|
250
274
|
|
|
251
|
-
def get_centreline_points(self, algo, mdata, fdata,
|
|
275
|
+
def get_centreline_points(self, algo, mdata, fdata, downwind_index, x):
|
|
252
276
|
"""
|
|
253
277
|
Gets the points along the centreline for given
|
|
254
278
|
values of x.
|
|
@@ -257,13 +281,12 @@ class YawedWakes(WakeFrame):
|
|
|
257
281
|
----------
|
|
258
282
|
algo: foxes.core.Algorithm
|
|
259
283
|
The calculation algorithm
|
|
260
|
-
mdata: foxes.core.
|
|
284
|
+
mdata: foxes.core.MData
|
|
261
285
|
The model data
|
|
262
|
-
fdata: foxes.core.
|
|
286
|
+
fdata: foxes.core.FData
|
|
263
287
|
The farm data
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
wake causing turbine. Shape: (n_states,)
|
|
288
|
+
downwind_index: int
|
|
289
|
+
The index in the downwind order
|
|
267
290
|
x: numpy.ndarray
|
|
268
291
|
The wake frame x coordinates, shape: (n_states, n_points)
|
|
269
292
|
|
|
@@ -274,7 +297,7 @@ class YawedWakes(WakeFrame):
|
|
|
274
297
|
|
|
275
298
|
"""
|
|
276
299
|
points = self.base_frame.get_centreline_points(
|
|
277
|
-
algo, mdata, fdata,
|
|
300
|
+
algo, mdata, fdata, downwind_index, x
|
|
278
301
|
)
|
|
279
302
|
|
|
280
303
|
nx = np.zeros_like(points)
|
|
@@ -291,7 +314,7 @@ class YawedWakes(WakeFrame):
|
|
|
291
314
|
del nx, nz
|
|
292
315
|
|
|
293
316
|
y = np.zeros_like(x)
|
|
294
|
-
self._update_y(algo, mdata, fdata, None,
|
|
317
|
+
self._update_y(algo, mdata, fdata, None, downwind_index, x, y)
|
|
295
318
|
|
|
296
319
|
points += y[:, :, None] * ny
|
|
297
320
|
|
|
@@ -17,13 +17,13 @@ class AxisymmetricWakeModel(DistSlicedWakeModel):
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
@abstractmethod
|
|
20
|
-
def
|
|
20
|
+
def calc_wakes_x_r(
|
|
21
21
|
self,
|
|
22
22
|
algo,
|
|
23
23
|
mdata,
|
|
24
24
|
fdata,
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
tdata,
|
|
26
|
+
downwind_index,
|
|
27
27
|
x,
|
|
28
28
|
r,
|
|
29
29
|
):
|
|
@@ -34,40 +34,39 @@ class AxisymmetricWakeModel(DistSlicedWakeModel):
|
|
|
34
34
|
----------
|
|
35
35
|
algo: foxes.core.Algorithm
|
|
36
36
|
The calculation algorithm
|
|
37
|
-
mdata: foxes.core.
|
|
37
|
+
mdata: foxes.core.MData
|
|
38
38
|
The model data
|
|
39
|
-
fdata: foxes.core.
|
|
39
|
+
fdata: foxes.core.FData
|
|
40
40
|
The farm data
|
|
41
|
-
|
|
42
|
-
The
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
wake causing turbine. Shape: (n_states,)
|
|
41
|
+
tdata: foxes.core.TData
|
|
42
|
+
The target point data
|
|
43
|
+
downwind_index: int
|
|
44
|
+
The index in the downwind order
|
|
46
45
|
x: numpy.ndarray
|
|
47
|
-
The x values, shape: (n_states,
|
|
46
|
+
The x values, shape: (n_states, n_targets)
|
|
48
47
|
r: numpy.ndarray
|
|
49
48
|
The radial values for each x value, shape:
|
|
50
|
-
(n_states,
|
|
49
|
+
(n_states, n_targets, n_yz_per_target)
|
|
51
50
|
|
|
52
51
|
Returns
|
|
53
52
|
-------
|
|
54
53
|
wdeltas: dict
|
|
55
54
|
The wake deltas. Key: variable name str,
|
|
56
|
-
value: numpy.ndarray, shape: (
|
|
57
|
-
|
|
58
|
-
The state-
|
|
59
|
-
is non-zero, shape: (n_states,
|
|
55
|
+
value: numpy.ndarray, shape: (n_st_sel, n_r_per_x)
|
|
56
|
+
st_sel: numpy.ndarray of bool
|
|
57
|
+
The state-target selection, for which the wake
|
|
58
|
+
is non-zero, shape: (n_states, n_targets)
|
|
60
59
|
|
|
61
60
|
"""
|
|
62
61
|
pass
|
|
63
62
|
|
|
64
|
-
def
|
|
63
|
+
def calc_wakes_x_yz(
|
|
65
64
|
self,
|
|
66
65
|
algo,
|
|
67
66
|
mdata,
|
|
68
67
|
fdata,
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
tdata,
|
|
69
|
+
downwind_index,
|
|
71
70
|
x,
|
|
72
71
|
yz,
|
|
73
72
|
):
|
|
@@ -78,32 +77,29 @@ class AxisymmetricWakeModel(DistSlicedWakeModel):
|
|
|
78
77
|
----------
|
|
79
78
|
algo: foxes.core.Algorithm
|
|
80
79
|
The calculation algorithm
|
|
81
|
-
mdata: foxes.core.
|
|
80
|
+
mdata: foxes.core.MData
|
|
82
81
|
The model data
|
|
83
|
-
fdata: foxes.core.
|
|
82
|
+
fdata: foxes.core.FData
|
|
84
83
|
The farm data
|
|
85
|
-
|
|
86
|
-
The
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
wake causing turbine. Shape: (n_states,)
|
|
84
|
+
tdata: foxes.core.TData
|
|
85
|
+
The target point data
|
|
86
|
+
downwind_index: int
|
|
87
|
+
The index in the downwind order
|
|
90
88
|
x: numpy.ndarray
|
|
91
|
-
The x values, shape: (n_states,
|
|
89
|
+
The x values, shape: (n_states, n_targets)
|
|
92
90
|
yz: numpy.ndarray
|
|
93
91
|
The yz values for each x value, shape:
|
|
94
|
-
(n_states,
|
|
92
|
+
(n_states, n_targets, n_yz_per_target, 2)
|
|
95
93
|
|
|
96
94
|
Returns
|
|
97
95
|
-------
|
|
98
96
|
wdeltas: dict
|
|
99
97
|
The wake deltas. Key: variable name str,
|
|
100
|
-
value: numpy.ndarray, shape: (
|
|
101
|
-
|
|
102
|
-
The state-
|
|
103
|
-
is non-zero, shape: (n_states,
|
|
98
|
+
value: numpy.ndarray, shape: (n_st_sel, n_yz_per_target)
|
|
99
|
+
st_sel: numpy.ndarray of bool
|
|
100
|
+
The state-target selection, for which the wake
|
|
101
|
+
is non-zero, shape: (n_states, n_targets)
|
|
104
102
|
|
|
105
103
|
"""
|
|
106
104
|
r = np.linalg.norm(yz, axis=-1)
|
|
107
|
-
return self.
|
|
108
|
-
algo, mdata, fdata, pdata, states_source_turbine, x, r
|
|
109
|
-
)
|
|
105
|
+
return self.calc_wakes_x_r(algo, mdata, fdata, tdata, downwind_index, x, r)
|