foxes 0.8.2__py3-none-any.whl → 1.0__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_RHB/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 +183 -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 +232 -101
- foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -6
- foxes/algorithms/downwind/models/init_farm_data.py +1 -1
- foxes/algorithms/downwind/models/point_wakes_calc.py +5 -6
- foxes/algorithms/downwind/models/reorder_farm_output.py +0 -1
- foxes/algorithms/downwind/models/set_amb_point_results.py +4 -2
- foxes/algorithms/iterative/iterative.py +73 -33
- foxes/algorithms/iterative/models/farm_wakes_calc.py +11 -6
- foxes/algorithms/sequential/models/plugin.py +1 -1
- foxes/algorithms/sequential/sequential.py +126 -255
- foxes/constants.py +17 -2
- foxes/core/__init__.py +1 -0
- foxes/core/algorithm.py +631 -146
- foxes/core/data.py +252 -20
- foxes/core/data_calc_model.py +13 -289
- foxes/core/engine.py +630 -0
- foxes/core/farm_controller.py +37 -9
- foxes/core/farm_data_model.py +15 -0
- foxes/core/model.py +133 -80
- foxes/core/point_data_model.py +15 -0
- foxes/core/rotor_model.py +27 -21
- foxes/core/states.py +16 -0
- foxes/core/turbine_type.py +28 -0
- foxes/core/wake_frame.py +22 -4
- foxes/core/wake_model.py +2 -3
- foxes/data/windio/windio_5turbines_timeseries.yaml +23 -1
- foxes/engines/__init__.py +16 -0
- foxes/engines/dask.py +975 -0
- foxes/engines/default.py +75 -0
- foxes/engines/futures.py +72 -0
- foxes/engines/mpi.py +38 -0
- foxes/engines/multiprocess.py +74 -0
- foxes/engines/numpy.py +185 -0
- foxes/engines/pool.py +263 -0
- foxes/engines/single.py +139 -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 +1 -1
- 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 +6 -0
- foxes/input/states/create/random_abl_states.py +1 -1
- foxes/input/states/field_data_nc.py +157 -32
- foxes/input/states/multi_height.py +127 -13
- foxes/input/states/one_point_flow.py +577 -0
- foxes/input/states/scan_ws.py +73 -2
- foxes/input/states/states_table.py +204 -35
- foxes/input/windio/__init__.py +1 -1
- foxes/input/windio/get_states.py +44 -23
- foxes/input/windio/read_attributes.py +41 -16
- foxes/input/windio/read_farm.py +116 -102
- foxes/input/windio/read_fields.py +13 -6
- foxes/input/windio/read_outputs.py +63 -22
- foxes/input/windio/runner.py +31 -17
- foxes/input/windio/windio.py +36 -22
- foxes/models/ground_models/wake_mirror.py +8 -4
- foxes/models/model_book.py +29 -18
- foxes/models/partial_wakes/rotor_points.py +3 -3
- foxes/models/rotor_models/centre.py +4 -0
- foxes/models/rotor_models/grid.py +22 -23
- foxes/models/rotor_models/levels.py +4 -5
- foxes/models/turbine_models/calculator.py +0 -2
- foxes/models/turbine_models/lookup_table.py +27 -2
- 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 +24 -0
- foxes/models/turbine_types/PCt_from_two.py +24 -0
- foxes/models/turbine_types/__init__.py +1 -0
- foxes/models/turbine_types/lookup.py +316 -0
- foxes/models/turbine_types/null_type.py +50 -0
- foxes/models/turbine_types/wsrho2PCt_from_two.py +24 -0
- foxes/models/turbine_types/wsti2PCt_from_two.py +24 -0
- 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 +23 -3
- foxes/models/wake_frames/rotor_wd.py +4 -2
- foxes/models/wake_frames/seq_dynamic_wakes.py +56 -63
- foxes/models/wake_frames/streamlines.py +19 -20
- foxes/models/wake_frames/timelines.py +328 -127
- foxes/models/wake_frames/yawed_wakes.py +4 -1
- foxes/models/wake_models/dist_sliced.py +1 -3
- foxes/models/wake_models/induction/rankine_half_body.py +4 -4
- foxes/models/wake_models/induction/rathmann.py +2 -2
- foxes/models/wake_models/induction/self_similar.py +2 -2
- foxes/models/wake_models/induction/vortex_sheet.py +2 -2
- foxes/models/wake_models/ti/iec_ti.py +34 -17
- foxes/models/wake_models/top_hat.py +1 -1
- foxes/models/wake_models/wind/bastankhah14.py +2 -2
- foxes/models/wake_models/wind/bastankhah16.py +8 -7
- foxes/models/wake_models/wind/jensen.py +1 -1
- foxes/models/wake_models/wind/turbopark.py +2 -2
- foxes/output/__init__.py +4 -1
- foxes/output/farm_layout.py +2 -2
- foxes/output/flow_plots_2d/__init__.py +0 -1
- foxes/output/flow_plots_2d/flow_plots.py +70 -30
- foxes/output/grids.py +91 -21
- foxes/output/seq_plugins/__init__.py +2 -0
- foxes/output/{flow_plots_2d → seq_plugins}/seq_flow_ani_plugin.py +62 -20
- foxes/output/seq_plugins/seq_wake_debug_plugin.py +145 -0
- foxes/output/slice_data.py +131 -111
- foxes/output/state_turbine_map.py +18 -13
- foxes/output/state_turbine_table.py +19 -19
- foxes/utils/__init__.py +1 -1
- foxes/utils/dev_utils.py +42 -0
- foxes/utils/dict.py +1 -1
- foxes/utils/factory.py +147 -52
- foxes/utils/pandas_helpers.py +4 -3
- foxes/utils/wind_dir.py +0 -2
- foxes/utils/xarray_utils.py +23 -13
- foxes/variables.py +37 -0
- {foxes-0.8.2.dist-info → foxes-1.0.dist-info}/METADATA +71 -33
- foxes-1.0.dist-info/RECORD +307 -0
- {foxes-0.8.2.dist-info → foxes-1.0.dist-info}/WHEEL +1 -1
- foxes-1.0.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/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.0.dist-info}/LICENSE +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import TurbineInductionModel
|
|
4
|
-
from foxes.utils import uv2wd, wd2uv
|
|
4
|
+
from foxes.utils import uv2wd, wd2uv, delta_wd
|
|
5
5
|
import foxes.variables as FV
|
|
6
6
|
import foxes.constants as FC
|
|
7
7
|
|
|
@@ -198,7 +198,7 @@ class RankineHalfBody(TurbineInductionModel):
|
|
|
198
198
|
xs = -np.sqrt(m / (4 * ws + 1e-15))
|
|
199
199
|
|
|
200
200
|
# set values out of body shape
|
|
201
|
-
st_sel = (ct >
|
|
201
|
+
st_sel = (ct > 1e-8) & ((RHB_shape < -1) | (x < xs))
|
|
202
202
|
if np.any(st_sel):
|
|
203
203
|
# apply selection
|
|
204
204
|
xyz = wake_coos[st_sel]
|
|
@@ -209,7 +209,7 @@ class RankineHalfBody(TurbineInductionModel):
|
|
|
209
209
|
wake_deltas["V"][st_sel] += vel_factor * xyz[:, 1]
|
|
210
210
|
|
|
211
211
|
# set values inside body shape
|
|
212
|
-
st_sel = (ct >
|
|
212
|
+
st_sel = (ct > 1e-8) & (RHB_shape >= -1) & (x >= xs) & (x <= 0)
|
|
213
213
|
if np.any(st_sel):
|
|
214
214
|
# apply selection
|
|
215
215
|
xyz = np.zeros_like(wake_coos[st_sel])
|
|
@@ -270,4 +270,4 @@ class RankineHalfBody(TurbineInductionModel):
|
|
|
270
270
|
new_wd = uv2wd(wind_vec)
|
|
271
271
|
new_ws = np.linalg.norm(wind_vec, axis=-1)
|
|
272
272
|
wake_deltas[FV.WS] += new_ws - amb_results[FV.WS]
|
|
273
|
-
wake_deltas[FV.WD] +=
|
|
273
|
+
wake_deltas[FV.WD] += delta_wd(amb_results[FV.WD], new_wd)
|
|
@@ -199,7 +199,7 @@ class Rathmann(TurbineInductionModel):
|
|
|
199
199
|
return sin_alpha * sin_beta * (1 + x_R**2)
|
|
200
200
|
|
|
201
201
|
# ws delta in front of rotor
|
|
202
|
-
sp_sel = (ct >
|
|
202
|
+
sp_sel = (ct > 1e-8) & (x_R <= 0)
|
|
203
203
|
if np.any(sp_sel):
|
|
204
204
|
xr = x_R[sp_sel]
|
|
205
205
|
a = self.induction.ct2a(ct[sp_sel])
|
|
@@ -209,7 +209,7 @@ class Rathmann(TurbineInductionModel):
|
|
|
209
209
|
# ws delta behind rotor
|
|
210
210
|
if not self.pre_rotor_only:
|
|
211
211
|
# mirror -blockage in rotor plane
|
|
212
|
-
sp_sel = (ct >
|
|
212
|
+
sp_sel = (ct > 1e-8) & (x_R > 0) & (r_R > 1)
|
|
213
213
|
if np.any(sp_sel):
|
|
214
214
|
xr = x_R[sp_sel]
|
|
215
215
|
a = self.induction.ct2a(ct[sp_sel])
|
|
@@ -214,7 +214,7 @@ class SelfSimilar(TurbineInductionModel):
|
|
|
214
214
|
r_R = np.linalg.norm(wake_coos[..., 1:3], axis=-1) / R
|
|
215
215
|
|
|
216
216
|
# select values
|
|
217
|
-
sp_sel = (ct >
|
|
217
|
+
sp_sel = (ct > 1e-8) & (x_R <= 0) # upstream
|
|
218
218
|
if np.any(sp_sel):
|
|
219
219
|
# velocity eqn 10 from [1]
|
|
220
220
|
xr = x_R[sp_sel]
|
|
@@ -225,7 +225,7 @@ class SelfSimilar(TurbineInductionModel):
|
|
|
225
225
|
|
|
226
226
|
# set area behind to mirrored value EXCEPT for area behind turbine
|
|
227
227
|
if not self.pre_rotor_only:
|
|
228
|
-
sp_sel = (ct >
|
|
228
|
+
sp_sel = (ct > 1e-8) & (x_R > 0) & (r_R > 1)
|
|
229
229
|
if np.any(sp_sel):
|
|
230
230
|
# velocity eqn 10 from [1]
|
|
231
231
|
xr = x_R[sp_sel]
|
|
@@ -183,7 +183,7 @@ class VortexSheet(TurbineInductionModel):
|
|
|
183
183
|
downwind_index=downwind_index,
|
|
184
184
|
)
|
|
185
185
|
|
|
186
|
-
sp_sel = (ct >
|
|
186
|
+
sp_sel = (ct > 1e-8) & (x <= 0)
|
|
187
187
|
ws_sel = ws[sp_sel]
|
|
188
188
|
ct_sel = ct[sp_sel]
|
|
189
189
|
r_sph_sel = r_sph[sp_sel]
|
|
@@ -203,7 +203,7 @@ class VortexSheet(TurbineInductionModel):
|
|
|
203
203
|
|
|
204
204
|
if not self.pre_rotor_only:
|
|
205
205
|
sp_sel = (
|
|
206
|
-
(ct >
|
|
206
|
+
(ct > 1e-8) & (x > 0) & (r > D / 2)
|
|
207
207
|
) # mirror in rotor plane and inverse blockage, but not directly behind rotor
|
|
208
208
|
ws_sel = ws[sp_sel]
|
|
209
209
|
ct_sel = ct[sp_sel]
|
|
@@ -54,24 +54,27 @@ class IECTIWake(TopHatWakeModel):
|
|
|
54
54
|
|
|
55
55
|
"""
|
|
56
56
|
super().__init__(superpositions={FV.TI: superposition}, induction=induction)
|
|
57
|
+
self.iec_type = iec_type
|
|
58
|
+
self.wake_k = None
|
|
57
59
|
|
|
58
|
-
if opening_angle is
|
|
60
|
+
if opening_angle is None:
|
|
61
|
+
self.wake_k = WakeK(**wake_k)
|
|
62
|
+
else:
|
|
59
63
|
if "k" in wake_k or "ka" in wake_k or "kb" in wake_k:
|
|
60
64
|
raise KeyError(
|
|
61
65
|
f"Can handle 'opening_angle' or ('k', 'ka', 'kb') parameters, not both"
|
|
62
66
|
)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
self.iec_type = iec_type
|
|
66
|
-
self.wake_k = WakeK(**wake_k)
|
|
67
|
+
self._k = float(np.tan(np.deg2rad(opening_angle / 2.0)))
|
|
67
68
|
|
|
68
69
|
def __repr__(self):
|
|
69
70
|
iname = (
|
|
70
71
|
self.induction if isinstance(self.induction, str) else self.induction.name
|
|
71
72
|
)
|
|
72
73
|
s = f"{type(self).__name__}"
|
|
73
|
-
s += f"({self.superpositions[FV.TI]}, induction={iname}
|
|
74
|
-
|
|
74
|
+
s += f"({self.superpositions[FV.TI]}, induction={iname}"
|
|
75
|
+
if self.wake_k is not None:
|
|
76
|
+
s += ", " + self.wake_k.repr()
|
|
77
|
+
s += ")"
|
|
75
78
|
return s
|
|
76
79
|
|
|
77
80
|
def sub_models(self):
|
|
@@ -84,7 +87,7 @@ class IECTIWake(TopHatWakeModel):
|
|
|
84
87
|
All sub models
|
|
85
88
|
|
|
86
89
|
"""
|
|
87
|
-
return [self.wake_k]
|
|
90
|
+
return [self.wake_k] if self.wake_k is not None else []
|
|
88
91
|
|
|
89
92
|
def new_wake_deltas(self, algo, mdata, fdata, tdata):
|
|
90
93
|
"""
|
|
@@ -147,15 +150,29 @@ class IECTIWake(TopHatWakeModel):
|
|
|
147
150
|
The wake radii, shape: (n_states, n_targets)
|
|
148
151
|
|
|
149
152
|
"""
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
153
|
+
if self.wake_k is None:
|
|
154
|
+
return self._k * x
|
|
155
|
+
else:
|
|
156
|
+
D = self.get_data(
|
|
157
|
+
FV.D,
|
|
158
|
+
FC.STATE_TARGET,
|
|
159
|
+
lookup="w",
|
|
160
|
+
algo=algo,
|
|
161
|
+
fdata=fdata,
|
|
162
|
+
tdata=tdata,
|
|
163
|
+
downwind_index=downwind_index,
|
|
164
|
+
upcast=True,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
k = self.wake_k(
|
|
168
|
+
FC.STATE_TARGET,
|
|
169
|
+
algo=algo,
|
|
170
|
+
fdata=fdata,
|
|
171
|
+
tdata=tdata,
|
|
172
|
+
upcast=True,
|
|
173
|
+
downwind_index=downwind_index,
|
|
174
|
+
)
|
|
175
|
+
return D / 2 + k * x
|
|
159
176
|
|
|
160
177
|
def calc_centreline(
|
|
161
178
|
self,
|
|
@@ -209,7 +209,7 @@ class TopHatWakeModel(AxisymmetricWakeModel):
|
|
|
209
209
|
wake_r = self.calc_wake_radius(algo, mdata, fdata, tdata, downwind_index, x, ct)
|
|
210
210
|
|
|
211
211
|
wdeltas = {}
|
|
212
|
-
st_sel = (
|
|
212
|
+
st_sel = (x > 1e-8) & (ct > 1e-8) & np.any(r < wake_r[:, :, None], axis=2)
|
|
213
213
|
if np.any(st_sel):
|
|
214
214
|
x = x[st_sel]
|
|
215
215
|
r = r[st_sel]
|
|
@@ -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]
|
|
@@ -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(
|
|
@@ -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
|
|
|
@@ -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]
|
|
@@ -443,7 +443,7 @@ class TurbOParkWakeIX(GaussianWakeModel):
|
|
|
443
443
|
)
|
|
444
444
|
|
|
445
445
|
# select targets:
|
|
446
|
-
st_sel = (x > 1e-
|
|
446
|
+
st_sel = (x > 1e-8) & (ct > 1e-8)
|
|
447
447
|
if np.any(st_sel):
|
|
448
448
|
# apply selection:
|
|
449
449
|
# x = x[st_sel]
|
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
|
@@ -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
|
|
|
@@ -482,6 +482,7 @@ class FlowPlots2D(SliceData):
|
|
|
482
482
|
ret_im=False,
|
|
483
483
|
animated=False,
|
|
484
484
|
rotor_color=None,
|
|
485
|
+
precalc=False,
|
|
485
486
|
**kwargs,
|
|
486
487
|
):
|
|
487
488
|
"""
|
|
@@ -527,6 +528,11 @@ class FlowPlots2D(SliceData):
|
|
|
527
528
|
Switch for usage for an animation
|
|
528
529
|
rotor_color: str, optional
|
|
529
530
|
Indicate the rotor orientation by a colored line
|
|
531
|
+
precalc: bool or tuple
|
|
532
|
+
Flag for pre-calculation run, adding an additional
|
|
533
|
+
generator call before the actual plot generations,
|
|
534
|
+
yields data, states, gdata. The same tuple can be given
|
|
535
|
+
for avoiding its calculation and picking up from there.
|
|
530
536
|
kwargs: dict, optional
|
|
531
537
|
Additional parameters for SliceData.get_states_data_xy
|
|
532
538
|
|
|
@@ -546,15 +552,21 @@ class FlowPlots2D(SliceData):
|
|
|
546
552
|
wdi = variables.index(FV.WD)
|
|
547
553
|
wsi = variables.index(FV.WS)
|
|
548
554
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
555
|
+
if isinstance(precalc, (tuple, list)):
|
|
556
|
+
data, states, gdata = precalc
|
|
557
|
+
else:
|
|
558
|
+
data, states, gdata = self.get_states_data_xy(
|
|
559
|
+
variables=variables,
|
|
560
|
+
vmin={var: vmin} if vmin is not None else {},
|
|
561
|
+
vmax={var: vmax} if vmax is not None else {},
|
|
562
|
+
data_format="numpy",
|
|
563
|
+
ret_states=True,
|
|
564
|
+
ret_grid=True,
|
|
565
|
+
**kwargs,
|
|
566
|
+
)
|
|
567
|
+
if precalc:
|
|
568
|
+
yield data, states, gdata
|
|
569
|
+
|
|
558
570
|
x_pos, y_pos, z_pos, __ = gdata
|
|
559
571
|
|
|
560
572
|
# define wind vector arrows:
|
|
@@ -573,8 +585,12 @@ class FlowPlots2D(SliceData):
|
|
|
573
585
|
|
|
574
586
|
# loop over states:
|
|
575
587
|
for si, s in enumerate(states):
|
|
576
|
-
if animated and si
|
|
588
|
+
if animated and si == 0:
|
|
589
|
+
vmin = vmin if vmin is not None else np.min(data[..., vi])
|
|
590
|
+
vmax = vmax if vmax is not None else np.max(data[..., vi])
|
|
591
|
+
elif animated and si > 0:
|
|
577
592
|
add_bar = False
|
|
593
|
+
|
|
578
594
|
if not animated and title is None:
|
|
579
595
|
ttl = f"State {s}"
|
|
580
596
|
ttl += f", z = {int(np.round(z_pos))} m"
|
|
@@ -652,6 +668,7 @@ class FlowPlots2D(SliceData):
|
|
|
652
668
|
ret_im=False,
|
|
653
669
|
animated=False,
|
|
654
670
|
rotor_color=None,
|
|
671
|
+
precalc=False,
|
|
655
672
|
**kwargs,
|
|
656
673
|
):
|
|
657
674
|
"""
|
|
@@ -699,6 +716,11 @@ class FlowPlots2D(SliceData):
|
|
|
699
716
|
Switch for usage for an animation
|
|
700
717
|
rotor_color: str, optional
|
|
701
718
|
Indicate the rotor orientation by a colored line
|
|
719
|
+
precalc: bool or tuple
|
|
720
|
+
Flag for pre-calculation run, adding an additional
|
|
721
|
+
generator call before the actual plot generations,
|
|
722
|
+
yields data, states, gdata. The same tuple can be given
|
|
723
|
+
for avoiding its calculation and picking up from there.
|
|
702
724
|
kwargs: dict, optional
|
|
703
725
|
Additional parameters for SliceData.get_states_data_xz
|
|
704
726
|
|
|
@@ -718,16 +740,22 @@ class FlowPlots2D(SliceData):
|
|
|
718
740
|
wdi = variables.index(FV.WD)
|
|
719
741
|
wsi = variables.index(FV.WS)
|
|
720
742
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
743
|
+
if isinstance(precalc, (tuple, list)):
|
|
744
|
+
data, states, gdata = precalc
|
|
745
|
+
else:
|
|
746
|
+
data, states, gdata = self.get_states_data_xz(
|
|
747
|
+
variables=variables,
|
|
748
|
+
vmin={var: vmin} if vmin is not None else {},
|
|
749
|
+
vmax={var: vmax} if vmax is not None else {},
|
|
750
|
+
data_format="numpy",
|
|
751
|
+
ret_states=True,
|
|
752
|
+
ret_grid=True,
|
|
753
|
+
x_direction=x_direction,
|
|
754
|
+
**kwargs,
|
|
755
|
+
)
|
|
756
|
+
if precalc:
|
|
757
|
+
yield data, states, gdata
|
|
758
|
+
|
|
731
759
|
x_pos, y_pos, z_pos, __ = gdata
|
|
732
760
|
|
|
733
761
|
# define wind vector arrows:
|
|
@@ -826,6 +854,7 @@ class FlowPlots2D(SliceData):
|
|
|
826
854
|
ret_im=False,
|
|
827
855
|
animated=False,
|
|
828
856
|
rotor_color=None,
|
|
857
|
+
precalc=False,
|
|
829
858
|
**kwargs,
|
|
830
859
|
):
|
|
831
860
|
"""
|
|
@@ -873,6 +902,11 @@ class FlowPlots2D(SliceData):
|
|
|
873
902
|
Switch for usage for an animation
|
|
874
903
|
rotor_color: str, optional
|
|
875
904
|
Indicate the rotor orientation by a colored line
|
|
905
|
+
precalc: bool or tuple
|
|
906
|
+
Flag for pre-calculation run, adding an additional
|
|
907
|
+
generator call before the actual plot generations,
|
|
908
|
+
yields data, states, gdata. The same tuple can be given
|
|
909
|
+
for avoiding its calculation and picking up from there.
|
|
876
910
|
kwargs: dict, optional
|
|
877
911
|
Additional parameters for SliceData.get_states_data_yz
|
|
878
912
|
|
|
@@ -892,16 +926,22 @@ class FlowPlots2D(SliceData):
|
|
|
892
926
|
wdi = variables.index(FV.WD)
|
|
893
927
|
wsi = variables.index(FV.WS)
|
|
894
928
|
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
929
|
+
if isinstance(precalc, (tuple, list)):
|
|
930
|
+
data, states, gdata = precalc
|
|
931
|
+
else:
|
|
932
|
+
data, states, gdata = self.get_states_data_yz(
|
|
933
|
+
variables=variables,
|
|
934
|
+
vmin={var: vmin} if vmin is not None else {},
|
|
935
|
+
vmax={var: vmax} if vmax is not None else {},
|
|
936
|
+
data_format="numpy",
|
|
937
|
+
ret_states=True,
|
|
938
|
+
ret_grid=True,
|
|
939
|
+
x_direction=x_direction,
|
|
940
|
+
**kwargs,
|
|
941
|
+
)
|
|
942
|
+
if precalc:
|
|
943
|
+
yield data, states, gdata
|
|
944
|
+
|
|
905
945
|
x_pos, y_pos, z_pos, __ = gdata
|
|
906
946
|
|
|
907
947
|
# define wind vector arrows:
|