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
|
@@ -81,7 +81,6 @@ class StatesTable(States):
|
|
|
81
81
|
"""
|
|
82
82
|
super().__init__()
|
|
83
83
|
|
|
84
|
-
self.data_source = data_source
|
|
85
84
|
self.ovars = output_vars
|
|
86
85
|
self.rpars = pd_read_pars
|
|
87
86
|
self.var2col = var2col
|
|
@@ -95,11 +94,30 @@ class StatesTable(States):
|
|
|
95
94
|
f"States '{self.name}': Cannot handle both 'states_sel' and 'states_loc', please pick one"
|
|
96
95
|
)
|
|
97
96
|
|
|
98
|
-
self._weights = None
|
|
99
97
|
self._N = None
|
|
100
98
|
self._tvars = None
|
|
101
99
|
self._profiles = None
|
|
102
100
|
|
|
101
|
+
self._data_source = data_source
|
|
102
|
+
self.__weights = None
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def data_source(self):
|
|
106
|
+
"""
|
|
107
|
+
The data source
|
|
108
|
+
|
|
109
|
+
Returns
|
|
110
|
+
-------
|
|
111
|
+
s: object
|
|
112
|
+
The data source
|
|
113
|
+
|
|
114
|
+
"""
|
|
115
|
+
if self.running:
|
|
116
|
+
raise ValueError(
|
|
117
|
+
f"States '{self.name}': Cannot access data_source while running"
|
|
118
|
+
)
|
|
119
|
+
return self._data_source
|
|
120
|
+
|
|
103
121
|
def reset(self, algo=None, states_sel=None, states_loc=None, verbosity=0):
|
|
104
122
|
"""
|
|
105
123
|
Reset the states, optionally select states
|
|
@@ -164,7 +182,6 @@ class StatesTable(States):
|
|
|
164
182
|
Names of all sub models
|
|
165
183
|
|
|
166
184
|
"""
|
|
167
|
-
|
|
168
185
|
return list(self._profiles.values())
|
|
169
186
|
|
|
170
187
|
def load_data(self, algo, verbosity=0):
|
|
@@ -202,7 +219,7 @@ class StatesTable(States):
|
|
|
202
219
|
print(
|
|
203
220
|
f"States '{self.name}': Reading static data '{self.data_source}' from context '{STATES}'"
|
|
204
221
|
)
|
|
205
|
-
self.
|
|
222
|
+
self._data_source = algo.dbook.get_file_path(
|
|
206
223
|
STATES, self.data_source, check_raw=False
|
|
207
224
|
)
|
|
208
225
|
if verbosity:
|
|
@@ -218,21 +235,21 @@ class StatesTable(States):
|
|
|
218
235
|
elif self.states_loc is not None:
|
|
219
236
|
data = data.loc[self.states_loc]
|
|
220
237
|
self._N = len(data.index)
|
|
221
|
-
self.
|
|
238
|
+
self.__inds = data.index.to_numpy()
|
|
222
239
|
|
|
223
240
|
col_w = self.var2col.get(FV.WEIGHT, FV.WEIGHT)
|
|
224
|
-
self.
|
|
241
|
+
self.__weights = np.zeros((self._N, algo.n_turbines), dtype=FC.DTYPE)
|
|
225
242
|
if col_w in data:
|
|
226
|
-
self.
|
|
243
|
+
self.__weights[:] = data[col_w].to_numpy()[:, None]
|
|
227
244
|
elif FV.WEIGHT in self.var2col:
|
|
228
245
|
raise KeyError(
|
|
229
246
|
f"Weight variable '{col_w}' defined in var2col, but not found in states table columns {data.columns}"
|
|
230
247
|
)
|
|
231
248
|
else:
|
|
232
|
-
self.
|
|
249
|
+
self.__weights[:] = 1.0 / self._N
|
|
233
250
|
if isorg:
|
|
234
251
|
data = data.copy()
|
|
235
|
-
data[col_w] = self.
|
|
252
|
+
data[col_w] = self.__weights[:, 0]
|
|
236
253
|
|
|
237
254
|
tcols = []
|
|
238
255
|
for v in self._tvars:
|
|
@@ -273,7 +290,9 @@ class StatesTable(States):
|
|
|
273
290
|
The index labels of states, or None for default integers
|
|
274
291
|
|
|
275
292
|
"""
|
|
276
|
-
|
|
293
|
+
if self.running:
|
|
294
|
+
raise ValueError(f"States '{self.name}': Cannot access index while running")
|
|
295
|
+
return self.__inds
|
|
277
296
|
|
|
278
297
|
def output_point_vars(self, algo):
|
|
279
298
|
"""
|
|
@@ -307,10 +326,87 @@ class StatesTable(States):
|
|
|
307
326
|
The weights, shape: (n_states, n_turbines)
|
|
308
327
|
|
|
309
328
|
"""
|
|
310
|
-
|
|
329
|
+
if self.running:
|
|
330
|
+
raise ValueError(
|
|
331
|
+
f"States '{self.name}': Cannot access weights while running"
|
|
332
|
+
)
|
|
333
|
+
return self.__weights
|
|
334
|
+
|
|
335
|
+
def set_running(
|
|
336
|
+
self,
|
|
337
|
+
algo,
|
|
338
|
+
data_stash,
|
|
339
|
+
sel=None,
|
|
340
|
+
isel=None,
|
|
341
|
+
verbosity=0,
|
|
342
|
+
):
|
|
343
|
+
"""
|
|
344
|
+
Sets this model status to running, and moves
|
|
345
|
+
all large data to stash.
|
|
346
|
+
|
|
347
|
+
The stashed data will be returned by the
|
|
348
|
+
unset_running() function after running calculations.
|
|
349
|
+
|
|
350
|
+
Parameters
|
|
351
|
+
----------
|
|
352
|
+
algo: foxes.core.Algorithm
|
|
353
|
+
The calculation algorithm
|
|
354
|
+
data_stash: dict
|
|
355
|
+
Large data stash, this function adds data here.
|
|
356
|
+
Key: model name. Value: dict, large model data
|
|
357
|
+
sel: dict, optional
|
|
358
|
+
The subset selection dictionary
|
|
359
|
+
isel: dict, optional
|
|
360
|
+
The index subset selection dictionary
|
|
361
|
+
verbosity: int
|
|
362
|
+
The verbosity level, 0 = silent
|
|
363
|
+
|
|
364
|
+
"""
|
|
365
|
+
super().set_running(algo, data_stash, sel, isel, verbosity)
|
|
366
|
+
|
|
367
|
+
data_stash[self.name] = dict(
|
|
368
|
+
data_source=self._data_source,
|
|
369
|
+
weights=self.__weights,
|
|
370
|
+
inds=self.__inds,
|
|
371
|
+
)
|
|
372
|
+
del self._data_source, self.__weights, self.__inds
|
|
373
|
+
|
|
374
|
+
def unset_running(
|
|
375
|
+
self,
|
|
376
|
+
algo,
|
|
377
|
+
data_stash,
|
|
378
|
+
sel=None,
|
|
379
|
+
isel=None,
|
|
380
|
+
verbosity=0,
|
|
381
|
+
):
|
|
382
|
+
"""
|
|
383
|
+
Sets this model status to not running, recovering large data
|
|
384
|
+
from stash
|
|
385
|
+
|
|
386
|
+
Parameters
|
|
387
|
+
----------
|
|
388
|
+
algo: foxes.core.Algorithm
|
|
389
|
+
The calculation algorithm
|
|
390
|
+
data_stash: dict
|
|
391
|
+
Large data stash, this function adds data here.
|
|
392
|
+
Key: model name. Value: dict, large model data
|
|
393
|
+
sel: dict, optional
|
|
394
|
+
The subset selection dictionary
|
|
395
|
+
isel: dict, optional
|
|
396
|
+
The index subset selection dictionary
|
|
397
|
+
verbosity: int
|
|
398
|
+
The verbosity level, 0 = silent
|
|
399
|
+
|
|
400
|
+
"""
|
|
401
|
+
super().unset_running(algo, data_stash, sel, isel, verbosity)
|
|
402
|
+
|
|
403
|
+
data = data_stash[self.name]
|
|
404
|
+
self._data_source = data.pop("data_source")
|
|
405
|
+
self.__weights = data.pop("weights")
|
|
406
|
+
self.__inds = data.pop("inds")
|
|
311
407
|
|
|
312
408
|
def calculate(self, algo, mdata, fdata, tdata):
|
|
313
|
-
"""
|
|
409
|
+
"""
|
|
314
410
|
The main model calculation.
|
|
315
411
|
|
|
316
412
|
This function is executed on a single chunk of data,
|
|
@@ -368,7 +464,7 @@ class StatesTable(States):
|
|
|
368
464
|
The verbosity level
|
|
369
465
|
|
|
370
466
|
"""
|
|
371
|
-
self.
|
|
467
|
+
self.__weights = None
|
|
372
468
|
self._N = None
|
|
373
469
|
self._tvars = None
|
|
374
470
|
|
|
@@ -412,11 +508,11 @@ class TabStates(StatesTable):
|
|
|
412
508
|
"""
|
|
413
509
|
self._normalize = normalize
|
|
414
510
|
if isinstance(data_source, Dataset):
|
|
415
|
-
self.
|
|
416
|
-
self.
|
|
511
|
+
self.__tab_source = None
|
|
512
|
+
self.__tab_data = data_source
|
|
417
513
|
elif isinstance(data_source, (str, Path)):
|
|
418
|
-
self.
|
|
419
|
-
self.
|
|
514
|
+
self.__tab_source = data_source
|
|
515
|
+
self.__tab_data = None
|
|
420
516
|
else:
|
|
421
517
|
raise TypeError(
|
|
422
518
|
f"Expecting str, Path or xarray.Dataset as data_source, got {type(data_source)}"
|
|
@@ -448,47 +544,47 @@ class TabStates(StatesTable):
|
|
|
448
544
|
|
|
449
545
|
"""
|
|
450
546
|
if self.data_source is None:
|
|
451
|
-
if self.
|
|
452
|
-
if not Path(self.
|
|
547
|
+
if self.__tab_data is None:
|
|
548
|
+
if not Path(self.__tab_source).is_file():
|
|
453
549
|
if verbosity:
|
|
454
550
|
print(
|
|
455
|
-
f"States '{self.name}': Reading static data '{self.
|
|
551
|
+
f"States '{self.name}': Reading static data '{self.__tab_source}' from context '{STATES}'"
|
|
456
552
|
)
|
|
457
|
-
self.
|
|
458
|
-
STATES, self.
|
|
553
|
+
self.__tab_source = algo.dbook.get_file_path(
|
|
554
|
+
STATES, self.__tab_source, check_raw=False
|
|
459
555
|
)
|
|
460
556
|
if verbosity:
|
|
461
|
-
print(f"Path: {self.
|
|
557
|
+
print(f"Path: {self.__tab_source}")
|
|
462
558
|
elif verbosity:
|
|
463
|
-
print(f"States '{self.name}': Reading file {self.
|
|
464
|
-
self.
|
|
559
|
+
print(f"States '{self.name}': Reading file {self.__tab_source}")
|
|
560
|
+
self.__tab_data = read_tab_file(self.__tab_source, self._normalize)
|
|
465
561
|
|
|
466
|
-
a = self.
|
|
467
|
-
b = self.
|
|
562
|
+
a = self.__tab_data.attrs["factor_ws"]
|
|
563
|
+
b = self.__tab_data.attrs["shift_wd"]
|
|
468
564
|
if b != 0.0:
|
|
469
565
|
raise ValueError(
|
|
470
566
|
f"{self.name}: shift_wd = {b} is not supported, expecting zero"
|
|
471
567
|
)
|
|
472
568
|
|
|
473
|
-
wd0 = self.
|
|
569
|
+
wd0 = self.__tab_data["wd"].to_numpy()
|
|
474
570
|
ws0 = a * np.append(
|
|
475
|
-
np.array([0], dtype=FC.DTYPE), self.
|
|
571
|
+
np.array([0], dtype=FC.DTYPE), self.__tab_data["ws"].to_numpy()
|
|
476
572
|
)
|
|
477
573
|
ws0 = 0.5 * (ws0[:-1] + ws0[1:])
|
|
478
574
|
|
|
479
|
-
n_ws = self.
|
|
480
|
-
n_wd = self.
|
|
575
|
+
n_ws = self.__tab_data.sizes["ws"]
|
|
576
|
+
n_wd = self.__tab_data.sizes["wd"]
|
|
481
577
|
ws = np.zeros((n_ws, n_wd), dtype=FC.DTYPE)
|
|
482
578
|
wd = np.zeros((n_ws, n_wd), dtype=FC.DTYPE)
|
|
483
579
|
ws[:] = ws0[:, None]
|
|
484
580
|
wd[:] = wd0[None, :]
|
|
485
581
|
|
|
486
|
-
wd_freq = self.
|
|
487
|
-
weights = self.
|
|
582
|
+
wd_freq = self.__tab_data["wd_freq"].to_numpy() / 100
|
|
583
|
+
weights = self.__tab_data["ws_freq"].to_numpy() * wd_freq[None, :] / 1000
|
|
488
584
|
|
|
489
585
|
sel = weights > 0
|
|
490
586
|
|
|
491
|
-
self.
|
|
587
|
+
self._data_source = pd.DataFrame(
|
|
492
588
|
index=np.arange(np.sum(sel)),
|
|
493
589
|
data={
|
|
494
590
|
FV.WS: ws[sel],
|
|
@@ -496,6 +592,79 @@ class TabStates(StatesTable):
|
|
|
496
592
|
FV.WEIGHT: weights[sel],
|
|
497
593
|
},
|
|
498
594
|
)
|
|
499
|
-
self.
|
|
595
|
+
self._data_source.index.name = FC.STATE
|
|
500
596
|
|
|
501
597
|
return super().load_data(algo, verbosity)
|
|
598
|
+
|
|
599
|
+
def set_running(
|
|
600
|
+
self,
|
|
601
|
+
algo,
|
|
602
|
+
data_stash,
|
|
603
|
+
sel=None,
|
|
604
|
+
isel=None,
|
|
605
|
+
verbosity=0,
|
|
606
|
+
):
|
|
607
|
+
"""
|
|
608
|
+
Sets this model status to running, and moves
|
|
609
|
+
all large data to stash.
|
|
610
|
+
|
|
611
|
+
The stashed data will be returned by the
|
|
612
|
+
unset_running() function after running calculations.
|
|
613
|
+
|
|
614
|
+
Parameters
|
|
615
|
+
----------
|
|
616
|
+
algo: foxes.core.Algorithm
|
|
617
|
+
The calculation algorithm
|
|
618
|
+
data_stash: dict
|
|
619
|
+
Large data stash, this function adds data here.
|
|
620
|
+
Key: model name. Value: dict, large model data
|
|
621
|
+
sel: dict, optional
|
|
622
|
+
The subset selection dictionary
|
|
623
|
+
isel: dict, optional
|
|
624
|
+
The index subset selection dictionary
|
|
625
|
+
verbosity: int
|
|
626
|
+
The verbosity level, 0 = silent
|
|
627
|
+
|
|
628
|
+
"""
|
|
629
|
+
super().set_running(algo, data_stash, sel, isel, verbosity)
|
|
630
|
+
|
|
631
|
+
data_stash[self.name].update(
|
|
632
|
+
dict(
|
|
633
|
+
tab_source=self.__tab_source,
|
|
634
|
+
tab_data=self.__tab_data,
|
|
635
|
+
)
|
|
636
|
+
)
|
|
637
|
+
del self.__tab_source, self.__tab_data
|
|
638
|
+
|
|
639
|
+
def unset_running(
|
|
640
|
+
self,
|
|
641
|
+
algo,
|
|
642
|
+
data_stash,
|
|
643
|
+
sel=None,
|
|
644
|
+
isel=None,
|
|
645
|
+
verbosity=0,
|
|
646
|
+
):
|
|
647
|
+
"""
|
|
648
|
+
Sets this model status to not running, recovering large data
|
|
649
|
+
from stash
|
|
650
|
+
|
|
651
|
+
Parameters
|
|
652
|
+
----------
|
|
653
|
+
algo: foxes.core.Algorithm
|
|
654
|
+
The calculation algorithm
|
|
655
|
+
data_stash: dict
|
|
656
|
+
Large data stash, this function adds data here.
|
|
657
|
+
Key: model name. Value: dict, large model data
|
|
658
|
+
sel: dict, optional
|
|
659
|
+
The subset selection dictionary
|
|
660
|
+
isel: dict, optional
|
|
661
|
+
The index subset selection dictionary
|
|
662
|
+
verbosity: int
|
|
663
|
+
The verbosity level, 0 = silent
|
|
664
|
+
|
|
665
|
+
"""
|
|
666
|
+
super().unset_running(algo, data_stash, sel, isel, verbosity)
|
|
667
|
+
|
|
668
|
+
data = data_stash[self.name]
|
|
669
|
+
self.__tab_source = data.pop("tab_source")
|
|
670
|
+
self.__tab_data = data.pop("tab_data")
|
foxes/input/windio/__init__.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Functions for
|
|
2
|
+
Functions for using windIO yaml files as input.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from .windio import read_windio
|
|
6
6
|
from .read_fields import wio2foxes, foxes2wio
|
|
7
7
|
from .get_states import get_states
|
|
8
|
-
from .read_farm import
|
|
8
|
+
from .read_farm import read_turbine_types, read_layout
|
|
9
9
|
from .read_attributes import read_attributes
|
|
10
10
|
from .read_outputs import read_outputs
|
|
11
11
|
from .runner import WindioRunner
|
foxes/input/windio/get_states.py
CHANGED
|
@@ -7,14 +7,18 @@ from foxes.core import States
|
|
|
7
7
|
import foxes.constants as FC
|
|
8
8
|
import foxes.variables as FV
|
|
9
9
|
|
|
10
|
+
|
|
10
11
|
def _get_profiles(coords, fields, dims, ovars, fixval, verbosity):
|
|
11
12
|
"""Read ABL profiles information
|
|
12
13
|
:group: input.windio
|
|
13
14
|
"""
|
|
14
15
|
profiles = {}
|
|
15
16
|
if FV.Z0 in fields:
|
|
16
|
-
if FV.H not in fields
|
|
17
|
-
|
|
17
|
+
if FV.H not in fields:
|
|
18
|
+
if verbosity > 0:
|
|
19
|
+
print(
|
|
20
|
+
f"Ignoring '{FV.Z0}', since no reference_height found. No ABL profile activated."
|
|
21
|
+
)
|
|
18
22
|
elif FV.MOL in fields:
|
|
19
23
|
ovars.append(FV.MOL)
|
|
20
24
|
fixval[FV.H] = fields[FV.H]
|
|
@@ -23,14 +27,20 @@ def _get_profiles(coords, fields, dims, ovars, fixval, verbosity):
|
|
|
23
27
|
fixval[FV.H] = fields[FV.H]
|
|
24
28
|
profiles = {FV.WS: "ABLLogNeutralWsProfile"}
|
|
25
29
|
elif FV.H in fields and verbosity > 0:
|
|
26
|
-
print(
|
|
30
|
+
print(
|
|
31
|
+
f"Ignoring '{FV.H}', since no '{FV.Z0}' data found. No ABL profile activated."
|
|
32
|
+
)
|
|
27
33
|
if len(profiles) and verbosity > 2:
|
|
28
|
-
print(
|
|
29
|
-
|
|
34
|
+
print(
|
|
35
|
+
f" Selecting ABL profile '{profiles[FV.WS]}', {FV.H} = {fields[FV.H]} m"
|
|
36
|
+
)
|
|
37
|
+
|
|
30
38
|
return profiles
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _get_SingleStateStates(
|
|
42
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
43
|
+
):
|
|
34
44
|
"""Try to generate single state parameters
|
|
35
45
|
:group: input.windio
|
|
36
46
|
"""
|
|
@@ -66,8 +76,10 @@ def _get_SingleStateStates(coords, fields, dims, states_dict,
|
|
|
66
76
|
)
|
|
67
77
|
return True
|
|
68
78
|
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
|
|
80
|
+
def _get_Timeseries(
|
|
81
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
82
|
+
):
|
|
71
83
|
"""Try to generate time series parameters
|
|
72
84
|
:group: input.windio
|
|
73
85
|
"""
|
|
@@ -100,24 +112,28 @@ def _get_Timeseries(coords, fields, dims, states_dict,
|
|
|
100
112
|
return True
|
|
101
113
|
return False
|
|
102
114
|
|
|
103
|
-
|
|
104
|
-
|
|
115
|
+
|
|
116
|
+
def _get_MultiHeightNCTimeseries(
|
|
117
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
118
|
+
):
|
|
105
119
|
"""Try to generate time series parameters
|
|
106
120
|
:group: input.windio
|
|
107
121
|
"""
|
|
108
122
|
if len(coords) == 2 and FC.TIME in coords and FV.H in coords:
|
|
109
123
|
if verbosity > 2:
|
|
110
124
|
print(" selecting class 'MultiHeightNCTimeseries'")
|
|
111
|
-
|
|
125
|
+
|
|
112
126
|
if len(profiles) and verbosity > 0:
|
|
113
|
-
print(
|
|
127
|
+
print(
|
|
128
|
+
f"Ignoring profile '{profiles[FV.WS]}' for states class 'MultiHeightNCTimeseries'"
|
|
129
|
+
)
|
|
114
130
|
|
|
115
131
|
data = {}
|
|
116
132
|
fix = {}
|
|
117
133
|
for v, d in fields.items():
|
|
118
134
|
if dims[v] == (FC.TIME, FV.H):
|
|
119
135
|
data[v] = ((FC.TIME, FV.H), d)
|
|
120
|
-
|
|
136
|
+
elif dims[v] == (FV.H, FC.TIME):
|
|
121
137
|
data[v] = ((FC.TIME, FV.H), np.swapaxes(d, 0, 1))
|
|
122
138
|
elif len(dims[v]) == 0:
|
|
123
139
|
fix[v] = d
|
|
@@ -139,6 +155,7 @@ def _get_MultiHeightNCTimeseries(coords, fields, dims, states_dict,
|
|
|
139
155
|
return True
|
|
140
156
|
return False
|
|
141
157
|
|
|
158
|
+
|
|
142
159
|
def get_states(coords, fields, dims, verbosity=1):
|
|
143
160
|
"""
|
|
144
161
|
Reads states parameters from windio input
|
|
@@ -164,18 +181,22 @@ def get_states(coords, fields, dims, verbosity=1):
|
|
|
164
181
|
"""
|
|
165
182
|
if verbosity > 2:
|
|
166
183
|
print(" Preparing states")
|
|
167
|
-
|
|
184
|
+
|
|
168
185
|
ovars = [FV.WS, FV.WD, FV.TI, FV.RHO]
|
|
169
|
-
fixval = {FV.TI: 0.05, FV.RHO: 1.225}
|
|
186
|
+
fixval = {FV.TI: 0.05, FV.RHO: 1.225}
|
|
170
187
|
profiles = _get_profiles(coords, fields, dims, ovars, fixval, verbosity)
|
|
171
188
|
|
|
172
189
|
states_dict = {}
|
|
173
|
-
if
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
190
|
+
if (
|
|
191
|
+
_get_SingleStateStates(
|
|
192
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
193
|
+
)
|
|
194
|
+
or _get_Timeseries(
|
|
195
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
196
|
+
)
|
|
197
|
+
or _get_MultiHeightNCTimeseries(
|
|
198
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
199
|
+
)
|
|
179
200
|
):
|
|
180
201
|
return States.new(**states_dict)
|
|
181
202
|
else:
|