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,11 +1,11 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
|
-
from foxes.core import
|
|
3
|
+
from foxes.core import TurbineInductionModel
|
|
4
4
|
import foxes.variables as FV
|
|
5
5
|
import foxes.constants as FC
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class Rathmann(
|
|
8
|
+
class Rathmann(TurbineInductionModel):
|
|
9
9
|
"""
|
|
10
10
|
The Rathmann induction wake model
|
|
11
11
|
|
|
@@ -47,6 +47,12 @@ class Rathmann(WakeModel):
|
|
|
47
47
|
self.induction = induction
|
|
48
48
|
self.pre_rotor_only = pre_rotor_only
|
|
49
49
|
|
|
50
|
+
def __repr__(self):
|
|
51
|
+
iname = (
|
|
52
|
+
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
53
|
+
)
|
|
54
|
+
return f"{type(self).__name__}(induction={iname})"
|
|
55
|
+
|
|
50
56
|
def sub_models(self):
|
|
51
57
|
"""
|
|
52
58
|
List of all sub-models
|
|
@@ -77,116 +83,105 @@ class Rathmann(WakeModel):
|
|
|
77
83
|
self.induction = algo.mbook.axial_induction[self.induction]
|
|
78
84
|
super().initialize(algo, verbosity, force)
|
|
79
85
|
|
|
80
|
-
def
|
|
86
|
+
def new_wake_deltas(self, algo, mdata, fdata, tdata):
|
|
81
87
|
"""
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
They are added on the fly to the wake_deltas dict.
|
|
88
|
+
Creates new empty wake delta arrays.
|
|
85
89
|
|
|
86
90
|
Parameters
|
|
87
91
|
----------
|
|
88
92
|
algo: foxes.core.Algorithm
|
|
89
93
|
The calculation algorithm
|
|
90
|
-
mdata: foxes.core.
|
|
94
|
+
mdata: foxes.core.MData
|
|
91
95
|
The model data
|
|
92
|
-
fdata: foxes.core.
|
|
96
|
+
fdata: foxes.core.FData
|
|
93
97
|
The farm data
|
|
94
|
-
|
|
95
|
-
The
|
|
98
|
+
tdata: foxes.core.TData
|
|
99
|
+
The target point data
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
96
103
|
wake_deltas: dict
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
wake delta applies, values: numpy.ndarray with
|
|
100
|
-
shape (n_states, n_points, ...)
|
|
104
|
+
Key: variable name, value: The zero filled
|
|
105
|
+
wake deltas, shape: (n_states, n_turbines, n_rpoints, ...)
|
|
101
106
|
|
|
102
107
|
"""
|
|
103
|
-
|
|
104
|
-
n_points = pdata.n_points
|
|
105
|
-
wake_deltas[FV.WS] = np.zeros((n_states, n_points), dtype=FC.DTYPE)
|
|
108
|
+
return {FV.WS: np.zeros_like(tdata[FC.TARGETS][..., 0])}
|
|
106
109
|
|
|
107
|
-
def
|
|
110
|
+
def contribute(
|
|
108
111
|
self,
|
|
109
112
|
algo,
|
|
110
113
|
mdata,
|
|
111
114
|
fdata,
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
tdata,
|
|
116
|
+
downwind_index,
|
|
114
117
|
wake_coos,
|
|
115
118
|
wake_deltas,
|
|
116
119
|
):
|
|
117
120
|
"""
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
Modifies wake_deltas on the fly.
|
|
121
|
+
Modifies wake deltas at target points by
|
|
122
|
+
contributions from the specified wake source turbines.
|
|
122
123
|
|
|
123
124
|
Parameters
|
|
124
125
|
----------
|
|
125
126
|
algo: foxes.core.Algorithm
|
|
126
127
|
The calculation algorithm
|
|
127
|
-
mdata: foxes.core.
|
|
128
|
+
mdata: foxes.core.MData
|
|
128
129
|
The model data
|
|
129
|
-
fdata: foxes.core.
|
|
130
|
+
fdata: foxes.core.FData
|
|
130
131
|
The farm data
|
|
131
|
-
|
|
132
|
-
The
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
tdata: foxes.core.TData
|
|
133
|
+
The target point data
|
|
134
|
+
downwind_index: int
|
|
135
|
+
The index of the wake causing turbine
|
|
136
|
+
in the downwnd order
|
|
136
137
|
wake_coos: numpy.ndarray
|
|
137
138
|
The wake frame coordinates of the evaluation
|
|
138
|
-
points, shape: (n_states,
|
|
139
|
+
points, shape: (n_states, n_targets, n_tpoints, 3)
|
|
139
140
|
wake_deltas: dict
|
|
140
|
-
The wake deltas
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
shape (n_states, n_points, ...)
|
|
141
|
+
The wake deltas. Key: variable name,
|
|
142
|
+
value: numpy.ndarray with shape
|
|
143
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
144
144
|
|
|
145
145
|
"""
|
|
146
|
-
|
|
147
|
-
# get x, y and z
|
|
148
|
-
x = wake_coos[:, :, 0]
|
|
149
|
-
y = wake_coos[:, :, 1]
|
|
150
|
-
z = wake_coos[:, :, 2]
|
|
151
|
-
|
|
152
146
|
# get ct:
|
|
153
147
|
ct = self.get_data(
|
|
154
148
|
FV.CT,
|
|
155
|
-
FC.
|
|
149
|
+
FC.STATE_TARGET_TPOINT,
|
|
156
150
|
lookup="w",
|
|
157
151
|
algo=algo,
|
|
158
152
|
fdata=fdata,
|
|
159
|
-
|
|
153
|
+
tdata=tdata,
|
|
160
154
|
upcast=True,
|
|
161
|
-
|
|
155
|
+
downwind_index=downwind_index,
|
|
162
156
|
)
|
|
163
157
|
|
|
164
158
|
# get ws:
|
|
165
159
|
ws = self.get_data(
|
|
166
160
|
FV.REWS,
|
|
167
|
-
FC.
|
|
161
|
+
FC.STATE_TARGET_TPOINT,
|
|
168
162
|
lookup="w",
|
|
169
163
|
algo=algo,
|
|
170
164
|
fdata=fdata,
|
|
171
|
-
|
|
165
|
+
tdata=tdata,
|
|
172
166
|
upcast=True,
|
|
173
|
-
|
|
167
|
+
downwind_index=downwind_index,
|
|
174
168
|
)
|
|
175
169
|
|
|
176
170
|
# get D
|
|
177
|
-
|
|
171
|
+
R = 0.5 * self.get_data(
|
|
178
172
|
FV.D,
|
|
179
|
-
FC.
|
|
173
|
+
FC.STATE_TARGET_TPOINT,
|
|
180
174
|
lookup="w",
|
|
181
175
|
algo=algo,
|
|
182
176
|
fdata=fdata,
|
|
183
|
-
|
|
184
|
-
upcast=
|
|
185
|
-
|
|
177
|
+
tdata=tdata,
|
|
178
|
+
upcast=False,
|
|
179
|
+
downwind_index=downwind_index,
|
|
186
180
|
)
|
|
187
181
|
|
|
188
|
-
|
|
189
|
-
|
|
182
|
+
# get x, r and R etc. Rounding for safe x < 0 condition below
|
|
183
|
+
x_R = np.round(wake_coos[..., 0] / R, 12)
|
|
184
|
+
r_R = np.linalg.norm(wake_coos[..., 1:3], axis=-1) / R
|
|
190
185
|
|
|
191
186
|
def mu(x_R):
|
|
192
187
|
"""axial shape function at r=0 from vortex cylinder model (eqn 11)"""
|
|
@@ -204,23 +199,21 @@ class Rathmann(WakeModel):
|
|
|
204
199
|
return sin_alpha * sin_beta * (1 + x_R**2)
|
|
205
200
|
|
|
206
201
|
# ws delta in front of rotor
|
|
207
|
-
sp_sel = (ct > 0) & (
|
|
202
|
+
sp_sel = (ct > 0) & (x_R <= 0)
|
|
208
203
|
if np.any(sp_sel):
|
|
204
|
+
xr = x_R[sp_sel]
|
|
209
205
|
a = self.induction.ct2a(ct[sp_sel])
|
|
210
|
-
blockage = (
|
|
211
|
-
ws[sp_sel] * a * mu(x_R[sp_sel]) * G(x_R[sp_sel], r_R[sp_sel])
|
|
212
|
-
) # eqn 10
|
|
206
|
+
blockage = ws[sp_sel] * a * mu(xr) * G(xr, r_R[sp_sel]) # eqn 10
|
|
213
207
|
wake_deltas[FV.WS][sp_sel] += -blockage
|
|
214
208
|
|
|
215
209
|
# ws delta behind rotor
|
|
216
210
|
if not self.pre_rotor_only:
|
|
217
211
|
# mirror -blockage in rotor plane
|
|
218
|
-
sp_sel = (ct > 0) & (
|
|
212
|
+
sp_sel = (ct > 0) & (x_R > 0) & (r_R > 1)
|
|
219
213
|
if np.any(sp_sel):
|
|
214
|
+
xr = x_R[sp_sel]
|
|
220
215
|
a = self.induction.ct2a(ct[sp_sel])
|
|
221
|
-
blockage = (
|
|
222
|
-
ws[sp_sel] * a * mu(-x_R[sp_sel]) * G(-x_R[sp_sel], r_R[sp_sel])
|
|
223
|
-
) # eqn 10
|
|
216
|
+
blockage = ws[sp_sel] * a * mu(-xr) * G(-xr, r_R[sp_sel]) # eqn 10
|
|
224
217
|
wake_deltas[FV.WS][sp_sel] += blockage
|
|
225
218
|
|
|
226
219
|
return wake_deltas
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
|
-
from foxes.core import
|
|
3
|
+
from foxes.core import TurbineInductionModel
|
|
4
4
|
import foxes.variables as FV
|
|
5
5
|
import foxes.constants as FC
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class SelfSimilar(
|
|
8
|
+
class SelfSimilar(TurbineInductionModel):
|
|
9
9
|
"""
|
|
10
10
|
The self-similar induction wake model
|
|
11
11
|
from Troldborg and Meyer Forsting
|
|
@@ -38,7 +38,7 @@ class SelfSimilar(WakeModel):
|
|
|
38
38
|
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
def __init__(self, pre_rotor_only=False, induction="Madsen"):
|
|
41
|
+
def __init__(self, pre_rotor_only=False, induction="Madsen", gamma=1.1):
|
|
42
42
|
"""
|
|
43
43
|
Constructor.
|
|
44
44
|
|
|
@@ -48,11 +48,20 @@ class SelfSimilar(WakeModel):
|
|
|
48
48
|
Calculate only the pre-rotor region
|
|
49
49
|
induction: foxes.core.AxialInductionModel or str
|
|
50
50
|
The induction model
|
|
51
|
+
gamma: float, default=1.1
|
|
52
|
+
The parameter that multiplies Ct in the ct2a calculation
|
|
51
53
|
|
|
52
54
|
"""
|
|
53
55
|
super().__init__()
|
|
54
56
|
self.induction = induction
|
|
55
57
|
self.pre_rotor_only = pre_rotor_only
|
|
58
|
+
self.gamma = gamma
|
|
59
|
+
|
|
60
|
+
def __repr__(self):
|
|
61
|
+
iname = (
|
|
62
|
+
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
63
|
+
)
|
|
64
|
+
return f"{type(self).__name__}(gamma={self.gamma}, induction={iname})"
|
|
56
65
|
|
|
57
66
|
def sub_models(self):
|
|
58
67
|
"""
|
|
@@ -84,40 +93,37 @@ class SelfSimilar(WakeModel):
|
|
|
84
93
|
self.induction = algo.mbook.axial_induction[self.induction]
|
|
85
94
|
super().initialize(algo, verbosity, force)
|
|
86
95
|
|
|
87
|
-
def
|
|
96
|
+
def new_wake_deltas(self, algo, mdata, fdata, tdata):
|
|
88
97
|
"""
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
They are added on the fly to the wake_deltas dict.
|
|
98
|
+
Creates new empty wake delta arrays.
|
|
92
99
|
|
|
93
100
|
Parameters
|
|
94
101
|
----------
|
|
95
102
|
algo: foxes.core.Algorithm
|
|
96
103
|
The calculation algorithm
|
|
97
|
-
mdata: foxes.core.
|
|
104
|
+
mdata: foxes.core.MData
|
|
98
105
|
The model data
|
|
99
|
-
fdata: foxes.core.
|
|
106
|
+
fdata: foxes.core.FData
|
|
100
107
|
The farm data
|
|
101
|
-
|
|
102
|
-
The
|
|
108
|
+
tdata: foxes.core.TData
|
|
109
|
+
The target point data
|
|
110
|
+
|
|
111
|
+
Returns
|
|
112
|
+
-------
|
|
103
113
|
wake_deltas: dict
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
wake delta applies, values: numpy.ndarray with
|
|
107
|
-
shape (n_states, n_points, ...)
|
|
114
|
+
Key: variable name, value: The zero filled
|
|
115
|
+
wake deltas, shape: (n_states, n_turbines, n_rpoints, ...)
|
|
108
116
|
|
|
109
117
|
"""
|
|
110
|
-
|
|
111
|
-
n_points = pdata.n_points
|
|
112
|
-
wake_deltas[FV.WS] = np.zeros((n_states, n_points), dtype=FC.DTYPE)
|
|
118
|
+
return {FV.WS: np.zeros_like(tdata[FC.TARGETS][..., 0])}
|
|
113
119
|
|
|
114
120
|
def _mu(self, x_R):
|
|
115
121
|
"""Helper function: define mu (eqn 11 from [1])"""
|
|
116
122
|
return 1 + (x_R / np.sqrt(1 + x_R**2))
|
|
117
123
|
|
|
118
|
-
def _a0(self, ct, x_R
|
|
124
|
+
def _a0(self, ct, x_R):
|
|
119
125
|
"""Helper function: define a0 with gamma factor, eqn 8 from [2]"""
|
|
120
|
-
return self.induction.ct2a(gamma * ct)
|
|
126
|
+
return self.induction.ct2a(self.gamma * ct)
|
|
121
127
|
|
|
122
128
|
def _a(self, ct, x_R):
|
|
123
129
|
"""Helper function: define axial shape function (eqn 11 from [1])"""
|
|
@@ -131,93 +137,84 @@ class SelfSimilar(WakeModel):
|
|
|
131
137
|
"""Helper function: define radial shape function (eqn 12 from [1])"""
|
|
132
138
|
return (1 / np.cosh(beta * (r_R) / self._r_half(x_R))) ** alpha # * (x_R < 0)
|
|
133
139
|
|
|
134
|
-
def
|
|
140
|
+
def contribute(
|
|
135
141
|
self,
|
|
136
142
|
algo,
|
|
137
143
|
mdata,
|
|
138
144
|
fdata,
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
tdata,
|
|
146
|
+
downwind_index,
|
|
141
147
|
wake_coos,
|
|
142
148
|
wake_deltas,
|
|
143
149
|
):
|
|
144
150
|
"""
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
Modifies wake_deltas on the fly.
|
|
151
|
+
Modifies wake deltas at target points by
|
|
152
|
+
contributions from the specified wake source turbines.
|
|
149
153
|
|
|
150
154
|
Parameters
|
|
151
155
|
----------
|
|
152
156
|
algo: foxes.core.Algorithm
|
|
153
157
|
The calculation algorithm
|
|
154
|
-
mdata: foxes.core.
|
|
158
|
+
mdata: foxes.core.MData
|
|
155
159
|
The model data
|
|
156
|
-
fdata: foxes.core.
|
|
160
|
+
fdata: foxes.core.FData
|
|
157
161
|
The farm data
|
|
158
|
-
|
|
159
|
-
The
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
tdata: foxes.core.TData
|
|
163
|
+
The target point data
|
|
164
|
+
downwind_index: int
|
|
165
|
+
The index of the wake causing turbine
|
|
166
|
+
in the downwnd order
|
|
163
167
|
wake_coos: numpy.ndarray
|
|
164
168
|
The wake frame coordinates of the evaluation
|
|
165
|
-
points, shape: (n_states,
|
|
169
|
+
points, shape: (n_states, n_targets, n_tpoints, 3)
|
|
166
170
|
wake_deltas: dict
|
|
167
|
-
The wake deltas
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
shape (n_states, n_points, ...)
|
|
171
|
+
The wake deltas. Key: variable name,
|
|
172
|
+
value: numpy.ndarray with shape
|
|
173
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
171
174
|
|
|
172
175
|
"""
|
|
173
|
-
|
|
174
176
|
# get ct
|
|
175
177
|
ct = self.get_data(
|
|
176
178
|
FV.CT,
|
|
177
|
-
FC.
|
|
179
|
+
FC.STATE_TARGET_TPOINT,
|
|
178
180
|
lookup="w",
|
|
179
181
|
algo=algo,
|
|
180
182
|
fdata=fdata,
|
|
181
|
-
|
|
183
|
+
tdata=tdata,
|
|
182
184
|
upcast=True,
|
|
183
|
-
|
|
185
|
+
downwind_index=downwind_index,
|
|
184
186
|
)
|
|
185
187
|
|
|
186
188
|
# get ws
|
|
187
189
|
ws = self.get_data(
|
|
188
190
|
FV.REWS,
|
|
189
|
-
FC.
|
|
191
|
+
FC.STATE_TARGET_TPOINT,
|
|
190
192
|
lookup="w",
|
|
191
193
|
algo=algo,
|
|
192
194
|
fdata=fdata,
|
|
193
|
-
|
|
195
|
+
tdata=tdata,
|
|
194
196
|
upcast=True,
|
|
195
|
-
|
|
197
|
+
downwind_index=downwind_index,
|
|
196
198
|
)
|
|
197
199
|
|
|
198
|
-
# get
|
|
199
|
-
|
|
200
|
+
# get R
|
|
201
|
+
R = 0.5 * self.get_data(
|
|
200
202
|
FV.D,
|
|
201
|
-
FC.
|
|
203
|
+
FC.STATE_TARGET_TPOINT,
|
|
202
204
|
lookup="w",
|
|
203
205
|
algo=algo,
|
|
204
206
|
fdata=fdata,
|
|
205
|
-
|
|
206
|
-
upcast=
|
|
207
|
-
|
|
207
|
+
tdata=tdata,
|
|
208
|
+
upcast=False,
|
|
209
|
+
downwind_index=downwind_index,
|
|
208
210
|
)
|
|
209
211
|
|
|
210
|
-
# get x, r and R etc
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
z = wake_coos[:, :, 2]
|
|
214
|
-
R = D / 2
|
|
215
|
-
x_R = x / R
|
|
216
|
-
r = np.sqrt(y**2 + z**2)
|
|
217
|
-
r_R = r / R
|
|
212
|
+
# get x, r and R etc. Rounding for safe x < 0 condition below
|
|
213
|
+
x_R = np.round(wake_coos[..., 0] / R, 12)
|
|
214
|
+
r_R = np.linalg.norm(wake_coos[..., 1:3], axis=-1) / R
|
|
218
215
|
|
|
219
216
|
# select values
|
|
220
|
-
sp_sel = (ct > 0) & (
|
|
217
|
+
sp_sel = (ct > 0) & (x_R <= 0) # upstream
|
|
221
218
|
if np.any(sp_sel):
|
|
222
219
|
# velocity eqn 10 from [1]
|
|
223
220
|
xr = x_R[sp_sel]
|
|
@@ -228,7 +225,7 @@ class SelfSimilar(WakeModel):
|
|
|
228
225
|
|
|
229
226
|
# set area behind to mirrored value EXCEPT for area behind turbine
|
|
230
227
|
if not self.pre_rotor_only:
|
|
231
|
-
sp_sel = (ct > 0) & (
|
|
228
|
+
sp_sel = (ct > 0) & (x_R > 0) & (r_R > 1)
|
|
232
229
|
if np.any(sp_sel):
|
|
233
230
|
# velocity eqn 10 from [1]
|
|
234
231
|
xr = x_R[sp_sel]
|