foxes 0.8.2__py3-none-any.whl → 1.1.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.
- docs/source/conf.py +353 -0
- examples/abl_states/run.py +160 -0
- examples/compare_rotors_pwakes/run.py +217 -0
- examples/compare_wakes/run.py +241 -0
- examples/dyn_wakes/run.py +311 -0
- examples/field_data_nc/run.py +121 -0
- examples/induction/run.py +201 -0
- examples/multi_height/run.py +113 -0
- examples/power_mask/run.py +249 -0
- examples/random_timeseries/run.py +210 -0
- examples/scan_row/run.py +193 -0
- examples/sector_management/run.py +162 -0
- examples/sequential/run.py +209 -0
- examples/single_state/run.py +201 -0
- examples/states_lookup_table/run.py +137 -0
- examples/streamline_wakes/run.py +138 -0
- examples/tab_file/run.py +142 -0
- examples/timelines/run.py +267 -0
- examples/timeseries/run.py +190 -0
- examples/timeseries_slurm/run.py +185 -0
- examples/wind_rose/run.py +141 -0
- examples/windio/run.py +29 -0
- examples/yawed_wake/run.py +196 -0
- foxes/__init__.py +4 -8
- foxes/algorithms/__init__.py +1 -1
- foxes/algorithms/downwind/downwind.py +247 -111
- foxes/algorithms/downwind/models/farm_wakes_calc.py +12 -7
- foxes/algorithms/downwind/models/init_farm_data.py +2 -2
- foxes/algorithms/downwind/models/point_wakes_calc.py +6 -7
- foxes/algorithms/downwind/models/reorder_farm_output.py +1 -2
- foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
- foxes/algorithms/downwind/models/set_amb_point_results.py +5 -3
- foxes/algorithms/iterative/iterative.py +74 -34
- foxes/algorithms/iterative/models/farm_wakes_calc.py +12 -7
- foxes/algorithms/iterative/models/urelax.py +3 -3
- foxes/algorithms/sequential/models/plugin.py +5 -5
- foxes/algorithms/sequential/models/seq_state.py +1 -1
- foxes/algorithms/sequential/sequential.py +126 -255
- foxes/constants.py +22 -7
- foxes/core/__init__.py +1 -0
- foxes/core/algorithm.py +632 -147
- foxes/core/data.py +252 -20
- foxes/core/data_calc_model.py +15 -291
- foxes/core/engine.py +640 -0
- foxes/core/farm_controller.py +38 -10
- foxes/core/farm_data_model.py +16 -1
- foxes/core/ground_model.py +2 -2
- foxes/core/model.py +249 -182
- foxes/core/partial_wakes_model.py +1 -1
- foxes/core/point_data_model.py +17 -2
- foxes/core/rotor_model.py +27 -21
- foxes/core/states.py +17 -1
- foxes/core/turbine_type.py +28 -0
- foxes/core/wake_frame.py +30 -34
- foxes/core/wake_model.py +5 -5
- foxes/core/wake_superposition.py +1 -1
- foxes/data/windio/windio_5turbines_timeseries.yaml +31 -15
- foxes/engines/__init__.py +17 -0
- foxes/engines/dask.py +982 -0
- foxes/engines/default.py +75 -0
- foxes/engines/futures.py +72 -0
- foxes/engines/mpi.py +38 -0
- foxes/engines/multiprocess.py +71 -0
- foxes/engines/numpy.py +167 -0
- foxes/engines/pool.py +249 -0
- foxes/engines/ray.py +79 -0
- foxes/engines/single.py +141 -0
- foxes/input/farm_layout/__init__.py +1 -0
- foxes/input/farm_layout/from_csv.py +4 -0
- foxes/input/farm_layout/from_json.py +2 -2
- foxes/input/farm_layout/grid.py +2 -2
- foxes/input/farm_layout/ring.py +65 -0
- foxes/input/farm_layout/row.py +2 -2
- foxes/input/states/__init__.py +7 -0
- foxes/input/states/create/random_abl_states.py +1 -1
- foxes/input/states/field_data_nc.py +158 -33
- foxes/input/states/multi_height.py +128 -14
- foxes/input/states/one_point_flow.py +577 -0
- foxes/input/states/scan_ws.py +74 -3
- foxes/input/states/single.py +1 -1
- foxes/input/states/slice_data_nc.py +681 -0
- foxes/input/states/states_table.py +204 -35
- foxes/input/windio/__init__.py +2 -2
- foxes/input/windio/get_states.py +44 -23
- foxes/input/windio/read_attributes.py +48 -17
- foxes/input/windio/read_farm.py +116 -102
- foxes/input/windio/read_fields.py +16 -6
- foxes/input/windio/read_outputs.py +71 -24
- foxes/input/windio/runner.py +31 -17
- foxes/input/windio/windio.py +41 -23
- foxes/models/farm_models/turbine2farm.py +1 -1
- foxes/models/ground_models/wake_mirror.py +10 -6
- foxes/models/model_book.py +58 -20
- foxes/models/partial_wakes/axiwake.py +3 -3
- foxes/models/partial_wakes/rotor_points.py +3 -3
- foxes/models/partial_wakes/top_hat.py +2 -2
- foxes/models/point_models/set_uniform_data.py +1 -1
- foxes/models/point_models/tke2ti.py +1 -1
- foxes/models/point_models/wake_deltas.py +1 -1
- foxes/models/rotor_models/centre.py +4 -0
- foxes/models/rotor_models/grid.py +24 -25
- foxes/models/rotor_models/levels.py +4 -5
- foxes/models/turbine_models/calculator.py +4 -6
- foxes/models/turbine_models/kTI_model.py +22 -6
- foxes/models/turbine_models/lookup_table.py +30 -4
- foxes/models/turbine_models/rotor_centre_calc.py +4 -3
- foxes/models/turbine_models/set_farm_vars.py +103 -34
- foxes/models/turbine_types/PCt_file.py +27 -3
- foxes/models/turbine_types/PCt_from_two.py +27 -3
- foxes/models/turbine_types/TBL_file.py +80 -0
- foxes/models/turbine_types/__init__.py +2 -0
- foxes/models/turbine_types/lookup.py +316 -0
- foxes/models/turbine_types/null_type.py +51 -1
- foxes/models/turbine_types/wsrho2PCt_from_two.py +29 -5
- foxes/models/turbine_types/wsti2PCt_from_two.py +31 -7
- foxes/models/vertical_profiles/__init__.py +1 -1
- foxes/models/vertical_profiles/data_profile.py +1 -1
- foxes/models/wake_frames/__init__.py +1 -0
- foxes/models/wake_frames/dynamic_wakes.py +424 -0
- foxes/models/wake_frames/farm_order.py +25 -5
- foxes/models/wake_frames/rotor_wd.py +6 -4
- foxes/models/wake_frames/seq_dynamic_wakes.py +61 -74
- foxes/models/wake_frames/streamlines.py +21 -22
- foxes/models/wake_frames/timelines.py +330 -129
- foxes/models/wake_frames/yawed_wakes.py +7 -4
- foxes/models/wake_models/dist_sliced.py +2 -4
- foxes/models/wake_models/induction/rankine_half_body.py +5 -5
- foxes/models/wake_models/induction/rathmann.py +78 -24
- foxes/models/wake_models/induction/self_similar.py +78 -28
- foxes/models/wake_models/induction/vortex_sheet.py +86 -48
- foxes/models/wake_models/ti/crespo_hernandez.py +6 -4
- foxes/models/wake_models/ti/iec_ti.py +40 -21
- foxes/models/wake_models/top_hat.py +1 -1
- foxes/models/wake_models/wind/bastankhah14.py +8 -6
- foxes/models/wake_models/wind/bastankhah16.py +17 -16
- foxes/models/wake_models/wind/jensen.py +4 -3
- foxes/models/wake_models/wind/turbopark.py +16 -13
- foxes/models/wake_superpositions/ti_linear.py +1 -1
- foxes/models/wake_superpositions/ti_max.py +1 -1
- foxes/models/wake_superpositions/ti_pow.py +1 -1
- foxes/models/wake_superpositions/ti_quadratic.py +1 -1
- foxes/models/wake_superpositions/ws_linear.py +8 -7
- foxes/models/wake_superpositions/ws_max.py +8 -7
- foxes/models/wake_superpositions/ws_pow.py +8 -7
- foxes/models/wake_superpositions/ws_product.py +5 -5
- foxes/models/wake_superpositions/ws_quadratic.py +8 -7
- foxes/output/__init__.py +4 -1
- foxes/output/farm_layout.py +16 -12
- foxes/output/farm_results_eval.py +1 -1
- foxes/output/flow_plots_2d/__init__.py +0 -1
- foxes/output/flow_plots_2d/flow_plots.py +70 -30
- foxes/output/grids.py +92 -22
- foxes/output/results_writer.py +2 -2
- foxes/output/rose_plot.py +3 -3
- foxes/output/seq_plugins/__init__.py +2 -0
- foxes/output/{flow_plots_2d → seq_plugins}/seq_flow_ani_plugin.py +64 -22
- foxes/output/seq_plugins/seq_wake_debug_plugin.py +145 -0
- foxes/output/slice_data.py +131 -111
- foxes/output/state_turbine_map.py +19 -14
- foxes/output/state_turbine_table.py +19 -19
- foxes/utils/__init__.py +1 -1
- foxes/utils/abl/neutral.py +2 -2
- foxes/utils/abl/stable.py +2 -2
- foxes/utils/abl/unstable.py +2 -2
- foxes/utils/data_book.py +1 -1
- foxes/utils/dev_utils.py +42 -0
- foxes/utils/dict.py +24 -1
- foxes/utils/exec_python.py +1 -1
- foxes/utils/factory.py +176 -53
- foxes/utils/geom2d/circle.py +1 -1
- foxes/utils/geom2d/polygon.py +1 -1
- foxes/utils/geopandas_utils.py +2 -2
- foxes/utils/load.py +2 -2
- foxes/utils/pandas_helpers.py +3 -2
- foxes/utils/wind_dir.py +0 -2
- foxes/utils/xarray_utils.py +24 -14
- foxes/variables.py +39 -2
- {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/METADATA +75 -33
- foxes-1.1.0.2.dist-info/RECORD +309 -0
- {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/WHEEL +1 -1
- foxes-1.1.0.2.dist-info/top_level.txt +4 -0
- tests/0_consistency/iterative/test_iterative.py +92 -0
- tests/0_consistency/partial_wakes/test_partial_wakes.py +90 -0
- tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +85 -0
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +103 -0
- tests/1_verification/flappy_0_6/abl_states/flappy/run.py +85 -0
- tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +87 -0
- tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +82 -0
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +82 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/flappy/run.py +92 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +93 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/flappy/run.py +92 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +96 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/flappy/run.py +94 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +122 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/flappy/run.py +94 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +122 -0
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/flappy/run.py +92 -0
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +93 -0
- tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +85 -0
- tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +130 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/flappy/run.py +96 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +116 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +93 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +99 -0
- tests/3_examples/test_examples.py +34 -0
- foxes/VERSION +0 -1
- foxes/output/flow_plots_2d.py +0 -0
- foxes/utils/geopandas_helpers.py +0 -294
- foxes/utils/runners/__init__.py +0 -1
- foxes/utils/runners/runners.py +0 -280
- foxes-0.8.2.dist-info/RECORD +0 -247
- foxes-0.8.2.dist-info/top_level.txt +0 -1
- foxes-0.8.2.dist-info/zip-safe +0 -1
- {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/LICENSE +0 -0
|
@@ -140,9 +140,9 @@ class Bastankhah2014(GaussianWakeModel):
|
|
|
140
140
|
downwind_index=downwind_index,
|
|
141
141
|
upcast=True,
|
|
142
142
|
)
|
|
143
|
-
|
|
143
|
+
|
|
144
144
|
# select targets:
|
|
145
|
-
st_sel = (x >
|
|
145
|
+
st_sel = (x > 1e-8) & (ct > 1e-8)
|
|
146
146
|
if np.any(st_sel):
|
|
147
147
|
# apply selection:
|
|
148
148
|
x = x[st_sel]
|
|
@@ -157,8 +157,9 @@ class Bastankhah2014(GaussianWakeModel):
|
|
|
157
157
|
fdata=fdata,
|
|
158
158
|
tdata=tdata,
|
|
159
159
|
downwind_index=downwind_index,
|
|
160
|
-
upcast=
|
|
161
|
-
|
|
160
|
+
upcast=False,
|
|
161
|
+
selection=st_sel,
|
|
162
|
+
)
|
|
162
163
|
|
|
163
164
|
# get k:
|
|
164
165
|
k = self.wake_k(
|
|
@@ -167,8 +168,9 @@ class Bastankhah2014(GaussianWakeModel):
|
|
|
167
168
|
fdata=fdata,
|
|
168
169
|
tdata=tdata,
|
|
169
170
|
downwind_index=downwind_index,
|
|
170
|
-
upcast=
|
|
171
|
-
|
|
171
|
+
upcast=False,
|
|
172
|
+
selection=st_sel,
|
|
173
|
+
)
|
|
172
174
|
|
|
173
175
|
# calculate sigma:
|
|
174
176
|
# beta = 0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct)
|
|
@@ -146,13 +146,13 @@ class Bastankhah2016Model(Model):
|
|
|
146
146
|
The k parameter values, shape: (n_states, n_targets)
|
|
147
147
|
|
|
148
148
|
"""
|
|
149
|
-
|
|
150
149
|
# store parameters:
|
|
151
150
|
out = {self.PARS: self.pars}
|
|
152
151
|
out[self.CHECK] = (
|
|
153
|
-
mdata
|
|
152
|
+
mdata.states_i0(counter=True),
|
|
153
|
+
mdata.n_states,
|
|
154
154
|
downwind_index,
|
|
155
|
-
x.
|
|
155
|
+
hash(x.tobytes()),
|
|
156
156
|
)
|
|
157
157
|
|
|
158
158
|
# get D:
|
|
@@ -180,7 +180,7 @@ class Bastankhah2016Model(Model):
|
|
|
180
180
|
)
|
|
181
181
|
|
|
182
182
|
# select targets:
|
|
183
|
-
st_sel = (x >
|
|
183
|
+
st_sel = (x > 1e-8) & (ct > 1e-8)
|
|
184
184
|
if np.any(st_sel):
|
|
185
185
|
# get ws:
|
|
186
186
|
ws = super().get_data(
|
|
@@ -191,7 +191,8 @@ class Bastankhah2016Model(Model):
|
|
|
191
191
|
fdata=fdata,
|
|
192
192
|
tdata=tdata,
|
|
193
193
|
downwind_index=downwind_index,
|
|
194
|
-
upcast=
|
|
194
|
+
upcast=False,
|
|
195
|
+
selection=st_sel,
|
|
195
196
|
)
|
|
196
197
|
|
|
197
198
|
# get TI:
|
|
@@ -203,7 +204,8 @@ class Bastankhah2016Model(Model):
|
|
|
203
204
|
fdata=fdata,
|
|
204
205
|
tdata=tdata,
|
|
205
206
|
downwind_index=downwind_index,
|
|
206
|
-
upcast=
|
|
207
|
+
upcast=False,
|
|
208
|
+
selection=st_sel,
|
|
207
209
|
)
|
|
208
210
|
|
|
209
211
|
# get alpha:
|
|
@@ -215,7 +217,8 @@ class Bastankhah2016Model(Model):
|
|
|
215
217
|
fdata=fdata,
|
|
216
218
|
tdata=tdata,
|
|
217
219
|
downwind_index=downwind_index,
|
|
218
|
-
upcast=
|
|
220
|
+
upcast=False,
|
|
221
|
+
selection=st_sel,
|
|
219
222
|
)
|
|
220
223
|
|
|
221
224
|
# get beta:
|
|
@@ -227,19 +230,16 @@ class Bastankhah2016Model(Model):
|
|
|
227
230
|
fdata=fdata,
|
|
228
231
|
tdata=tdata,
|
|
229
232
|
downwind_index=downwind_index,
|
|
230
|
-
upcast=
|
|
233
|
+
upcast=False,
|
|
234
|
+
selection=st_sel,
|
|
231
235
|
)
|
|
232
236
|
|
|
233
237
|
# apply filter:
|
|
234
238
|
x = x[st_sel]
|
|
235
239
|
D = D[st_sel]
|
|
236
240
|
ct = ct[st_sel]
|
|
237
|
-
ws = ws[st_sel]
|
|
238
|
-
ti = ti[st_sel]
|
|
239
241
|
k = k[st_sel]
|
|
240
242
|
gamma = gamma[st_sel]
|
|
241
|
-
alpha = alpha[st_sel]
|
|
242
|
-
beta = beta[st_sel]
|
|
243
243
|
|
|
244
244
|
# calc theta_c0, Eq. (6.12):
|
|
245
245
|
cosg = np.cos(gamma)
|
|
@@ -329,7 +329,7 @@ class Bastankhah2016Model(Model):
|
|
|
329
329
|
|
|
330
330
|
# update mdata:
|
|
331
331
|
out[self.ST_SEL] = st_sel
|
|
332
|
-
mdata
|
|
332
|
+
mdata.add(self.MDATA_KEY, out, None)
|
|
333
333
|
|
|
334
334
|
def has_data(self, mdata, downwind_index, x):
|
|
335
335
|
"""
|
|
@@ -352,9 +352,10 @@ class Bastankhah2016Model(Model):
|
|
|
352
352
|
|
|
353
353
|
"""
|
|
354
354
|
check = (
|
|
355
|
-
mdata
|
|
355
|
+
mdata.states_i0(counter=True),
|
|
356
|
+
mdata.n_states,
|
|
356
357
|
downwind_index,
|
|
357
|
-
x.
|
|
358
|
+
hash(x.tobytes()),
|
|
358
359
|
)
|
|
359
360
|
return self.MDATA_KEY in mdata and mdata[self.MDATA_KEY][self.CHECK] == check
|
|
360
361
|
|
|
@@ -551,7 +552,7 @@ class Bastankhah2016(DistSlicedWakeModel):
|
|
|
551
552
|
upcast=True,
|
|
552
553
|
downwind_index=downwind_index,
|
|
553
554
|
)
|
|
554
|
-
gamma
|
|
555
|
+
gamma = gamma * np.pi / 180
|
|
555
556
|
|
|
556
557
|
# get k:
|
|
557
558
|
k = self.wake_k(
|
|
@@ -88,7 +88,7 @@ class JensenWake(TopHatWakeModel):
|
|
|
88
88
|
fdata=fdata,
|
|
89
89
|
tdata=tdata,
|
|
90
90
|
downwind_index=downwind_index,
|
|
91
|
-
upcast=
|
|
91
|
+
upcast=True,
|
|
92
92
|
)
|
|
93
93
|
|
|
94
94
|
k = self.wake_k(
|
|
@@ -156,8 +156,9 @@ class JensenWake(TopHatWakeModel):
|
|
|
156
156
|
fdata=fdata,
|
|
157
157
|
tdata=tdata,
|
|
158
158
|
downwind_index=downwind_index,
|
|
159
|
-
upcast=
|
|
160
|
-
|
|
159
|
+
upcast=False,
|
|
160
|
+
selection=st_sel,
|
|
161
|
+
)
|
|
161
162
|
/ 2
|
|
162
163
|
)
|
|
163
164
|
|
|
@@ -160,7 +160,7 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
160
160
|
)
|
|
161
161
|
|
|
162
162
|
# select targets:
|
|
163
|
-
st_sel = (x > 1e-
|
|
163
|
+
st_sel = (x > 1e-8) & (ct > 1e-8)
|
|
164
164
|
if np.any(st_sel):
|
|
165
165
|
# apply selection:
|
|
166
166
|
x = x[st_sel]
|
|
@@ -175,8 +175,9 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
175
175
|
fdata=fdata,
|
|
176
176
|
tdata=tdata,
|
|
177
177
|
downwind_index=downwind_index,
|
|
178
|
-
upcast=
|
|
179
|
-
|
|
178
|
+
upcast=False,
|
|
179
|
+
selection=st_sel,
|
|
180
|
+
)
|
|
180
181
|
|
|
181
182
|
# get TI:
|
|
182
183
|
ati = self.get_data(
|
|
@@ -187,7 +188,8 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
187
188
|
fdata=fdata,
|
|
188
189
|
tdata=tdata,
|
|
189
190
|
downwind_index=downwind_index,
|
|
190
|
-
upcast=
|
|
191
|
+
upcast=False,
|
|
192
|
+
selection=st_sel,
|
|
191
193
|
)
|
|
192
194
|
|
|
193
195
|
# get k:
|
|
@@ -197,11 +199,10 @@ class TurbOParkWake(GaussianWakeModel):
|
|
|
197
199
|
fdata=fdata,
|
|
198
200
|
tdata=tdata,
|
|
199
201
|
downwind_index=downwind_index,
|
|
200
|
-
upcast=True,
|
|
201
202
|
amb_ti=ati,
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
upcast=False,
|
|
204
|
+
selection=st_sel,
|
|
205
|
+
)
|
|
205
206
|
|
|
206
207
|
# calculate sigma:
|
|
207
208
|
# beta = np.sqrt(0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct))
|
|
@@ -443,7 +444,7 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
443
444
|
)
|
|
444
445
|
|
|
445
446
|
# select targets:
|
|
446
|
-
st_sel = (x > 1e-
|
|
447
|
+
st_sel = (x > 1e-8) & (ct > 1e-8)
|
|
447
448
|
if np.any(st_sel):
|
|
448
449
|
# apply selection:
|
|
449
450
|
# x = x[st_sel]
|
|
@@ -458,8 +459,9 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
458
459
|
fdata=fdata,
|
|
459
460
|
tdata=tdata,
|
|
460
461
|
downwind_index=downwind_index,
|
|
461
|
-
upcast=
|
|
462
|
-
|
|
462
|
+
upcast=False,
|
|
463
|
+
selection=st_sel,
|
|
464
|
+
)
|
|
463
465
|
|
|
464
466
|
# get k:
|
|
465
467
|
k = self.wake_k(
|
|
@@ -468,8 +470,9 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
468
470
|
fdata=fdata,
|
|
469
471
|
tdata=tdata,
|
|
470
472
|
downwind_index=downwind_index,
|
|
471
|
-
upcast=
|
|
472
|
-
|
|
473
|
+
upcast=False,
|
|
474
|
+
selection=st_sel,
|
|
475
|
+
)
|
|
473
476
|
|
|
474
477
|
# calculate sigma:
|
|
475
478
|
# beta = np.sqrt(0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct))
|
|
@@ -63,7 +63,7 @@ class TILinear(WakeSuperposition):
|
|
|
63
63
|
The target point data
|
|
64
64
|
downwind_index: int
|
|
65
65
|
The index of the wake causing turbine
|
|
66
|
-
in the
|
|
66
|
+
in the downwind order
|
|
67
67
|
st_sel: numpy.ndarray of bool
|
|
68
68
|
The selection of targets, shape: (n_states, n_targets)
|
|
69
69
|
variable: str
|
|
@@ -63,7 +63,7 @@ class TIMax(WakeSuperposition):
|
|
|
63
63
|
The target point data
|
|
64
64
|
downwind_index: int
|
|
65
65
|
The index of the wake causing turbine
|
|
66
|
-
in the
|
|
66
|
+
in the downwind order
|
|
67
67
|
st_sel: numpy.ndarray of bool
|
|
68
68
|
The selection of targets, shape: (n_states, n_targets)
|
|
69
69
|
variable: str
|
|
@@ -70,7 +70,7 @@ class TIPow(WakeSuperposition):
|
|
|
70
70
|
The target point data
|
|
71
71
|
downwind_index: int
|
|
72
72
|
The index of the wake causing turbine
|
|
73
|
-
in the
|
|
73
|
+
in the downwind order
|
|
74
74
|
st_sel: numpy.ndarray of bool
|
|
75
75
|
The selection of targets, shape: (n_states, n_targets)
|
|
76
76
|
variable: str
|
|
@@ -63,7 +63,7 @@ class TIQuadratic(WakeSuperposition):
|
|
|
63
63
|
The target point data
|
|
64
64
|
downwind_index: int
|
|
65
65
|
The index of the wake causing turbine
|
|
66
|
-
in the
|
|
66
|
+
in the downwind order
|
|
67
67
|
st_sel: numpy.ndarray of bool
|
|
68
68
|
The selection of targets, shape: (n_states, n_targets)
|
|
69
69
|
variable: str
|
|
@@ -7,7 +7,7 @@ import foxes.constants as FC
|
|
|
7
7
|
|
|
8
8
|
class WSLinear(WakeSuperposition):
|
|
9
9
|
"""
|
|
10
|
-
Linear
|
|
10
|
+
Linear superposition of wind deficit results
|
|
11
11
|
|
|
12
12
|
Attributes
|
|
13
13
|
----------
|
|
@@ -94,7 +94,7 @@ class WSLinear(WakeSuperposition):
|
|
|
94
94
|
The target point data
|
|
95
95
|
downwind_index: int
|
|
96
96
|
The index of the wake causing turbine
|
|
97
|
-
in the
|
|
97
|
+
in the downwind order
|
|
98
98
|
st_sel: numpy.ndarray of bool
|
|
99
99
|
The selection of targets, shape: (n_states, n_targets)
|
|
100
100
|
variable: str
|
|
@@ -121,14 +121,15 @@ class WSLinear(WakeSuperposition):
|
|
|
121
121
|
if np.any(st_sel):
|
|
122
122
|
scale = self.get_data(
|
|
123
123
|
FV.AMB_REWS if self.scale_amb else FV.REWS,
|
|
124
|
-
FC.
|
|
124
|
+
FC.STATE_TARGET_TPOINT,
|
|
125
125
|
lookup="w",
|
|
126
126
|
algo=algo,
|
|
127
127
|
fdata=fdata,
|
|
128
128
|
tdata=tdata,
|
|
129
129
|
downwind_index=downwind_index,
|
|
130
|
-
upcast=
|
|
131
|
-
|
|
130
|
+
upcast=False,
|
|
131
|
+
selection=st_sel,
|
|
132
|
+
)
|
|
132
133
|
|
|
133
134
|
wake_delta[st_sel] += scale * wake_model_result
|
|
134
135
|
|
|
@@ -182,7 +183,7 @@ class WSLinear(WakeSuperposition):
|
|
|
182
183
|
|
|
183
184
|
class WSLinearLocal(WakeSuperposition):
|
|
184
185
|
"""
|
|
185
|
-
Local linear
|
|
186
|
+
Local linear superposition of wind deficit results
|
|
186
187
|
|
|
187
188
|
Attributes
|
|
188
189
|
----------
|
|
@@ -261,7 +262,7 @@ class WSLinearLocal(WakeSuperposition):
|
|
|
261
262
|
The target point data
|
|
262
263
|
downwind_index: int
|
|
263
264
|
The index of the wake causing turbine
|
|
264
|
-
in the
|
|
265
|
+
in the downwind order
|
|
265
266
|
st_sel: numpy.ndarray of bool
|
|
266
267
|
The selection of targets, shape: (n_states, n_targets)
|
|
267
268
|
variable: str
|
|
@@ -7,7 +7,7 @@ import foxes.constants as FC
|
|
|
7
7
|
|
|
8
8
|
class WSMax(WakeSuperposition):
|
|
9
9
|
"""
|
|
10
|
-
Max
|
|
10
|
+
Max superposition of wind deficit results
|
|
11
11
|
|
|
12
12
|
Attributes
|
|
13
13
|
----------
|
|
@@ -94,7 +94,7 @@ class WSMax(WakeSuperposition):
|
|
|
94
94
|
The target point data
|
|
95
95
|
downwind_index: int
|
|
96
96
|
The index of the wake causing turbine
|
|
97
|
-
in the
|
|
97
|
+
in the downwind order
|
|
98
98
|
st_sel: numpy.ndarray of bool
|
|
99
99
|
The selection of targets, shape: (n_states, n_targets)
|
|
100
100
|
variable: str
|
|
@@ -121,14 +121,15 @@ class WSMax(WakeSuperposition):
|
|
|
121
121
|
if np.any(st_sel):
|
|
122
122
|
scale = self.get_data(
|
|
123
123
|
FV.AMB_REWS if self.scale_amb else FV.REWS,
|
|
124
|
-
FC.
|
|
124
|
+
FC.STATE_TARGET_TPOINT,
|
|
125
125
|
lookup="w",
|
|
126
126
|
algo=algo,
|
|
127
127
|
fdata=fdata,
|
|
128
128
|
tdata=tdata,
|
|
129
129
|
downwind_index=downwind_index,
|
|
130
|
-
upcast=
|
|
131
|
-
|
|
130
|
+
upcast=False,
|
|
131
|
+
selection=st_sel,
|
|
132
|
+
)
|
|
132
133
|
|
|
133
134
|
wake_model_result = np.abs(scale * wake_model_result)
|
|
134
135
|
odelta = wake_delta[st_sel]
|
|
@@ -185,7 +186,7 @@ class WSMax(WakeSuperposition):
|
|
|
185
186
|
|
|
186
187
|
class WSMaxLocal(WakeSuperposition):
|
|
187
188
|
"""
|
|
188
|
-
Local max
|
|
189
|
+
Local max superposition of wind deficit results
|
|
189
190
|
|
|
190
191
|
Attributes
|
|
191
192
|
----------
|
|
@@ -264,7 +265,7 @@ class WSMaxLocal(WakeSuperposition):
|
|
|
264
265
|
The target point data
|
|
265
266
|
downwind_index: int
|
|
266
267
|
The index of the wake causing turbine
|
|
267
|
-
in the
|
|
268
|
+
in the downwind order
|
|
268
269
|
st_sel: numpy.ndarray of bool
|
|
269
270
|
The selection of targets, shape: (n_states, n_targets)
|
|
270
271
|
variable: str
|
|
@@ -7,7 +7,7 @@ import foxes.constants as FC
|
|
|
7
7
|
|
|
8
8
|
class WSPow(WakeSuperposition):
|
|
9
9
|
"""
|
|
10
|
-
Power
|
|
10
|
+
Power superposition of wind deficit results
|
|
11
11
|
|
|
12
12
|
Attributes
|
|
13
13
|
----------
|
|
@@ -99,7 +99,7 @@ class WSPow(WakeSuperposition):
|
|
|
99
99
|
The target point data
|
|
100
100
|
downwind_index: int
|
|
101
101
|
The index of the wake causing turbine
|
|
102
|
-
in the
|
|
102
|
+
in the downwind order
|
|
103
103
|
st_sel: numpy.ndarray of bool
|
|
104
104
|
The selection of targets, shape: (n_states, n_targets)
|
|
105
105
|
variable: str
|
|
@@ -126,14 +126,15 @@ class WSPow(WakeSuperposition):
|
|
|
126
126
|
if np.any(st_sel):
|
|
127
127
|
scale = self.get_data(
|
|
128
128
|
FV.AMB_REWS if self.scale_amb else FV.REWS,
|
|
129
|
-
FC.
|
|
129
|
+
FC.STATE_TARGET_TPOINT,
|
|
130
130
|
lookup="w",
|
|
131
131
|
algo=algo,
|
|
132
132
|
fdata=fdata,
|
|
133
133
|
tdata=tdata,
|
|
134
134
|
downwind_index=downwind_index,
|
|
135
|
-
upcast=
|
|
136
|
-
|
|
135
|
+
upcast=False,
|
|
136
|
+
selection=st_sel,
|
|
137
|
+
)
|
|
137
138
|
|
|
138
139
|
wake_delta[st_sel] += np.abs(scale * wake_model_result) ** self.pow
|
|
139
140
|
|
|
@@ -187,7 +188,7 @@ class WSPow(WakeSuperposition):
|
|
|
187
188
|
|
|
188
189
|
class WSPowLocal(WakeSuperposition):
|
|
189
190
|
"""
|
|
190
|
-
Local power
|
|
191
|
+
Local power superposition of wind deficit results
|
|
191
192
|
|
|
192
193
|
Attributes
|
|
193
194
|
----------
|
|
@@ -272,7 +273,7 @@ class WSPowLocal(WakeSuperposition):
|
|
|
272
273
|
The target point data
|
|
273
274
|
downwind_index: int
|
|
274
275
|
The index of the wake causing turbine
|
|
275
|
-
in the
|
|
276
|
+
in the downwind order
|
|
276
277
|
st_sel: numpy.ndarray of bool
|
|
277
278
|
The selection of targets, shape: (n_states, n_targets)
|
|
278
279
|
variable: str
|
|
@@ -7,7 +7,7 @@ import foxes.constants as FC
|
|
|
7
7
|
|
|
8
8
|
class WSProduct(WakeSuperposition):
|
|
9
9
|
"""
|
|
10
|
-
Product
|
|
10
|
+
Product superposition of wind deficit results
|
|
11
11
|
|
|
12
12
|
This is based on the idea that the dimensionless
|
|
13
13
|
wind deficit should be rescaled with the wake
|
|
@@ -95,7 +95,7 @@ class WSProduct(WakeSuperposition):
|
|
|
95
95
|
The target point data
|
|
96
96
|
downwind_index: int
|
|
97
97
|
The index of the wake causing turbine
|
|
98
|
-
in the
|
|
98
|
+
in the downwind order
|
|
99
99
|
st_sel: numpy.ndarray of bool
|
|
100
100
|
The selection of targets, shape: (n_states, n_targets)
|
|
101
101
|
variable: str
|
|
@@ -119,10 +119,10 @@ class WSProduct(WakeSuperposition):
|
|
|
119
119
|
f"Superposition '{self.name}': Expecting wind speed variable, got {variable}"
|
|
120
120
|
)
|
|
121
121
|
|
|
122
|
-
if np.
|
|
123
|
-
|
|
124
|
-
wake_delta[:] = 1
|
|
122
|
+
if np.max(np.abs(wake_delta)) < 1e-14:
|
|
123
|
+
wake_delta[:] = 1
|
|
125
124
|
|
|
125
|
+
if np.any(st_sel):
|
|
126
126
|
wake_delta[st_sel] *= 1 + wake_model_result
|
|
127
127
|
|
|
128
128
|
return wake_delta
|
|
@@ -7,7 +7,7 @@ import foxes.constants as FC
|
|
|
7
7
|
|
|
8
8
|
class WSQuadratic(WakeSuperposition):
|
|
9
9
|
"""
|
|
10
|
-
Quadratic
|
|
10
|
+
Quadratic superposition of wind deficit results
|
|
11
11
|
|
|
12
12
|
Attributes
|
|
13
13
|
----------
|
|
@@ -94,7 +94,7 @@ class WSQuadratic(WakeSuperposition):
|
|
|
94
94
|
The target point data
|
|
95
95
|
downwind_index: int
|
|
96
96
|
The index of the wake causing turbine
|
|
97
|
-
in the
|
|
97
|
+
in the downwind order
|
|
98
98
|
st_sel: numpy.ndarray of bool
|
|
99
99
|
The selection of targets, shape: (n_states, n_targets)
|
|
100
100
|
variable: str
|
|
@@ -121,14 +121,15 @@ class WSQuadratic(WakeSuperposition):
|
|
|
121
121
|
if np.any(st_sel):
|
|
122
122
|
scale = self.get_data(
|
|
123
123
|
FV.AMB_REWS if self.scale_amb else FV.REWS,
|
|
124
|
-
FC.
|
|
124
|
+
FC.STATE_TARGET_TPOINT,
|
|
125
125
|
lookup="w",
|
|
126
126
|
algo=algo,
|
|
127
127
|
fdata=fdata,
|
|
128
128
|
tdata=tdata,
|
|
129
129
|
downwind_index=downwind_index,
|
|
130
|
-
upcast=
|
|
131
|
-
|
|
130
|
+
upcast=False,
|
|
131
|
+
selection=st_sel,
|
|
132
|
+
)
|
|
132
133
|
|
|
133
134
|
wake_delta[st_sel] += (scale * wake_model_result) ** 2
|
|
134
135
|
|
|
@@ -182,7 +183,7 @@ class WSQuadratic(WakeSuperposition):
|
|
|
182
183
|
|
|
183
184
|
class WSQuadraticLocal(WakeSuperposition):
|
|
184
185
|
"""
|
|
185
|
-
Local quadratic
|
|
186
|
+
Local quadratic superposition of wind deficit results
|
|
186
187
|
|
|
187
188
|
Attributes
|
|
188
189
|
----------
|
|
@@ -261,7 +262,7 @@ class WSQuadraticLocal(WakeSuperposition):
|
|
|
261
262
|
The target point data
|
|
262
263
|
downwind_index: int
|
|
263
264
|
The index of the wake causing turbine
|
|
264
|
-
in the
|
|
265
|
+
in the downwind order
|
|
265
266
|
st_sel: numpy.ndarray of bool
|
|
266
267
|
The selection of targets, shape: (n_states, n_targets)
|
|
267
268
|
variable: str
|
foxes/output/__init__.py
CHANGED
|
@@ -16,5 +16,8 @@ from .slice_data import SliceData
|
|
|
16
16
|
from .rotor_point_plots import RotorPointPlot
|
|
17
17
|
from .state_turbine_table import StateTurbineTable
|
|
18
18
|
|
|
19
|
-
from .flow_plots_2d import FlowPlots2D
|
|
19
|
+
from .flow_plots_2d import FlowPlots2D
|
|
20
|
+
from .seq_plugins import SeqFlowAnimationPlugin, SeqWakeDebugPlugin
|
|
21
|
+
|
|
20
22
|
from . import grids
|
|
23
|
+
from . import seq_plugins
|
foxes/output/farm_layout.py
CHANGED
|
@@ -138,7 +138,7 @@ class FarmLayoutOutput(Output):
|
|
|
138
138
|
----------
|
|
139
139
|
color_by: str, optional
|
|
140
140
|
Set scatter color by variable results.
|
|
141
|
-
Use "mean_REWS" etc for means, also
|
|
141
|
+
Use "mean_REWS", etc, for means, also
|
|
142
142
|
min, max, sum. All wrt states
|
|
143
143
|
fontsize: int, optional
|
|
144
144
|
Size of the turbine numbers
|
|
@@ -288,8 +288,6 @@ class FarmLayoutOutput(Output):
|
|
|
288
288
|
"""
|
|
289
289
|
Writes the layout plot to file.
|
|
290
290
|
|
|
291
|
-
The kwargs are forwarded to self.get_figure
|
|
292
|
-
|
|
293
291
|
Parameters
|
|
294
292
|
----------
|
|
295
293
|
file_path: str
|
|
@@ -297,6 +295,8 @@ class FarmLayoutOutput(Output):
|
|
|
297
295
|
for default
|
|
298
296
|
fontsize: int
|
|
299
297
|
Size of the turbine numbers
|
|
298
|
+
kwargs: dict, optional
|
|
299
|
+
Additional arguments for get_figure()
|
|
300
300
|
|
|
301
301
|
"""
|
|
302
302
|
|
|
@@ -325,7 +325,7 @@ class FarmLayoutOutput(Output):
|
|
|
325
325
|
fname = file_path if file_path is not None else self.farm.name + ".xyh"
|
|
326
326
|
np.savetxt(fname, data, header="x y h")
|
|
327
327
|
|
|
328
|
-
def write_csv(self, file_path=None):
|
|
328
|
+
def write_csv(self, file_path=None, type_col=None, algo=None):
|
|
329
329
|
"""
|
|
330
330
|
Writes csv layout file.
|
|
331
331
|
|
|
@@ -334,6 +334,10 @@ class FarmLayoutOutput(Output):
|
|
|
334
334
|
file_path: str
|
|
335
335
|
The file into which to plot, or None
|
|
336
336
|
for default
|
|
337
|
+
type_col: str, optional
|
|
338
|
+
Name of the turbine type column
|
|
339
|
+
algo: foxes.core.Algorithm, optional
|
|
340
|
+
The algorithm, needed for turbine types
|
|
337
341
|
|
|
338
342
|
"""
|
|
339
343
|
|
|
@@ -341,17 +345,17 @@ class FarmLayoutOutput(Output):
|
|
|
341
345
|
|
|
342
346
|
fname = file_path if file_path is not None else self.farm.name + ".csv"
|
|
343
347
|
|
|
344
|
-
lyt = pd.DataFrame(
|
|
345
|
-
index=range(len(data)), columns=["id", "name", "x", "y", "h", "D"]
|
|
346
|
-
)
|
|
348
|
+
lyt = pd.DataFrame(index=range(len(data)), columns=["name", "x", "y", "h", "D"])
|
|
347
349
|
lyt.index.name = "index"
|
|
348
|
-
lyt["
|
|
349
|
-
lyt["
|
|
350
|
-
lyt["
|
|
351
|
-
lyt["
|
|
352
|
-
lyt["h"] = data[:, 2]
|
|
350
|
+
lyt["name"] = [t.name for t in self.farm.turbines]
|
|
351
|
+
lyt["x"] = np.round(data[:, 0], 4)
|
|
352
|
+
lyt["y"] = np.round(data[:, 1], 4)
|
|
353
|
+
lyt["h"] = np.round(data[:, 2], 4)
|
|
353
354
|
lyt["D"] = [t.D for t in self.farm.turbines]
|
|
354
355
|
|
|
356
|
+
if type_col is not None:
|
|
357
|
+
lyt[type_col] = [m.name for m in algo.farm_controller.turbine_types]
|
|
358
|
+
|
|
355
359
|
lyt.to_csv(fname)
|
|
356
360
|
|
|
357
361
|
def write_json(self, file_path=None):
|
|
@@ -381,7 +381,7 @@ class FarmResultsEval(Output):
|
|
|
381
381
|
algo: foxes.core.Algorithm, optional
|
|
382
382
|
The algorithm, for P_nominal lookup
|
|
383
383
|
annual: bool, optional
|
|
384
|
-
Flag for
|
|
384
|
+
Flag for returning annual results, by default False
|
|
385
385
|
ambient: bool, optional
|
|
386
386
|
Flag for ambient power, by default False
|
|
387
387
|
hours: int, optional
|