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
foxes/core/turbine_model.py
CHANGED
|
@@ -28,13 +28,13 @@ class TurbineModel(FarmDataModel):
|
|
|
28
28
|
----------
|
|
29
29
|
algo: foxes.core.Algorithm
|
|
30
30
|
The calculation algorithm
|
|
31
|
-
mdata: foxes.core.
|
|
31
|
+
mdata: foxes.core.MData
|
|
32
32
|
The model data
|
|
33
|
-
fdata: foxes.core.
|
|
33
|
+
fdata: foxes.core.FData
|
|
34
34
|
The farm data
|
|
35
|
-
st_sel: numpy.ndarray of bool
|
|
35
|
+
st_sel: slice or numpy.ndarray of bool
|
|
36
36
|
The state-turbine selection,
|
|
37
|
-
shape: (n_states, n_turbines)
|
|
37
|
+
for shape: (n_states, n_turbines)
|
|
38
38
|
|
|
39
39
|
Returns
|
|
40
40
|
-------
|
foxes/core/turbine_type.py
CHANGED
|
@@ -60,6 +60,30 @@ class TurbineType(TurbineModel):
|
|
|
60
60
|
f"Turbine type '{self.name}': Unkown P_unit '{P_unit}', expecting {list(FC.P_UNITS.keys())}"
|
|
61
61
|
)
|
|
62
62
|
|
|
63
|
+
def __repr__(self):
|
|
64
|
+
a = f"D={self.D}, H={self.H}, P_nominal={self.P_nominal}, P_unit={self.P_unit}"
|
|
65
|
+
return f"{type(self).__name__}({a})"
|
|
66
|
+
|
|
67
|
+
def modify_cutin(self, modify_ct, modify_P):
|
|
68
|
+
"""
|
|
69
|
+
Modify the data such that a discontinuity
|
|
70
|
+
at cutin wind speed is avoided
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
variable: str
|
|
75
|
+
The target variable
|
|
76
|
+
modify_ct: bool
|
|
77
|
+
Flag for modification of the ct curve
|
|
78
|
+
modify_P: bool
|
|
79
|
+
Flag for modification of the power curve
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
if modify_ct or modify_P:
|
|
83
|
+
raise NotImplementedError(
|
|
84
|
+
f"Turbine type '{self.name}': Continuous cutin not implemented for modify_ct = {modify_ct}, modify_P = {modify_P}"
|
|
85
|
+
)
|
|
86
|
+
|
|
63
87
|
@classmethod
|
|
64
88
|
def new(cls, ttype_type, *args, **kwargs):
|
|
65
89
|
"""
|
foxes/core/vertical_profile.py
CHANGED
|
@@ -27,14 +27,14 @@ class VerticalProfile(Model):
|
|
|
27
27
|
return []
|
|
28
28
|
|
|
29
29
|
@abstractmethod
|
|
30
|
-
def calculate(self,
|
|
30
|
+
def calculate(self, tdata, heights):
|
|
31
31
|
"""
|
|
32
32
|
Run the profile calculation.
|
|
33
33
|
|
|
34
34
|
Parameters
|
|
35
35
|
----------
|
|
36
|
-
|
|
37
|
-
The
|
|
36
|
+
tdata: dict
|
|
37
|
+
The target point data
|
|
38
38
|
heights: numpy.ndarray
|
|
39
39
|
The evaluation heights
|
|
40
40
|
|
foxes/core/wake_frame.py
CHANGED
|
@@ -51,29 +51,36 @@ class WakeFrame(Model):
|
|
|
51
51
|
pass
|
|
52
52
|
|
|
53
53
|
@abstractmethod
|
|
54
|
-
def get_wake_coos(
|
|
54
|
+
def get_wake_coos(
|
|
55
|
+
self,
|
|
56
|
+
algo,
|
|
57
|
+
mdata,
|
|
58
|
+
fdata,
|
|
59
|
+
tdata,
|
|
60
|
+
downwind_index,
|
|
61
|
+
):
|
|
55
62
|
"""
|
|
56
|
-
Calculate wake coordinates.
|
|
63
|
+
Calculate wake coordinates of rotor points.
|
|
57
64
|
|
|
58
65
|
Parameters
|
|
59
66
|
----------
|
|
60
67
|
algo: foxes.core.Algorithm
|
|
61
68
|
The calculation algorithm
|
|
62
|
-
mdata: foxes.core.
|
|
69
|
+
mdata: foxes.core.MData
|
|
63
70
|
The model data
|
|
64
|
-
fdata: foxes.core.
|
|
71
|
+
fdata: foxes.core.FData
|
|
65
72
|
The farm data
|
|
66
|
-
|
|
67
|
-
The
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
tdata: foxes.core.TData
|
|
74
|
+
The target point data
|
|
75
|
+
downwind_index: int
|
|
76
|
+
The index of the wake causing turbine
|
|
77
|
+
in the downwnd order
|
|
71
78
|
|
|
72
79
|
Returns
|
|
73
80
|
-------
|
|
74
81
|
wake_coos: numpy.ndarray
|
|
75
82
|
The wake frame coordinates of the evaluation
|
|
76
|
-
points, shape: (n_states,
|
|
83
|
+
points, shape: (n_states, n_targets, n_tpoints, 3)
|
|
77
84
|
|
|
78
85
|
"""
|
|
79
86
|
pass
|
|
@@ -82,10 +89,12 @@ class WakeFrame(Model):
|
|
|
82
89
|
self,
|
|
83
90
|
algo,
|
|
84
91
|
variable,
|
|
85
|
-
|
|
92
|
+
downwind_index,
|
|
86
93
|
fdata,
|
|
87
|
-
|
|
94
|
+
tdata,
|
|
95
|
+
target,
|
|
88
96
|
states0=None,
|
|
97
|
+
upcast=False,
|
|
89
98
|
):
|
|
90
99
|
"""
|
|
91
100
|
Return data that is required for computing the
|
|
@@ -97,27 +106,61 @@ class WakeFrame(Model):
|
|
|
97
106
|
The algorithm, needed for data from previous iteration
|
|
98
107
|
variable: str
|
|
99
108
|
The variable, serves as data key
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
fdata: foxes.core.Data
|
|
109
|
+
downwind_index: int, optional
|
|
110
|
+
The index in the downwind order
|
|
111
|
+
fdata: foxes.core.FData
|
|
104
112
|
The farm data
|
|
105
|
-
|
|
106
|
-
The
|
|
113
|
+
tdata: foxes.core.TData
|
|
114
|
+
The target point data
|
|
115
|
+
target: str, optional
|
|
116
|
+
The dimensions identifier for the output,
|
|
117
|
+
FC.STATE_TURBINE, FC.STATE_TARGET,
|
|
118
|
+
FC.STATE_TARGET_TPOINT
|
|
107
119
|
states0: numpy.ndarray, optional
|
|
108
120
|
The states of wake creation
|
|
121
|
+
upcast: bool
|
|
122
|
+
Flag for ensuring targets dimension,
|
|
123
|
+
otherwise dimension 1 is entered
|
|
124
|
+
|
|
125
|
+
Returns
|
|
126
|
+
-------
|
|
127
|
+
data: numpy.ndarray
|
|
128
|
+
Data for wake modelling, shape:
|
|
129
|
+
(n_states, n_turbines) or (n_states, n_target)
|
|
130
|
+
dims: tuple
|
|
131
|
+
The data dimensions
|
|
109
132
|
|
|
110
133
|
"""
|
|
111
134
|
n_states = fdata.n_states
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
135
|
+
s = np.s_[:] if states0 is None else states0
|
|
136
|
+
|
|
137
|
+
if not upcast:
|
|
138
|
+
if target == FC.STATE_TARGET_TPOINT:
|
|
139
|
+
out = fdata[variable][s, downwind_index, None, None]
|
|
140
|
+
dims = (FC.STATE, 1, 1)
|
|
141
|
+
else:
|
|
142
|
+
out = fdata[variable][s, downwind_index, None]
|
|
143
|
+
dims = (FC.STATE, 1)
|
|
144
|
+
elif target == FC.STATE_TURBINE:
|
|
145
|
+
out = np.zeros((n_states, fdata.n_turbines), dtype=FC.DTYPE)
|
|
146
|
+
out[:] = fdata[variable][s, downwind_index, None]
|
|
147
|
+
dims = (FC.STATE, FC.TURBINE)
|
|
148
|
+
elif target == FC.STATE_TARGET:
|
|
149
|
+
out = np.zeros((n_states, tdata.n_targets), dtype=FC.DTYPE)
|
|
150
|
+
out[:] = fdata[variable][s, downwind_index, None]
|
|
151
|
+
dims = (FC.STATE, FC.TARGET)
|
|
152
|
+
elif target == FC.STATE_TARGET_TPOINT:
|
|
153
|
+
out = np.zeros((n_states, tdata.n_targets, tdata.n_tpoints), dtype=FC.DTYPE)
|
|
154
|
+
out[:] = fdata[variable][s, downwind_index, None, None]
|
|
155
|
+
dims = (FC.STATE, FC.TARGET, FC.TPOINT)
|
|
156
|
+
else:
|
|
157
|
+
raise ValueError(
|
|
158
|
+
f"Unsupported target '{target}', expcting '{FC.STATE_TURBINE}', '{FC.STATE_TARGET}', {FC.STATE_TARGET_TPOINT}"
|
|
159
|
+
)
|
|
117
160
|
|
|
118
|
-
return out
|
|
161
|
+
return out, dims
|
|
119
162
|
|
|
120
|
-
def get_centreline_points(self, algo, mdata, fdata,
|
|
163
|
+
def get_centreline_points(self, algo, mdata, fdata, downwind_index, x):
|
|
121
164
|
"""
|
|
122
165
|
Gets the points along the centreline for given
|
|
123
166
|
values of x.
|
|
@@ -126,13 +169,12 @@ class WakeFrame(Model):
|
|
|
126
169
|
----------
|
|
127
170
|
algo: foxes.core.Algorithm
|
|
128
171
|
The calculation algorithm
|
|
129
|
-
mdata: foxes.core.
|
|
172
|
+
mdata: foxes.core.MData
|
|
130
173
|
The model data
|
|
131
|
-
fdata: foxes.core.
|
|
174
|
+
fdata: foxes.core.FData
|
|
132
175
|
The farm data
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
wake causing turbine. Shape: (n_states,)
|
|
176
|
+
downwind_index: int
|
|
177
|
+
The index in the downwind order
|
|
136
178
|
x: numpy.ndarray
|
|
137
179
|
The wake frame x coordinates, shape: (n_states, n_points)
|
|
138
180
|
|
|
@@ -151,7 +193,7 @@ class WakeFrame(Model):
|
|
|
151
193
|
algo,
|
|
152
194
|
mdata,
|
|
153
195
|
fdata,
|
|
154
|
-
|
|
196
|
+
downwind_index,
|
|
155
197
|
variables,
|
|
156
198
|
x,
|
|
157
199
|
dx,
|
|
@@ -166,13 +208,12 @@ class WakeFrame(Model):
|
|
|
166
208
|
----------
|
|
167
209
|
algo: foxes.core.Algorithm
|
|
168
210
|
The calculation algorithm
|
|
169
|
-
mdata: foxes.core.
|
|
211
|
+
mdata: foxes.core.MData
|
|
170
212
|
The model data
|
|
171
|
-
fdata: foxes.core.
|
|
213
|
+
fdata: foxes.core.FData
|
|
172
214
|
The farm data
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
wake causing turbine. Shape: (n_states,)
|
|
215
|
+
downwind_index: int
|
|
216
|
+
The index in the downwind order
|
|
176
217
|
variables: list of str
|
|
177
218
|
The variables to be integrated
|
|
178
219
|
x: numpy.ndarray
|
|
@@ -208,22 +249,22 @@ class WakeFrame(Model):
|
|
|
208
249
|
xs = np.arange(xmin, xmin + n_ix * dx, dx)
|
|
209
250
|
xpts = np.zeros((n_states, n_steps), dtype=FC.DTYPE)
|
|
210
251
|
xpts[:] = xs[None, 1:]
|
|
211
|
-
pts = self.get_centreline_points(
|
|
212
|
-
algo, mdata, fdata, states_source_turbine, xpts
|
|
213
|
-
)
|
|
252
|
+
pts = self.get_centreline_points(algo, mdata, fdata, downwind_index, xpts)
|
|
214
253
|
|
|
215
254
|
# run ambient calculation:
|
|
216
|
-
|
|
255
|
+
tdata = Data.from_points(
|
|
217
256
|
pts,
|
|
218
|
-
data={
|
|
219
|
-
|
|
257
|
+
data={
|
|
258
|
+
v: np.full((n_states, n_steps, 1), np.nan, dtype=FC.DTYPE) for v in vrs
|
|
259
|
+
},
|
|
260
|
+
dims={v: (FC.STATE, FC.TARGET, FC.TPOINT) for v in vrs},
|
|
220
261
|
)
|
|
221
|
-
res = algo.states.calculate(algo, mdata, fdata,
|
|
222
|
-
|
|
262
|
+
res = algo.states.calculate(algo, mdata, fdata, tdata)
|
|
263
|
+
tdata.update(res)
|
|
223
264
|
amb2var = algo.get_model("SetAmbPointResults")()
|
|
224
265
|
amb2var.initialize(algo, verbosity=0)
|
|
225
|
-
res = amb2var.calculate(algo, mdata, fdata,
|
|
226
|
-
|
|
266
|
+
res = amb2var.calculate(algo, mdata, fdata, tdata)
|
|
267
|
+
tdata.update(res)
|
|
227
268
|
del res, amb2var
|
|
228
269
|
|
|
229
270
|
# find out if all vars ambient:
|
|
@@ -237,16 +278,16 @@ class WakeFrame(Model):
|
|
|
237
278
|
if not ambient:
|
|
238
279
|
wcalc = algo.get_model("PointWakesCalculation")(wake_models=wake_models)
|
|
239
280
|
wcalc.initialize(algo, verbosity=0)
|
|
240
|
-
wsrc =
|
|
241
|
-
res = wcalc.calculate(algo, mdata, fdata,
|
|
242
|
-
|
|
281
|
+
wsrc = downwind_index if self_wake else None
|
|
282
|
+
res = wcalc.calculate(algo, mdata, fdata, tdata, downwind_index=wsrc)
|
|
283
|
+
tdata.update(res)
|
|
243
284
|
del wcalc, res
|
|
244
285
|
|
|
245
286
|
# collect integration results:
|
|
246
287
|
iresults = np.zeros((n_states, n_ix, n_vars), dtype=FC.DTYPE)
|
|
247
288
|
for vi, v in enumerate(variables):
|
|
248
289
|
for i in range(n_steps):
|
|
249
|
-
iresults[:, i + 1, vi] = iresults[:, i, vi] +
|
|
290
|
+
iresults[:, i + 1, vi] = iresults[:, i, vi] + tdata[v][:, i, 0] * dx
|
|
250
291
|
|
|
251
292
|
# interpolate to x of interest:
|
|
252
293
|
qts = np.zeros((n_states, n_points, 2), dtype=FC.DTYPE)
|
foxes/core/wake_model.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
|
+
import numpy as np
|
|
2
3
|
|
|
3
4
|
from foxes.utils import all_subclasses
|
|
5
|
+
import foxes.variables as FV
|
|
6
|
+
import foxes.constants as FC
|
|
4
7
|
|
|
5
8
|
from .model import Model
|
|
6
9
|
|
|
@@ -13,70 +16,79 @@ class WakeModel(Model):
|
|
|
13
16
|
|
|
14
17
|
"""
|
|
15
18
|
|
|
16
|
-
@
|
|
17
|
-
def
|
|
19
|
+
@property
|
|
20
|
+
def affects_downwind(self):
|
|
21
|
+
"""
|
|
22
|
+
Flag for downwind or upwind effects
|
|
23
|
+
on other turbines
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
dwnd: bool
|
|
28
|
+
Flag for downwind effects by this model
|
|
29
|
+
|
|
18
30
|
"""
|
|
19
|
-
|
|
31
|
+
return True
|
|
20
32
|
|
|
21
|
-
|
|
33
|
+
def new_wake_deltas(self, algo, mdata, fdata, tdata):
|
|
34
|
+
"""
|
|
35
|
+
Creates new empty wake delta arrays.
|
|
22
36
|
|
|
23
37
|
Parameters
|
|
24
38
|
----------
|
|
25
39
|
algo: foxes.core.Algorithm
|
|
26
40
|
The calculation algorithm
|
|
27
|
-
mdata: foxes.core.
|
|
41
|
+
mdata: foxes.core.MData
|
|
28
42
|
The model data
|
|
29
|
-
fdata: foxes.core.
|
|
43
|
+
fdata: foxes.core.FData
|
|
30
44
|
The farm data
|
|
31
|
-
|
|
32
|
-
The
|
|
45
|
+
tdata: foxes.core.TData
|
|
46
|
+
The target point data
|
|
47
|
+
|
|
48
|
+
Returns
|
|
49
|
+
-------
|
|
33
50
|
wake_deltas: dict
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
wake delta applies, values: numpy.ndarray with
|
|
37
|
-
shape (n_states, n_points, ...)
|
|
51
|
+
Key: variable name, value: The zero filled
|
|
52
|
+
wake deltas, shape: (n_states, n_turbines, n_rpoints, ...)
|
|
38
53
|
|
|
39
54
|
"""
|
|
40
|
-
|
|
55
|
+
return {FV.WS: np.zeros_like(tdata[FC.TARGETS][..., 0])}
|
|
41
56
|
|
|
42
57
|
@abstractmethod
|
|
43
|
-
def
|
|
58
|
+
def contribute(
|
|
44
59
|
self,
|
|
45
60
|
algo,
|
|
46
61
|
mdata,
|
|
47
62
|
fdata,
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
tdata,
|
|
64
|
+
downwind_index,
|
|
50
65
|
wake_coos,
|
|
51
66
|
wake_deltas,
|
|
52
67
|
):
|
|
53
68
|
"""
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Modifies wake_deltas on the fly.
|
|
69
|
+
Modifies wake deltas at target points by
|
|
70
|
+
contributions from the specified wake source turbines.
|
|
58
71
|
|
|
59
72
|
Parameters
|
|
60
73
|
----------
|
|
61
74
|
algo: foxes.core.Algorithm
|
|
62
75
|
The calculation algorithm
|
|
63
|
-
mdata: foxes.core.
|
|
76
|
+
mdata: foxes.core.MData
|
|
64
77
|
The model data
|
|
65
|
-
fdata: foxes.core.
|
|
78
|
+
fdata: foxes.core.FData
|
|
66
79
|
The farm data
|
|
67
|
-
|
|
68
|
-
The
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
tdata: foxes.core.TData
|
|
81
|
+
The target point data
|
|
82
|
+
downwind_index: int
|
|
83
|
+
The index of the wake causing turbine
|
|
84
|
+
in the downwnd order
|
|
72
85
|
wake_coos: numpy.ndarray
|
|
73
86
|
The wake frame coordinates of the evaluation
|
|
74
|
-
points, shape: (n_states,
|
|
87
|
+
points, shape: (n_states, n_targets, n_tpoints, 3)
|
|
75
88
|
wake_deltas: dict
|
|
76
|
-
The wake deltas
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
shape (n_states, n_points, ...)
|
|
89
|
+
The wake deltas. Key: variable name,
|
|
90
|
+
value: numpy.ndarray with shape
|
|
91
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
80
92
|
|
|
81
93
|
"""
|
|
82
94
|
pass
|
|
@@ -86,7 +98,6 @@ class WakeModel(Model):
|
|
|
86
98
|
algo,
|
|
87
99
|
mdata,
|
|
88
100
|
fdata,
|
|
89
|
-
pdata,
|
|
90
101
|
amb_results,
|
|
91
102
|
wake_deltas,
|
|
92
103
|
):
|
|
@@ -99,21 +110,18 @@ class WakeModel(Model):
|
|
|
99
110
|
----------
|
|
100
111
|
algo: foxes.core.Algorithm
|
|
101
112
|
The calculation algorithm
|
|
102
|
-
mdata: foxes.core.
|
|
113
|
+
mdata: foxes.core.MData
|
|
103
114
|
The model data
|
|
104
|
-
fdata: foxes.core.
|
|
115
|
+
fdata: foxes.core.FData
|
|
105
116
|
The farm data
|
|
106
|
-
pdata: foxes.core.Data
|
|
107
|
-
The evaluation point data
|
|
108
117
|
amb_results: dict
|
|
109
118
|
The ambient results, key: variable name str,
|
|
110
|
-
values: numpy.ndarray with shape
|
|
119
|
+
values: numpy.ndarray with shape
|
|
120
|
+
(n_states, n_targets, n_tpoints)
|
|
111
121
|
wake_deltas: dict
|
|
112
|
-
The wake deltas
|
|
113
|
-
Key:
|
|
114
|
-
|
|
115
|
-
(n_states, n_points, ...) before evaluation,
|
|
116
|
-
numpy.ndarray with shape (n_states, n_points) afterwards
|
|
122
|
+
The wake deltas object at the selected target
|
|
123
|
+
turbines. Key: variable str, value: numpy.ndarray
|
|
124
|
+
with shape (n_states, n_targets, n_tpoints)
|
|
117
125
|
|
|
118
126
|
"""
|
|
119
127
|
pass
|
|
@@ -152,3 +160,26 @@ class WakeModel(Model):
|
|
|
152
160
|
)
|
|
153
161
|
)
|
|
154
162
|
raise KeyError(estr)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class TurbineInductionModel(WakeModel):
|
|
166
|
+
"""
|
|
167
|
+
Abstract base class for turbine induction models.
|
|
168
|
+
|
|
169
|
+
:group: core
|
|
170
|
+
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def affects_downwind(self):
|
|
175
|
+
"""
|
|
176
|
+
Flag for downwind or upwind effects
|
|
177
|
+
on other turbines
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
dwnd: bool
|
|
182
|
+
Flag for downwind effects by this model
|
|
183
|
+
|
|
184
|
+
"""
|
|
185
|
+
return False
|
foxes/core/wake_superposition.py
CHANGED
|
@@ -17,48 +17,51 @@ class WakeSuperposition(Model):
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
@abstractmethod
|
|
20
|
-
def
|
|
20
|
+
def add_wake(
|
|
21
21
|
self,
|
|
22
22
|
algo,
|
|
23
23
|
mdata,
|
|
24
24
|
fdata,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
tdata,
|
|
26
|
+
downwind_index,
|
|
27
|
+
st_sel,
|
|
28
28
|
variable,
|
|
29
29
|
wake_delta,
|
|
30
30
|
wake_model_result,
|
|
31
31
|
):
|
|
32
32
|
"""
|
|
33
|
-
Add a wake delta to previous wake deltas
|
|
33
|
+
Add a wake delta to previous wake deltas,
|
|
34
|
+
at rotor points.
|
|
34
35
|
|
|
35
36
|
Parameters
|
|
36
37
|
----------
|
|
37
38
|
algo: foxes.core.Algorithm
|
|
38
39
|
The calculation algorithm
|
|
39
|
-
mdata: foxes.core.
|
|
40
|
+
mdata: foxes.core.MData
|
|
40
41
|
The model data
|
|
41
|
-
fdata: foxes.core.
|
|
42
|
+
fdata: foxes.core.FData
|
|
42
43
|
The farm data
|
|
43
|
-
|
|
44
|
-
The
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
The selection of
|
|
44
|
+
tdata: foxes.core.TData
|
|
45
|
+
The target point data
|
|
46
|
+
downwind_index: int
|
|
47
|
+
The index of the wake causing turbine
|
|
48
|
+
in the downwnd order
|
|
49
|
+
st_sel: numpy.ndarray of bool
|
|
50
|
+
The selection of targets, shape: (n_states, n_targets)
|
|
50
51
|
variable: str
|
|
51
52
|
The variable name for which the wake deltas applies
|
|
52
53
|
wake_delta: numpy.ndarray
|
|
53
|
-
The original wake deltas, shape:
|
|
54
|
+
The original wake deltas, shape:
|
|
55
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
54
56
|
wake_model_result: numpy.ndarray
|
|
55
|
-
The new wake deltas of the selected
|
|
56
|
-
shape: (
|
|
57
|
+
The new wake deltas of the selected rotors,
|
|
58
|
+
shape: (n_st_sel, n_tpoints, ...)
|
|
57
59
|
|
|
58
60
|
Returns
|
|
59
61
|
-------
|
|
60
62
|
wdelta: numpy.ndarray
|
|
61
|
-
The updated wake deltas, shape:
|
|
63
|
+
The updated wake deltas, shape:
|
|
64
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
62
65
|
|
|
63
66
|
"""
|
|
64
67
|
pass
|
|
@@ -69,7 +72,6 @@ class WakeSuperposition(Model):
|
|
|
69
72
|
algo,
|
|
70
73
|
mdata,
|
|
71
74
|
fdata,
|
|
72
|
-
pdata,
|
|
73
75
|
variable,
|
|
74
76
|
amb_results,
|
|
75
77
|
wake_delta,
|
|
@@ -82,24 +84,25 @@ class WakeSuperposition(Model):
|
|
|
82
84
|
----------
|
|
83
85
|
algo: foxes.core.Algorithm
|
|
84
86
|
The calculation algorithm
|
|
85
|
-
mdata: foxes.core.
|
|
87
|
+
mdata: foxes.core.MData
|
|
86
88
|
The model data
|
|
87
|
-
fdata: foxes.core.
|
|
89
|
+
fdata: foxes.core.FData
|
|
88
90
|
The farm data
|
|
89
|
-
pdata: foxes.core.Data
|
|
90
|
-
The evaluation point data
|
|
91
91
|
variable: str
|
|
92
92
|
The variable name for which the wake deltas applies
|
|
93
93
|
amb_results: numpy.ndarray
|
|
94
|
-
The ambient results
|
|
94
|
+
The ambient results at targets,
|
|
95
|
+
shape: (n_states, n_targets, n_tpoints)
|
|
95
96
|
wake_delta: numpy.ndarray
|
|
96
|
-
The wake deltas, shape:
|
|
97
|
+
The wake deltas at targets, shape:
|
|
98
|
+
(n_states, n_targets, n_tpoints)
|
|
97
99
|
|
|
98
100
|
Returns
|
|
99
101
|
-------
|
|
100
102
|
final_wake_delta: numpy.ndarray
|
|
101
103
|
The final wake delta, which will be added to the ambient
|
|
102
|
-
results by simple plus operation. Shape:
|
|
104
|
+
results by simple plus operation. Shape:
|
|
105
|
+
(n_states, n_targets, n_tpoints)
|
|
103
106
|
|
|
104
107
|
"""
|
|
105
108
|
pass
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from foxes.utils import random_xy_square
|
|
4
|
+
from foxes.core import Turbine
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def add_random(
|
|
8
|
+
farm,
|
|
9
|
+
n_turbines,
|
|
10
|
+
min_dist,
|
|
11
|
+
centre=[0, 0],
|
|
12
|
+
seed=None,
|
|
13
|
+
verbosity=1,
|
|
14
|
+
**turbine_parameters,
|
|
15
|
+
):
|
|
16
|
+
"""
|
|
17
|
+
Add turbines that lie randomly within a square
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
farm: foxes.WindFarm
|
|
22
|
+
The wind farm
|
|
23
|
+
n_turbines: int
|
|
24
|
+
The number of turbines
|
|
25
|
+
min_dist: float
|
|
26
|
+
The minimal distance between turbines
|
|
27
|
+
centre: array-like
|
|
28
|
+
The (x, y) coordinates of the mean
|
|
29
|
+
seed: int, optional
|
|
30
|
+
The random seed
|
|
31
|
+
verbosity: int
|
|
32
|
+
The verbosity level, 0 = silent
|
|
33
|
+
turbine_parameters: dict, optional
|
|
34
|
+
Additional parameters are forwarded to the WindFarm.add_turbine().
|
|
35
|
+
|
|
36
|
+
:group: input.farm_layout
|
|
37
|
+
|
|
38
|
+
"""
|
|
39
|
+
xy = random_xy_square(n_turbines, min_dist, seed=seed, verbosity=verbosity)
|
|
40
|
+
xy += np.array(centre)[None, :]
|
|
41
|
+
|
|
42
|
+
for i in range(len(xy)):
|
|
43
|
+
farm.add_turbine(
|
|
44
|
+
Turbine(
|
|
45
|
+
xy=xy[i],
|
|
46
|
+
**turbine_parameters,
|
|
47
|
+
),
|
|
48
|
+
verbosity=verbosity,
|
|
49
|
+
)
|
foxes/input/states/__init__.py
CHANGED