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,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from foxes.core import PartialWakesModel, Data
|
|
4
|
-
import foxes.constants as FC
|
|
1
|
+
from foxes.core import PartialWakesModel
|
|
5
2
|
|
|
6
3
|
|
|
7
4
|
class RotorPoints(PartialWakesModel):
|
|
@@ -13,180 +10,89 @@ class RotorPoints(PartialWakesModel):
|
|
|
13
10
|
|
|
14
11
|
"""
|
|
15
12
|
|
|
16
|
-
def __init__(self, wake_models=None, wake_frame=None):
|
|
17
|
-
"""
|
|
18
|
-
Constructor.
|
|
19
|
-
|
|
20
|
-
Parameters
|
|
21
|
-
----------
|
|
22
|
-
wake_models: list of foxes.core.WakeModel, optional
|
|
23
|
-
The wake models, default are the ones from the algorithm
|
|
24
|
-
wake_frame: foxes.core.WakeFrame, optional
|
|
25
|
-
The wake frame, default is the one from the algorithm
|
|
26
|
-
|
|
27
|
-
"""
|
|
28
|
-
super().__init__(wake_models, wake_frame)
|
|
29
|
-
|
|
30
13
|
def get_wake_points(self, algo, mdata, fdata):
|
|
31
14
|
"""
|
|
32
|
-
Get the wake calculation points
|
|
15
|
+
Get the wake calculation points, and their
|
|
16
|
+
weights.
|
|
33
17
|
|
|
34
18
|
Parameters
|
|
35
19
|
----------
|
|
36
20
|
algo: foxes.core.Algorithm
|
|
37
21
|
The calculation algorithm
|
|
38
|
-
mdata: foxes.core.
|
|
22
|
+
mdata: foxes.core.MData
|
|
39
23
|
The model data
|
|
40
|
-
fdata: foxes.core.
|
|
24
|
+
fdata: foxes.core.FData
|
|
41
25
|
The farm data
|
|
42
26
|
|
|
43
27
|
Returns
|
|
44
28
|
-------
|
|
45
29
|
rpoints: numpy.ndarray
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
n_states, n_turbines, n_rpoints, __ = rpoints.shape
|
|
51
|
-
return rpoints.reshape(n_states, n_turbines * n_rpoints, 3)
|
|
30
|
+
The wake calculation points, shape:
|
|
31
|
+
(n_states, n_turbines, n_tpoints, 3)
|
|
32
|
+
rweights: numpy.ndarray
|
|
33
|
+
The target point weights, shape: (n_tpoints,)
|
|
52
34
|
|
|
53
|
-
def new_wake_deltas(self, algo, mdata, fdata):
|
|
54
35
|
"""
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
----------
|
|
60
|
-
algo: foxes.core.Algorithm
|
|
61
|
-
The calculation algorithm
|
|
62
|
-
mdata: foxes.core.Data
|
|
63
|
-
The model data
|
|
64
|
-
fdata: foxes.core.Data
|
|
65
|
-
The farm data
|
|
66
|
-
|
|
67
|
-
Returns
|
|
68
|
-
-------
|
|
69
|
-
wake_deltas: dict
|
|
70
|
-
Keys: Variable name str, values: any
|
|
71
|
-
pdata: foxes.core.Data
|
|
72
|
-
The evaluation point data
|
|
73
|
-
|
|
74
|
-
"""
|
|
75
|
-
points = self.get_wake_points(algo, mdata, fdata)
|
|
76
|
-
pdata = Data.from_points(points=points)
|
|
77
|
-
|
|
78
|
-
wake_deltas = {}
|
|
79
|
-
for w in self.wake_models:
|
|
80
|
-
w.init_wake_deltas(algo, mdata, fdata, pdata, wake_deltas)
|
|
81
|
-
|
|
82
|
-
return wake_deltas, pdata
|
|
83
|
-
|
|
84
|
-
def contribute_to_wake_deltas(
|
|
85
|
-
self,
|
|
86
|
-
algo,
|
|
87
|
-
mdata,
|
|
88
|
-
fdata,
|
|
89
|
-
pdata,
|
|
90
|
-
states_source_turbine,
|
|
91
|
-
wake_deltas,
|
|
92
|
-
):
|
|
93
|
-
"""
|
|
94
|
-
Modifies wake deltas by contributions from the
|
|
95
|
-
specified wake source turbines.
|
|
96
|
-
|
|
97
|
-
Parameters
|
|
98
|
-
----------
|
|
99
|
-
algo: foxes.core.Algorithm
|
|
100
|
-
The calculation algorithm
|
|
101
|
-
mdata: foxes.core.Data
|
|
102
|
-
The model data
|
|
103
|
-
fdata: foxes.core.Data
|
|
104
|
-
The farm data
|
|
105
|
-
pdata: foxes.core.Data
|
|
106
|
-
The evaluation point data
|
|
107
|
-
states_source_turbine: numpy.ndarray of int
|
|
108
|
-
For each state, one turbine index corresponding
|
|
109
|
-
to the wake causing turbine. Shape: (n_states,)
|
|
110
|
-
wake_deltas: Any
|
|
111
|
-
The wake deltas object created by the
|
|
112
|
-
`new_wake_deltas` function
|
|
113
|
-
|
|
114
|
-
"""
|
|
115
|
-
wcoos = self.wake_frame.get_wake_coos(
|
|
116
|
-
algo, mdata, fdata, pdata, states_source_turbine
|
|
36
|
+
rotor = algo.rotor_model
|
|
37
|
+
return (
|
|
38
|
+
rotor.from_data_or_store(rotor.RPOINTS, algo, mdata),
|
|
39
|
+
rotor.from_data_or_store(rotor.RWEIGHTS, algo, mdata),
|
|
117
40
|
)
|
|
118
41
|
|
|
119
|
-
|
|
120
|
-
w.contribute_to_wake_deltas(
|
|
121
|
-
algo, mdata, fdata, pdata, states_source_turbine, wcoos, wake_deltas
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
def evaluate_results(
|
|
42
|
+
def finalize_wakes(
|
|
125
43
|
self,
|
|
126
44
|
algo,
|
|
127
45
|
mdata,
|
|
128
46
|
fdata,
|
|
129
|
-
|
|
47
|
+
tdata,
|
|
48
|
+
amb_res,
|
|
49
|
+
rpoint_weights,
|
|
130
50
|
wake_deltas,
|
|
131
|
-
|
|
132
|
-
|
|
51
|
+
wmodel,
|
|
52
|
+
downwind_index,
|
|
133
53
|
):
|
|
134
54
|
"""
|
|
135
|
-
Updates the
|
|
136
|
-
|
|
55
|
+
Updates the wake_deltas at the selected target
|
|
56
|
+
downwind index.
|
|
57
|
+
|
|
58
|
+
Modifies wake_deltas on the fly.
|
|
137
59
|
|
|
138
60
|
Parameters
|
|
139
61
|
----------
|
|
140
62
|
algo: foxes.core.Algorithm
|
|
141
63
|
The calculation algorithm
|
|
142
|
-
mdata: foxes.core.
|
|
64
|
+
mdata: foxes.core.MData
|
|
143
65
|
The model data
|
|
144
|
-
fdata: foxes.core.
|
|
66
|
+
fdata: foxes.core.FData
|
|
145
67
|
The farm data
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
rpoints = algo.rotor_model.from_data_or_store(FC.RPOINTS, algo, mdata)
|
|
164
|
-
n_states, n_turbines, n_rpoints, __ = rpoints.shape
|
|
165
|
-
|
|
166
|
-
amb_res_in = amb_res is not None
|
|
167
|
-
if not amb_res_in:
|
|
168
|
-
amb_res = algo.rotor_model.from_data_or_store(
|
|
169
|
-
FC.AMB_RPOINT_RESULTS, algo, mdata
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
wres = {}
|
|
173
|
-
st_sel = (np.arange(n_states), states_turbine)
|
|
174
|
-
for v, ares in amb_res.items():
|
|
175
|
-
wres[v] = ares.reshape(n_states, n_turbines, n_rpoints)[st_sel]
|
|
68
|
+
tdata: foxes.core.Data
|
|
69
|
+
The target point data
|
|
70
|
+
amb_res: dict
|
|
71
|
+
The ambient results at the target points
|
|
72
|
+
of all rotors. Key: variable name, value
|
|
73
|
+
np.ndarray of shape:
|
|
74
|
+
(n_states, n_turbines, n_rotor_points)
|
|
75
|
+
rpoint_weights: numpy.ndarray
|
|
76
|
+
The rotor point weights, shape: (n_rotor_points,)
|
|
77
|
+
wake_deltas: dict
|
|
78
|
+
The wake deltas. Key: variable name,
|
|
79
|
+
value: np.ndarray of shape
|
|
80
|
+
(n_states, n_turbines, n_tpoints)
|
|
81
|
+
wmodel: foxes.core.WakeModel
|
|
82
|
+
The wake model
|
|
83
|
+
downwind_index: int
|
|
84
|
+
The index in the downwind order
|
|
176
85
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
86
|
+
Returns
|
|
87
|
+
-------
|
|
88
|
+
final_wake_deltas: dict
|
|
89
|
+
The final wake deltas at the selected downwind
|
|
90
|
+
turbines. Key: variable name, value: np.ndarray
|
|
91
|
+
of shape (n_states, n_rotor_points)
|
|
182
92
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
amb_res[v][st_sel] = wres[v]
|
|
188
|
-
wres[v] = wres[v][:, None]
|
|
93
|
+
"""
|
|
94
|
+
ares = {v: d[:, downwind_index, None] for v, d in amb_res.items()}
|
|
95
|
+
wdel = {v: d[:, downwind_index, None].copy() for v, d in wake_deltas.items()}
|
|
96
|
+
wmodel.finalize_wake_deltas(algo, mdata, fdata, ares, wdel)
|
|
189
97
|
|
|
190
|
-
|
|
191
|
-
algo, mdata, fdata, wres, weights, states_turbine=states_turbine
|
|
192
|
-
)
|
|
98
|
+
return {v: d[:, 0] for v, d in wdel.items()}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from foxes.core import PartialWakesModel
|
|
4
|
+
import foxes.variables as FV
|
|
5
|
+
import foxes.constants as FC
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PartialSegregated(PartialWakesModel):
|
|
9
|
+
"""
|
|
10
|
+
Add the averaged wake effects to the separately
|
|
11
|
+
averaged ambient rotor results
|
|
12
|
+
|
|
13
|
+
Attributes
|
|
14
|
+
----------
|
|
15
|
+
rotor_model: foxes.core.RotorModel
|
|
16
|
+
The rotor model, default is the one from the algorithm
|
|
17
|
+
grotor: foxes.models.rotor_models.GridRotor
|
|
18
|
+
The grid rotor model
|
|
19
|
+
|
|
20
|
+
:group: models.partial_wakes
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, rotor_model):
|
|
25
|
+
"""
|
|
26
|
+
Constructor.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
rotor_model: foxes.core.RotorModel
|
|
31
|
+
The rotor model for wake averaging
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
super().__init__()
|
|
35
|
+
|
|
36
|
+
self.rotor = rotor_model
|
|
37
|
+
self.YZ = self.var("YZ")
|
|
38
|
+
self.W = self.var(FV.WEIGHT)
|
|
39
|
+
|
|
40
|
+
def __repr__(self):
|
|
41
|
+
return f"{type(self).__name__}(rotor_model={self.rotor.name})"
|
|
42
|
+
|
|
43
|
+
def sub_models(self):
|
|
44
|
+
"""
|
|
45
|
+
List of all sub-models
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
smdls: list of foxes.core.Model
|
|
50
|
+
Names of all sub models
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
return super().sub_models() + [self.rotor]
|
|
54
|
+
|
|
55
|
+
def get_wake_points(self, algo, mdata, fdata):
|
|
56
|
+
"""
|
|
57
|
+
Get the wake calculation points, and their
|
|
58
|
+
weights.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
algo: foxes.core.Algorithm
|
|
63
|
+
The calculation algorithm
|
|
64
|
+
mdata: foxes.core.MData
|
|
65
|
+
The model data
|
|
66
|
+
fdata: foxes.core.FData
|
|
67
|
+
The farm data
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
rpoints: numpy.ndarray
|
|
72
|
+
The wake calculation points, shape:
|
|
73
|
+
(n_states, n_turbines, n_tpoints, 3)
|
|
74
|
+
rweights: numpy.ndarray
|
|
75
|
+
The target point weights, shape: (n_tpoints,)
|
|
76
|
+
|
|
77
|
+
"""
|
|
78
|
+
return (
|
|
79
|
+
self.rotor.get_rotor_points(algo, mdata, fdata),
|
|
80
|
+
self.rotor.rotor_point_weights(),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def finalize_wakes(
|
|
84
|
+
self,
|
|
85
|
+
algo,
|
|
86
|
+
mdata,
|
|
87
|
+
fdata,
|
|
88
|
+
tdata,
|
|
89
|
+
amb_res,
|
|
90
|
+
rpoint_weights,
|
|
91
|
+
wake_deltas,
|
|
92
|
+
wmodel,
|
|
93
|
+
downwind_index,
|
|
94
|
+
):
|
|
95
|
+
"""
|
|
96
|
+
Updates the wake_deltas at the selected target
|
|
97
|
+
downwind index.
|
|
98
|
+
|
|
99
|
+
Modifies wake_deltas on the fly.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
algo: foxes.core.Algorithm
|
|
104
|
+
The calculation algorithm
|
|
105
|
+
mdata: foxes.core.MData
|
|
106
|
+
The model data
|
|
107
|
+
fdata: foxes.core.FData
|
|
108
|
+
The farm data
|
|
109
|
+
tdata: foxes.core.Data
|
|
110
|
+
The target point data
|
|
111
|
+
amb_res: dict
|
|
112
|
+
The ambient results at the target points
|
|
113
|
+
of all rotors. Key: variable name, value
|
|
114
|
+
np.ndarray of shape:
|
|
115
|
+
(n_states, n_turbines, n_rotor_points)
|
|
116
|
+
rpoint_weights: numpy.ndarray
|
|
117
|
+
The rotor point weights, shape: (n_rotor_points,)
|
|
118
|
+
wake_deltas: dict
|
|
119
|
+
The wake deltas. Key: variable name,
|
|
120
|
+
value: np.ndarray of shape
|
|
121
|
+
(n_states, n_turbines, n_tpoints)
|
|
122
|
+
wmodel: foxes.core.WakeModel
|
|
123
|
+
The wake model
|
|
124
|
+
downwind_index: int
|
|
125
|
+
The index in the downwind order
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
final_wake_deltas: dict
|
|
130
|
+
The final wake deltas at the selected downwind
|
|
131
|
+
turbines. Key: variable name, value: np.ndarray
|
|
132
|
+
of shape (n_states, n_rotor_points)
|
|
133
|
+
|
|
134
|
+
"""
|
|
135
|
+
n_states = fdata.n_states
|
|
136
|
+
n_rotor_points = len(rpoint_weights)
|
|
137
|
+
gweights = tdata[FC.TWEIGHTS]
|
|
138
|
+
|
|
139
|
+
wdel = {v: d[:, downwind_index, None].copy() for v, d in wake_deltas.items()}
|
|
140
|
+
|
|
141
|
+
if n_rotor_points == tdata.n_tpoints:
|
|
142
|
+
ares = {v: d[:, downwind_index, None] for v, d in amb_res.items()}
|
|
143
|
+
else:
|
|
144
|
+
ares = {}
|
|
145
|
+
for v, d in amb_res.items():
|
|
146
|
+
ares[v] = np.zeros((n_states, 1, tdata.n_tpoints), dtype=FC.DTYPE)
|
|
147
|
+
ares[v][:] = np.einsum("sp,p->s", d[:, downwind_index], rpoint_weights)[
|
|
148
|
+
:, None, None
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
wmodel.finalize_wake_deltas(algo, mdata, fdata, ares, wdel)
|
|
152
|
+
|
|
153
|
+
for v in wdel.keys():
|
|
154
|
+
hdel = np.zeros((n_states, n_rotor_points), dtype=FC.DTYPE)
|
|
155
|
+
hdel[:] = np.einsum("sp,p->s", wdel[v][:, 0], gweights)[:, None]
|
|
156
|
+
wdel[v] = hdel
|
|
157
|
+
|
|
158
|
+
return wdel
|