foxes 1.1.0.2__py3-none-any.whl → 1.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 +3 -2
- examples/dyn_wakes/run.py +2 -2
- examples/timelines/run.py +1 -1
- foxes/__init__.py +13 -2
- foxes/algorithms/downwind/downwind.py +6 -1
- foxes/algorithms/downwind/models/init_farm_data.py +5 -2
- foxes/algorithms/downwind/models/point_wakes_calc.py +0 -1
- foxes/algorithms/iterative/iterative.py +1 -1
- foxes/algorithms/sequential/sequential.py +4 -3
- foxes/config/__init__.py +1 -0
- foxes/config/config.py +134 -0
- foxes/constants.py +15 -6
- foxes/core/algorithm.py +22 -10
- foxes/core/data.py +2 -1
- foxes/core/engine.py +40 -34
- foxes/core/farm_controller.py +4 -3
- foxes/core/farm_data_model.py +6 -2
- foxes/core/model.py +2 -1
- foxes/core/point_data_model.py +4 -2
- foxes/core/rotor_model.py +8 -4
- foxes/core/turbine_type.py +1 -1
- foxes/core/wake_frame.py +7 -5
- foxes/core/wake_model.py +6 -1
- foxes/data/__init__.py +1 -1
- foxes/data/static_data.py +0 -7
- foxes/engines/dask.py +4 -3
- foxes/engines/single.py +1 -1
- foxes/input/__init__.py +1 -1
- foxes/input/farm_layout/from_csv.py +3 -1
- foxes/input/farm_layout/from_file.py +10 -10
- foxes/input/farm_layout/from_json.py +4 -3
- foxes/input/farm_layout/grid.py +3 -3
- foxes/input/states/create/random_abl_states.py +5 -3
- foxes/input/states/field_data_nc.py +22 -14
- foxes/input/states/multi_height.py +26 -15
- foxes/input/states/one_point_flow.py +6 -5
- foxes/input/states/scan_ws.py +4 -1
- foxes/input/states/single.py +15 -6
- foxes/input/states/slice_data_nc.py +18 -12
- foxes/input/states/states_table.py +17 -10
- foxes/input/yaml/__init__.py +3 -0
- foxes/input/yaml/dict.py +210 -0
- foxes/input/yaml/windio/__init__.py +4 -0
- foxes/input/{windio → yaml/windio}/get_states.py +7 -7
- foxes/input/{windio → yaml/windio}/read_attributes.py +61 -40
- foxes/input/{windio → yaml/windio}/read_farm.py +34 -43
- foxes/input/{windio → yaml/windio}/read_fields.py +11 -10
- foxes/input/yaml/windio/read_outputs.py +147 -0
- foxes/input/yaml/windio/windio.py +269 -0
- foxes/input/yaml/yaml.py +103 -0
- foxes/models/partial_wakes/axiwake.py +7 -6
- foxes/models/partial_wakes/centre.py +3 -2
- foxes/models/partial_wakes/segregated.py +5 -2
- foxes/models/point_models/set_uniform_data.py +5 -3
- foxes/models/rotor_models/centre.py +2 -2
- foxes/models/rotor_models/grid.py +5 -5
- foxes/models/rotor_models/levels.py +6 -6
- foxes/models/turbine_models/kTI_model.py +3 -1
- foxes/models/turbine_models/lookup_table.py +7 -4
- foxes/models/turbine_models/power_mask.py +14 -8
- foxes/models/turbine_models/sector_management.py +4 -2
- foxes/models/turbine_models/set_farm_vars.py +53 -23
- foxes/models/turbine_models/table_factors.py +8 -7
- foxes/models/turbine_models/yaw2yawm.py +0 -1
- foxes/models/turbine_models/yawm2yaw.py +0 -1
- foxes/models/turbine_types/CpCt_file.py +6 -3
- foxes/models/turbine_types/CpCt_from_two.py +6 -3
- foxes/models/turbine_types/PCt_file.py +7 -6
- foxes/models/turbine_types/PCt_from_two.py +11 -2
- foxes/models/turbine_types/TBL_file.py +3 -4
- foxes/models/turbine_types/wsrho2PCt_from_two.py +19 -11
- foxes/models/turbine_types/wsti2PCt_from_two.py +19 -11
- foxes/models/vertical_profiles/abl_log_neutral_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_stable_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_unstable_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_ws.py +1 -1
- foxes/models/wake_frames/dynamic_wakes.py +17 -9
- foxes/models/wake_frames/farm_order.py +4 -3
- foxes/models/wake_frames/rotor_wd.py +3 -1
- foxes/models/wake_frames/seq_dynamic_wakes.py +14 -7
- foxes/models/wake_frames/streamlines.py +9 -6
- foxes/models/wake_frames/timelines.py +21 -14
- foxes/models/wake_frames/yawed_wakes.py +3 -1
- foxes/models/wake_models/induction/vortex_sheet.py +0 -1
- foxes/models/wake_models/ti/crespo_hernandez.py +2 -1
- foxes/models/wake_models/wind/bastankhah14.py +3 -2
- foxes/models/wake_models/wind/bastankhah16.py +2 -1
- foxes/models/wake_models/wind/turbopark.py +9 -7
- foxes/models/wake_superpositions/ws_product.py +0 -1
- foxes/output/calc_points.py +7 -4
- foxes/output/farm_layout.py +30 -18
- foxes/output/farm_results_eval.py +4 -3
- foxes/output/grids.py +8 -7
- foxes/output/output.py +7 -2
- foxes/output/results_writer.py +10 -11
- foxes/output/rose_plot.py +38 -20
- foxes/output/rotor_point_plots.py +7 -3
- foxes/output/slice_data.py +1 -1
- foxes/output/state_turbine_map.py +5 -1
- foxes/output/state_turbine_table.py +7 -3
- foxes/output/turbine_type_curves.py +7 -2
- foxes/utils/dict.py +107 -3
- foxes/utils/geopandas_utils.py +3 -2
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/METADATA +20 -21
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/RECORD +122 -122
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/WHEEL +1 -1
- foxes-1.2.dist-info/entry_points.txt +3 -0
- tests/0_consistency/iterative/test_iterative.py +65 -67
- tests/0_consistency/partial_wakes/test_partial_wakes.py +58 -61
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +56 -53
- tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +41 -41
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +34 -34
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +50 -50
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +51 -52
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +73 -74
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +73 -74
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +51 -49
- tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +101 -103
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +61 -62
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +51 -52
- examples/windio/run.py +0 -29
- foxes/data/states/windio_timeseries_5000.nc +0 -0
- foxes/data/windio/DTU_10MW_turbine.yaml +0 -10
- foxes/data/windio/__init__.py +0 -0
- foxes/data/windio/windio_5turbines_timeseries.yaml +0 -79
- foxes/input/windio/__init__.py +0 -11
- foxes/input/windio/read_outputs.py +0 -172
- foxes/input/windio/runner.py +0 -183
- foxes/input/windio/windio.py +0 -193
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/LICENSE +0 -0
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/top_level.txt +0 -0
|
@@ -6,7 +6,13 @@ from .read_outputs import read_outputs
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def _read_wind_deficit(
|
|
9
|
-
wake_model_key,
|
|
9
|
+
wake_model_key,
|
|
10
|
+
wind_deficit,
|
|
11
|
+
superposition,
|
|
12
|
+
induction,
|
|
13
|
+
algo_dict,
|
|
14
|
+
mbook,
|
|
15
|
+
verbosity,
|
|
10
16
|
):
|
|
11
17
|
"""Reads the wind deficit wake model"""
|
|
12
18
|
|
|
@@ -69,17 +75,25 @@ def _read_wind_deficit(
|
|
|
69
75
|
supd = ws_sup_dict if eff_ws else ws_sup_amb_dict
|
|
70
76
|
wind_def_dict["superposition"] = supd[superposition["ws_superposition"]]
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
mbook.wake_models[wname] = WakeModel.new(**wind_def_dict)
|
|
73
79
|
if verbosity > 2:
|
|
74
80
|
print(f" Created wake model '{wname}':")
|
|
75
|
-
print(" ",
|
|
81
|
+
print(" ", mbook.wake_models[wname])
|
|
76
82
|
algo_dict["wake_models"].append(wname)
|
|
77
83
|
|
|
78
84
|
return ka, kb, amb_ti
|
|
79
85
|
|
|
80
86
|
|
|
81
87
|
def _read_turbulence(
|
|
82
|
-
turbulence_model,
|
|
88
|
+
turbulence_model,
|
|
89
|
+
superposition,
|
|
90
|
+
induction,
|
|
91
|
+
algo_dict,
|
|
92
|
+
mbook,
|
|
93
|
+
ka,
|
|
94
|
+
kb,
|
|
95
|
+
amb_ti,
|
|
96
|
+
verbosity,
|
|
83
97
|
):
|
|
84
98
|
"""Reads the ti wake model"""
|
|
85
99
|
|
|
@@ -128,14 +142,14 @@ def _read_turbulence(
|
|
|
128
142
|
tiwake_dict["ti_var"] = ti_var
|
|
129
143
|
tiwake_dict["superposition"] = ti_sup_dict[superposition["ti_superposition"]]
|
|
130
144
|
|
|
131
|
-
|
|
145
|
+
mbook.wake_models[wname] = WakeModel.new(**tiwake_dict)
|
|
132
146
|
if verbosity > 2:
|
|
133
147
|
print(f" Created wake model '{wname}':")
|
|
134
|
-
print(" ",
|
|
148
|
+
print(" ", mbook.wake_models[wname])
|
|
135
149
|
algo_dict["wake_models"].append(wname)
|
|
136
150
|
|
|
137
151
|
|
|
138
|
-
def _read_blockage(blockage_model, induction, algo_dict, verbosity):
|
|
152
|
+
def _read_blockage(blockage_model, induction, algo_dict, mbook, verbosity):
|
|
139
153
|
"""Reads the blockage model"""
|
|
140
154
|
indc_def_map = Dict(
|
|
141
155
|
{
|
|
@@ -154,10 +168,10 @@ def _read_blockage(blockage_model, induction, algo_dict, verbosity):
|
|
|
154
168
|
print(" Contents:", [k for k in blockage_model.keys()])
|
|
155
169
|
if wname not in ["None", "none"]:
|
|
156
170
|
indc_dict = Dict(wmodel_type=indc_def_map[wname], induction=induction)
|
|
157
|
-
|
|
171
|
+
mbook.wake_models[wname] = WakeModel.new(**indc_dict)
|
|
158
172
|
if verbosity > 2:
|
|
159
173
|
print(f" Created wake model '{wname}':")
|
|
160
|
-
print(" ",
|
|
174
|
+
print(" ", mbook.wake_models[wname])
|
|
161
175
|
algo_dict["wake_models"].append(wname)
|
|
162
176
|
algo_dict["algo_type"] = "Iterative"
|
|
163
177
|
|
|
@@ -214,7 +228,7 @@ def _read_rotor_averaging(rotor_averaging, algo_dict, verbosity):
|
|
|
214
228
|
print(" --> partial_wakes :", algo_dict["partial_wakes"])
|
|
215
229
|
|
|
216
230
|
|
|
217
|
-
def _read_deflection(deflection, induction, algo_dict, verbosity):
|
|
231
|
+
def _read_deflection(deflection, induction, algo_dict, mbook, verbosity):
|
|
218
232
|
"""Reads deflection model"""
|
|
219
233
|
defl_def_map = Dict(
|
|
220
234
|
{
|
|
@@ -231,25 +245,25 @@ def _read_deflection(deflection, induction, algo_dict, verbosity):
|
|
|
231
245
|
print(" Contents:", [k for k in deflection.keys()])
|
|
232
246
|
indc_dict = Dict(wframe_type=defl_def_map[wname])
|
|
233
247
|
try:
|
|
234
|
-
|
|
235
|
-
**indc_dict, induction=induction
|
|
236
|
-
)
|
|
248
|
+
mbook.wake_frames[wname] = WakeFrame.new(**indc_dict, induction=induction)
|
|
237
249
|
except TypeError:
|
|
238
|
-
|
|
250
|
+
mbook.wake_frames[wname] = WakeFrame.new(**indc_dict)
|
|
239
251
|
if verbosity > 2:
|
|
240
252
|
print(f" Created wake frame '{wname}':")
|
|
241
|
-
print(" ",
|
|
253
|
+
print(" ", mbook.wake_frames[wname])
|
|
242
254
|
algo_dict["wake_frame"] = wname
|
|
243
255
|
|
|
244
256
|
|
|
245
|
-
def _read_analysis(wio_ana,
|
|
257
|
+
def _read_analysis(wio_ana, idict, mbook, verbosity):
|
|
246
258
|
"""Reads the windio analyses"""
|
|
247
259
|
if verbosity > 2:
|
|
248
260
|
print(" Reading analysis")
|
|
249
261
|
print(" Contents:", [k for k in wio_ana.keys()])
|
|
250
262
|
|
|
251
263
|
# superposition:
|
|
252
|
-
superposition = Dict(
|
|
264
|
+
superposition = Dict(
|
|
265
|
+
wio_ana["superposition_model"], name=wio_ana.name + ".superposition_model"
|
|
266
|
+
)
|
|
253
267
|
if verbosity > 2:
|
|
254
268
|
print(" Reading superposition_model")
|
|
255
269
|
print(" Contents:", [k for k in superposition.keys()])
|
|
@@ -270,9 +284,18 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
|
|
|
270
284
|
wake_model_key = (
|
|
271
285
|
"wind_deficit_model" if "wind_deficit_model" in wio_ana else "wake_model"
|
|
272
286
|
)
|
|
273
|
-
|
|
287
|
+
algo_dict = idict["algorithm"]
|
|
288
|
+
wind_deficit = Dict(
|
|
289
|
+
wio_ana[wake_model_key], name=wio_ana.name + "." + wake_model_key
|
|
290
|
+
)
|
|
274
291
|
ka, kb, amb_ti = _read_wind_deficit(
|
|
275
|
-
wake_model_key,
|
|
292
|
+
wake_model_key,
|
|
293
|
+
wind_deficit,
|
|
294
|
+
superposition,
|
|
295
|
+
induction,
|
|
296
|
+
algo_dict,
|
|
297
|
+
mbook,
|
|
298
|
+
verbosity,
|
|
276
299
|
)
|
|
277
300
|
|
|
278
301
|
# turbulence model:
|
|
@@ -283,6 +306,7 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
|
|
|
283
306
|
superposition,
|
|
284
307
|
induction,
|
|
285
308
|
algo_dict,
|
|
309
|
+
mbook,
|
|
286
310
|
ka,
|
|
287
311
|
kb,
|
|
288
312
|
amb_ti,
|
|
@@ -294,7 +318,7 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
|
|
|
294
318
|
# blockage model:
|
|
295
319
|
if "blockage_model" in wio_ana:
|
|
296
320
|
blockage_model = Dict(wio_ana["blockage_model"], name="blockage_model")
|
|
297
|
-
_read_blockage(blockage_model, induction, algo_dict, verbosity)
|
|
321
|
+
_read_blockage(blockage_model, induction, algo_dict, mbook, verbosity)
|
|
298
322
|
elif verbosity > 0:
|
|
299
323
|
print("blockage_model not found, not using a turbine induction model")
|
|
300
324
|
|
|
@@ -308,37 +332,35 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
|
|
|
308
332
|
# deflection:
|
|
309
333
|
if "deflection_model" in wio_ana:
|
|
310
334
|
deflection = Dict(wio_ana["deflection_model"], name="deflection_model")
|
|
311
|
-
_read_deflection(deflection, induction, algo_dict, verbosity)
|
|
335
|
+
_read_deflection(deflection, induction, algo_dict, mbook, verbosity)
|
|
312
336
|
elif verbosity > 0:
|
|
313
337
|
print("deflection_model not found, using default settings")
|
|
314
338
|
|
|
315
339
|
|
|
316
|
-
def read_attributes(wio,
|
|
340
|
+
def read_attributes(wio, idict, mbook, verbosity=1):
|
|
317
341
|
"""
|
|
318
342
|
Reads the attributes part of windio
|
|
319
343
|
|
|
320
344
|
Parameters
|
|
321
345
|
----------
|
|
322
|
-
wio:
|
|
346
|
+
wio: foxes.utils.Dict
|
|
323
347
|
The windio data
|
|
324
|
-
|
|
325
|
-
The
|
|
348
|
+
idict: foxes.utils.Dict
|
|
349
|
+
The foxes input data dictionary
|
|
350
|
+
mbook: foxes.models.ModelBook
|
|
351
|
+
The model book
|
|
326
352
|
verbosity: int
|
|
327
353
|
The verbosity level, 0=silent
|
|
328
|
-
**output_pars: dict, optional
|
|
329
|
-
Additional parameters for output reading
|
|
330
354
|
|
|
331
355
|
Returns
|
|
332
356
|
-------
|
|
333
|
-
out_dicts: list of dict
|
|
334
|
-
The output dictionaries
|
|
335
357
|
odir: pathlib.Path
|
|
336
|
-
|
|
358
|
+
The output directory
|
|
337
359
|
|
|
338
|
-
:group: input.windio
|
|
360
|
+
:group: input.yaml.windio
|
|
339
361
|
|
|
340
362
|
"""
|
|
341
|
-
wio_attrs = Dict(wio["attributes"], name="attributes")
|
|
363
|
+
wio_attrs = Dict(wio["attributes"], name=wio.name + ".attributes")
|
|
342
364
|
if verbosity > 1:
|
|
343
365
|
print("Reading attributes")
|
|
344
366
|
print(" Contents:", [k for k in wio_attrs.keys()])
|
|
@@ -355,15 +377,14 @@ def read_attributes(wio, algo_dict, verbosity=1, **output_pars):
|
|
|
355
377
|
print(f"Running flow model 'foxes', overruling original choice '{fmname}'")
|
|
356
378
|
|
|
357
379
|
# read analysis:
|
|
358
|
-
wio_ana = Dict(wio_attrs["analysis"], name="
|
|
359
|
-
_read_analysis(wio_ana,
|
|
380
|
+
wio_ana = Dict(wio_attrs["analysis"], name=wio_attrs.name + ".analysis")
|
|
381
|
+
_read_analysis(wio_ana, idict, mbook, verbosity)
|
|
360
382
|
|
|
361
383
|
# outputs:
|
|
362
|
-
|
|
384
|
+
odict = idict["outputs"]
|
|
385
|
+
odir = "."
|
|
363
386
|
if "outputs" in wio_attrs:
|
|
364
|
-
outputs = Dict(wio_attrs["outputs"], name="outputs")
|
|
365
|
-
|
|
366
|
-
outputs, algo_dict, verbosity=verbosity, **output_pars
|
|
367
|
-
)
|
|
387
|
+
outputs = Dict(wio_attrs["outputs"], name=wio_attrs.name + ".outputs")
|
|
388
|
+
odir = read_outputs(outputs, odict, verbosity=verbosity)
|
|
368
389
|
|
|
369
|
-
return
|
|
390
|
+
return odir
|
|
@@ -6,7 +6,7 @@ from foxes.core import Turbine, TurbineType
|
|
|
6
6
|
import foxes.variables as FV
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def read_turbine_types(wio_farm,
|
|
9
|
+
def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
|
|
10
10
|
"""
|
|
11
11
|
Reads the turbine type from windio
|
|
12
12
|
|
|
@@ -14,8 +14,8 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
14
14
|
----------
|
|
15
15
|
wio_farm: dict
|
|
16
16
|
The windio farm data
|
|
17
|
-
|
|
18
|
-
The
|
|
17
|
+
mbook: foxes.models.ModelBook
|
|
18
|
+
The model book
|
|
19
19
|
ws_exp_P: int
|
|
20
20
|
The REWS exponent for power
|
|
21
21
|
ws_exp_ct: int
|
|
@@ -29,9 +29,14 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
29
29
|
Mapping from turbine type key to turbine
|
|
30
30
|
type name in the model book
|
|
31
31
|
|
|
32
|
-
:group: input.windio
|
|
32
|
+
:group: input.yaml.windio
|
|
33
33
|
|
|
34
34
|
"""
|
|
35
|
+
|
|
36
|
+
def _print(*args, level=1, **kwargs):
|
|
37
|
+
if verbosity >= level:
|
|
38
|
+
print(*args, **kwargs)
|
|
39
|
+
|
|
35
40
|
if "turbine_types" not in wio_farm:
|
|
36
41
|
wio_farm["turbine_types"] = {0: wio_farm["turbines"]}
|
|
37
42
|
|
|
@@ -39,29 +44,25 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
39
44
|
for k, wio_trbns in wio_farm["turbine_types"].items():
|
|
40
45
|
tname = wio_trbns.pop("name")
|
|
41
46
|
ttypes[k] = tname
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
print(" Contents:", [k for k in wio_trbns.keys()])
|
|
47
|
+
_print(" Reading turbine type", k, level=3)
|
|
48
|
+
_print(" Name:", tname, level=3)
|
|
49
|
+
_print(" Contents:", [k for k in wio_trbns.keys()], level=3)
|
|
46
50
|
|
|
47
51
|
# read performance:
|
|
48
52
|
performance = Dict(wio_trbns["performance"], name="performance")
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
print(" Contents:", [k for k in performance.keys()])
|
|
53
|
+
_print(" Reading performance", level=3)
|
|
54
|
+
_print(" Contents:", [k for k in performance.keys()], level=3)
|
|
52
55
|
|
|
53
56
|
# P, ct data:
|
|
54
57
|
if "power_curve" in performance:
|
|
55
58
|
power_curve = Dict(performance["power_curve"], name="power_curve")
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
print(" Contents:", [k for k in power_curve.keys()])
|
|
59
|
+
_print(" Reading power_curve", level=3)
|
|
60
|
+
_print(" Contents:", [k for k in power_curve.keys()], level=3)
|
|
59
61
|
P = power_curve["power_values"]
|
|
60
62
|
ws_P = power_curve["power_wind_speeds"]
|
|
61
63
|
ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
print(" Contents:", [k for k in ct_curve.keys()])
|
|
64
|
+
_print(" Reading Ct_curve", level=3)
|
|
65
|
+
_print(" Contents:", [k for k in ct_curve.keys()], level=3)
|
|
65
66
|
ct = ct_curve["Ct_values"]
|
|
66
67
|
ws_ct = ct_curve["Ct_wind_speeds"]
|
|
67
68
|
|
|
@@ -75,10 +76,9 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
75
76
|
)
|
|
76
77
|
return FV.REWS if wse == 1 else (FV.REWS2 if wse == 2 else FV.REWS3)
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
|
|
79
|
+
_print(f" Creating model '{tname}'", level=3)
|
|
80
|
+
_print(f" Turbine type class: PCtFomTwo", level=3)
|
|
81
|
+
mbook.turbine_types[tname] = TurbineType.new(
|
|
82
82
|
ttype_type="PCtFromTwo",
|
|
83
83
|
data_source_P=data_P,
|
|
84
84
|
data_source_ct=data_ct,
|
|
@@ -92,31 +92,27 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
92
92
|
var_ws_P=_get_wse_var(ws_exp_P),
|
|
93
93
|
rho=1.225,
|
|
94
94
|
)
|
|
95
|
-
|
|
96
|
-
print(" ", algo_dict["mbook"].turbine_types[tname])
|
|
95
|
+
_print(" ", mbook.turbine_types[tname], level=3)
|
|
97
96
|
|
|
98
97
|
# P, ct data:
|
|
99
98
|
elif "Cp_curve" in performance:
|
|
100
99
|
cp_curve = Dict(performance["Cp_curve"], name="Cp_curve")
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
print(" Contents:", [k for k in cp_curve.keys()])
|
|
100
|
+
_print(" Reading Cp_curve", level=3)
|
|
101
|
+
_print(" Contents:", [k for k in cp_curve.keys()], level=3)
|
|
104
102
|
cp = cp_curve["Cp_values"]
|
|
105
103
|
ws_cp = cp_curve["Cp_wind_speeds"]
|
|
106
104
|
ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
print(" Contents:", [k for k in ct_curve.keys()])
|
|
105
|
+
_print(" Reading Ct_curve", level=3)
|
|
106
|
+
_print(" Contents:", [k for k in ct_curve.keys()], level=3)
|
|
110
107
|
ct = ct_curve["Ct_values"]
|
|
111
108
|
ws_ct = ct_curve["Ct_wind_speeds"]
|
|
112
109
|
|
|
113
110
|
data_cp = pd.DataFrame(data={"ws": ws_cp, "cp": cp})
|
|
114
111
|
data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
|
|
115
112
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
|
|
113
|
+
_print(f" Creating model '{tname}'", level=3)
|
|
114
|
+
_print(f" Turbine type class: CpCtFromTwo", level=3)
|
|
115
|
+
mbook.turbine_types[tname] = TurbineType.new(
|
|
120
116
|
ttype_type="CpCtFromTwo",
|
|
121
117
|
data_source_cp=data_cp,
|
|
122
118
|
data_source_ct=data_ct,
|
|
@@ -127,6 +123,7 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
127
123
|
H=wio_trbns["hub_height"],
|
|
128
124
|
D=wio_trbns["rotor_diameter"],
|
|
129
125
|
)
|
|
126
|
+
_print(" ", mbook.turbine_types[tname], level=3)
|
|
130
127
|
|
|
131
128
|
else:
|
|
132
129
|
raise KeyError(f"Expecting either 'power_curve' or 'Cp_curve'")
|
|
@@ -134,7 +131,7 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
134
131
|
return ttypes
|
|
135
132
|
|
|
136
133
|
|
|
137
|
-
def read_layout(lname, ldict,
|
|
134
|
+
def read_layout(lname, ldict, farm, ttypes, verbosity=1):
|
|
138
135
|
"""
|
|
139
136
|
Read wind farm layout from windio input
|
|
140
137
|
|
|
@@ -144,26 +141,20 @@ def read_layout(lname, ldict, algo_dict, ttypes, verbosity=1):
|
|
|
144
141
|
The layout name
|
|
145
142
|
ldict: dict
|
|
146
143
|
The layout data
|
|
147
|
-
|
|
148
|
-
The
|
|
144
|
+
farm: foxes.core.WindFarm
|
|
145
|
+
The wind farm
|
|
149
146
|
ttypes: dict
|
|
150
147
|
Mapping from turbine type key to turbine
|
|
151
148
|
type name in the model book
|
|
152
149
|
verbosity: int
|
|
153
150
|
The verbosity level, 0=silent
|
|
154
151
|
|
|
155
|
-
|
|
156
|
-
-------
|
|
157
|
-
states: foxes.core.States
|
|
158
|
-
The states object
|
|
159
|
-
|
|
160
|
-
:group: input.windio
|
|
152
|
+
:group: input.yaml.windio
|
|
161
153
|
|
|
162
154
|
"""
|
|
163
155
|
if verbosity > 2:
|
|
164
156
|
print(f" Reading '{lname}'")
|
|
165
157
|
cdict = Dict(ldict["coordinates"], name="coordinates")
|
|
166
|
-
farm = algo_dict["farm"]
|
|
167
158
|
tmap = ldict.get("turbine_types", None)
|
|
168
159
|
if verbosity > 2:
|
|
169
160
|
print(f" Turbine type map:", tmap)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from numbers import Number
|
|
3
3
|
|
|
4
|
-
import foxes.constants as FC
|
|
5
4
|
import foxes.variables as FV
|
|
5
|
+
import foxes.constants as FC
|
|
6
|
+
|
|
6
7
|
|
|
7
8
|
""" Mapping from windio to foxes variables
|
|
8
|
-
:group: input.windio
|
|
9
|
+
:group: input.yaml.windio
|
|
9
10
|
"""
|
|
10
11
|
wio2foxes = {
|
|
11
12
|
"time": FC.TIME,
|
|
@@ -24,14 +25,14 @@ wio2foxes = {
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
""" Mapping from foxes to windio variables
|
|
27
|
-
:group: input.windio
|
|
28
|
+
:group: input.yaml.windio
|
|
28
29
|
"""
|
|
29
30
|
foxes2wio = {d: k for k, d in wio2foxes.items()}
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
def _read_nondimensional_coordinate(name, wio_data, coords):
|
|
33
34
|
"""read nondimensional coordinate
|
|
34
|
-
:group: input.windio
|
|
35
|
+
:group: input.yaml.windio
|
|
35
36
|
"""
|
|
36
37
|
if isinstance(wio_data, Number):
|
|
37
38
|
coords[wio2foxes[name]] = wio_data
|
|
@@ -41,7 +42,7 @@ def _read_nondimensional_coordinate(name, wio_data, coords):
|
|
|
41
42
|
|
|
42
43
|
def _read_dimensional_coordinate(name, wio_data, coords):
|
|
43
44
|
"""read dimensional coordinate
|
|
44
|
-
:group: input.windio
|
|
45
|
+
:group: input.yaml.windio
|
|
45
46
|
"""
|
|
46
47
|
if isinstance(wio_data, list):
|
|
47
48
|
wio_data = np.array(wio_data)
|
|
@@ -53,7 +54,7 @@ def _read_dimensional_coordinate(name, wio_data, coords):
|
|
|
53
54
|
|
|
54
55
|
def _read_multi_dimensional_coordinate(name, wio_data, coords):
|
|
55
56
|
"""Read multi dimensional coordinate
|
|
56
|
-
:group: input.windio
|
|
57
|
+
:group: input.yaml.windio
|
|
57
58
|
"""
|
|
58
59
|
return _read_nondimensional_coordinate(
|
|
59
60
|
name, wio_data, coords
|
|
@@ -62,7 +63,7 @@ def _read_multi_dimensional_coordinate(name, wio_data, coords):
|
|
|
62
63
|
|
|
63
64
|
def _read_nondimensional_data(name, wio_data, fields, dims):
|
|
64
65
|
"""read nondimensional data
|
|
65
|
-
:group: input.windio
|
|
66
|
+
:group: input.yaml.windio
|
|
66
67
|
"""
|
|
67
68
|
if isinstance(wio_data, Number):
|
|
68
69
|
v = wio2foxes[name]
|
|
@@ -74,7 +75,7 @@ def _read_nondimensional_data(name, wio_data, fields, dims):
|
|
|
74
75
|
|
|
75
76
|
def _read_dimensional_data(name, wio_data, fields, dims):
|
|
76
77
|
"""read dimensional data
|
|
77
|
-
:group: input.windio
|
|
78
|
+
:group: input.yaml.windio
|
|
78
79
|
"""
|
|
79
80
|
if isinstance(wio_data, dict) and "data" in wio_data and "dims" in wio_data:
|
|
80
81
|
d = wio_data["data"]
|
|
@@ -91,7 +92,7 @@ def _read_dimensional_data(name, wio_data, fields, dims):
|
|
|
91
92
|
|
|
92
93
|
def _read_multi_dimensional_data(name, wio_data, fields, dims):
|
|
93
94
|
"""Read multi dimensional data
|
|
94
|
-
:group: input.windio
|
|
95
|
+
:group: input.yaml.windio
|
|
95
96
|
"""
|
|
96
97
|
return _read_nondimensional_data(
|
|
97
98
|
name, wio_data, fields, dims
|
|
@@ -129,7 +130,7 @@ def read_wind_resource_field(
|
|
|
129
130
|
success: bool
|
|
130
131
|
Flag for successful data extraction
|
|
131
132
|
|
|
132
|
-
:group: input.windio
|
|
133
|
+
:group: input.yaml.windio
|
|
133
134
|
|
|
134
135
|
"""
|
|
135
136
|
if name in [
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from foxes.utils import Dict
|
|
4
|
+
import foxes.variables as FV
|
|
5
|
+
import foxes.constants as FC
|
|
6
|
+
|
|
7
|
+
from .read_fields import foxes2wio
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _read_turbine_outputs(wio_outs, odict, verbosity):
|
|
11
|
+
"""Reads the turbine outputs request"""
|
|
12
|
+
if "turbine_outputs" in wio_outs and wio_outs["turbine_outputs"].get(
|
|
13
|
+
"report", True
|
|
14
|
+
):
|
|
15
|
+
turbine_outputs = Dict(
|
|
16
|
+
wio_outs["turbine_outputs"], name=wio_outs.name + ".turbine_outputs"
|
|
17
|
+
)
|
|
18
|
+
turbine_nc_filename = turbine_outputs.pop(
|
|
19
|
+
"turbine_nc_filename", "turbine_outputs.nc"
|
|
20
|
+
)
|
|
21
|
+
output_variables = turbine_outputs["output_variables"]
|
|
22
|
+
if verbosity > 2:
|
|
23
|
+
print(" Reading turbine_outputs")
|
|
24
|
+
print(" File name:", turbine_nc_filename)
|
|
25
|
+
print(" output_variables:", output_variables)
|
|
26
|
+
|
|
27
|
+
vmap = Dict(
|
|
28
|
+
power=FV.P,
|
|
29
|
+
rotor_effective_velocity=FV.REWS,
|
|
30
|
+
)
|
|
31
|
+
ivmap = {d: k for k, d in vmap.items()}
|
|
32
|
+
ivmap.update(
|
|
33
|
+
{
|
|
34
|
+
FC.STATE: "time",
|
|
35
|
+
FC.TURBINE: "turbine",
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
odict["StateTurbineTable"] = Dict(
|
|
40
|
+
functions=[
|
|
41
|
+
dict(
|
|
42
|
+
name="get_dataset",
|
|
43
|
+
variables=[vmap[v] for v in output_variables],
|
|
44
|
+
name_map=ivmap,
|
|
45
|
+
to_file=turbine_nc_filename,
|
|
46
|
+
round={vw: FV.get_default_digits(vf) for vw, vf in vmap.items()},
|
|
47
|
+
verbosity=verbosity,
|
|
48
|
+
)
|
|
49
|
+
],
|
|
50
|
+
name=odict.name + ".StateTurbineTable",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _read_flow_field(wio_outs, odict, verbosity):
|
|
55
|
+
"""Reads the flow field request"""
|
|
56
|
+
if "flow_field" in wio_outs and wio_outs["flow_field"].get("report", True):
|
|
57
|
+
flow_field = Dict(wio_outs["flow_field"], name=wio_outs.name + ".flow_field")
|
|
58
|
+
flow_nc_filename = flow_field.pop("flow_nc_filename", "flow_field.nc")
|
|
59
|
+
output_variables = flow_field.pop("output_variables")
|
|
60
|
+
z_planes = Dict(flow_field.pop("z_planes"), name=flow_field.name + ".z_planes")
|
|
61
|
+
z_sampling = z_planes["z_sampling"]
|
|
62
|
+
xy_sampling = z_planes["xy_sampling"]
|
|
63
|
+
cases_run = Dict(
|
|
64
|
+
flow_field.pop("cases_run", {}), name=flow_field.name + ".cases_run"
|
|
65
|
+
)
|
|
66
|
+
states_isel = cases_run.get("subset", None)
|
|
67
|
+
if "all_occurences" in cases_run and cases_run.pop("all_occurences"):
|
|
68
|
+
states_isel = None
|
|
69
|
+
if verbosity > 2:
|
|
70
|
+
print(" Reading flow_field")
|
|
71
|
+
print(" File name :", flow_nc_filename)
|
|
72
|
+
print(" output_variables:", output_variables)
|
|
73
|
+
print(" states subset :", states_isel)
|
|
74
|
+
print(" z_sampling :", z_sampling)
|
|
75
|
+
print(" xy_sampling :", xy_sampling)
|
|
76
|
+
|
|
77
|
+
vmap = Dict(
|
|
78
|
+
wind_speed=FV.WS,
|
|
79
|
+
wind_direction=FV.WD,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
if z_sampling in ["hub_height", "default"]:
|
|
83
|
+
z = None
|
|
84
|
+
elif isinstance(z_sampling, (int, float)):
|
|
85
|
+
z = z_sampling
|
|
86
|
+
else:
|
|
87
|
+
raise NotImplementedError(
|
|
88
|
+
f"z_sampling '{z_sampling}' of type '{type(z_sampling).__name__}' is not supported (yet). Please give 'hub_height', 'default' or a float."
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if xy_sampling == "default":
|
|
92
|
+
odict["SliceData"] = Dict(
|
|
93
|
+
verbosity_delta=3,
|
|
94
|
+
functions=[
|
|
95
|
+
dict(
|
|
96
|
+
name="get_states_data_xy",
|
|
97
|
+
states_isel=states_isel,
|
|
98
|
+
n_img_points=(100, 100),
|
|
99
|
+
variables=[vmap[v] for v in output_variables],
|
|
100
|
+
z=z,
|
|
101
|
+
to_file=flow_nc_filename,
|
|
102
|
+
label_map=foxes2wio,
|
|
103
|
+
verbosity=verbosity,
|
|
104
|
+
)
|
|
105
|
+
],
|
|
106
|
+
name=odict.name + ".SliceData",
|
|
107
|
+
)
|
|
108
|
+
else:
|
|
109
|
+
raise NotImplementedError(
|
|
110
|
+
f"xy_sampling '{xy_sampling}' is not supported (yet)"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def read_outputs(wio_outs, odict, verbosity=1):
|
|
115
|
+
"""
|
|
116
|
+
Reads the windio outputs
|
|
117
|
+
|
|
118
|
+
Parameters
|
|
119
|
+
----------
|
|
120
|
+
wio_outs: foxes.utils.Dict
|
|
121
|
+
The windio output data dict
|
|
122
|
+
odict: foxes.utils.Dict
|
|
123
|
+
The foxes output dictionary
|
|
124
|
+
verbosity: int
|
|
125
|
+
The verbosity level, 0=silent
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
odir: pathlib.Path
|
|
130
|
+
The output directory
|
|
131
|
+
|
|
132
|
+
:group: input.yaml.windio
|
|
133
|
+
|
|
134
|
+
"""
|
|
135
|
+
odir = wio_outs.pop("output_folder", ".")
|
|
136
|
+
if verbosity > 2:
|
|
137
|
+
print(" Reading outputs")
|
|
138
|
+
print(" Output dir:", odir)
|
|
139
|
+
print(" Contents :", [k for k in wio_outs.keys()])
|
|
140
|
+
|
|
141
|
+
# read turbine_outputs:
|
|
142
|
+
_read_turbine_outputs(wio_outs, odict, verbosity)
|
|
143
|
+
|
|
144
|
+
# read flow field:
|
|
145
|
+
_read_flow_field(wio_outs, odict, verbosity)
|
|
146
|
+
|
|
147
|
+
return odir
|