foxes 1.4__py3-none-any.whl → 1.5.1__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 +1 -1
- examples/abl_states/run.py +58 -56
- examples/dyn_wakes/run.py +110 -118
- examples/field_data_nc/run.py +23 -21
- examples/multi_height/run.py +8 -6
- examples/scan_row/run.py +89 -87
- examples/sector_management/run.py +40 -38
- examples/states_lookup_table/run.py +6 -4
- examples/streamline_wakes/run.py +10 -8
- examples/timelines/run.py +100 -98
- examples/timeseries/run.py +71 -76
- examples/wind_rose/run.py +27 -25
- examples/yawed_wake/run.py +85 -81
- foxes/algorithms/downwind/downwind.py +5 -5
- foxes/algorithms/downwind/models/init_farm_data.py +58 -28
- foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
- foxes/core/algorithm.py +6 -5
- foxes/core/data.py +75 -4
- foxes/core/data_calc_model.py +4 -2
- foxes/core/engine.py +33 -40
- foxes/core/farm_data_model.py +16 -13
- foxes/core/model.py +19 -1
- foxes/core/point_data_model.py +19 -14
- foxes/core/rotor_model.py +1 -0
- foxes/core/wake_deflection.py +3 -3
- foxes/data/states/point_cloud_100.nc +0 -0
- foxes/data/states/weibull_cloud_4.nc +0 -0
- foxes/data/states/weibull_grid.nc +0 -0
- foxes/engines/dask.py +3 -6
- foxes/engines/default.py +2 -2
- foxes/engines/numpy.py +11 -10
- foxes/engines/pool.py +21 -11
- foxes/engines/single.py +8 -6
- foxes/input/farm_layout/__init__.py +1 -0
- foxes/input/farm_layout/from_arrays.py +68 -0
- foxes/input/states/__init__.py +7 -1
- foxes/input/states/dataset_states.py +710 -0
- foxes/input/states/field_data.py +531 -0
- foxes/input/states/multi_height.py +2 -0
- foxes/input/states/one_point_flow.py +1 -0
- foxes/input/states/point_cloud_data.py +618 -0
- foxes/input/states/scan.py +2 -0
- foxes/input/states/single.py +2 -0
- foxes/input/states/states_table.py +13 -23
- foxes/input/states/weibull_sectors.py +182 -77
- foxes/input/states/wrg_states.py +1 -1
- foxes/input/yaml/dict.py +25 -24
- foxes/input/yaml/windio/read_attributes.py +40 -27
- foxes/input/yaml/windio/read_farm.py +12 -10
- foxes/input/yaml/windio/read_outputs.py +25 -15
- foxes/input/yaml/windio/read_site.py +121 -12
- foxes/input/yaml/windio/windio.py +22 -10
- foxes/input/yaml/yaml.py +1 -0
- foxes/models/model_book.py +16 -15
- foxes/models/rotor_models/__init__.py +1 -0
- foxes/models/rotor_models/centre.py +1 -1
- foxes/models/rotor_models/direct_infusion.py +241 -0
- foxes/models/turbine_models/calculator.py +16 -3
- foxes/models/turbine_models/kTI_model.py +1 -0
- foxes/models/turbine_models/lookup_table.py +2 -0
- foxes/models/turbine_models/power_mask.py +1 -0
- foxes/models/turbine_models/rotor_centre_calc.py +2 -0
- foxes/models/turbine_models/sector_management.py +1 -0
- foxes/models/turbine_models/set_farm_vars.py +3 -8
- foxes/models/turbine_models/table_factors.py +2 -0
- foxes/models/turbine_models/thrust2ct.py +1 -0
- foxes/models/turbine_models/yaw2yawm.py +2 -0
- foxes/models/turbine_models/yawm2yaw.py +2 -0
- foxes/models/turbine_types/PCt_file.py +2 -4
- foxes/models/turbine_types/PCt_from_two.py +1 -0
- foxes/models/turbine_types/__init__.py +1 -0
- foxes/models/turbine_types/calculator_type.py +123 -0
- foxes/models/turbine_types/null_type.py +1 -0
- foxes/models/turbine_types/wsrho2PCt_from_two.py +2 -0
- foxes/models/turbine_types/wsti2PCt_from_two.py +3 -1
- foxes/output/farm_layout.py +2 -0
- foxes/output/farm_results_eval.py +4 -1
- foxes/output/flow_plots_2d/flow_plots.py +18 -0
- foxes/output/flow_plots_2d/get_fig.py +1 -0
- foxes/output/output.py +6 -1
- foxes/output/results_writer.py +1 -1
- foxes/output/rose_plot.py +10 -0
- foxes/output/rotor_point_plots.py +3 -0
- foxes/output/state_turbine_map.py +3 -0
- foxes/output/turbine_type_curves.py +3 -0
- foxes/utils/dict.py +46 -34
- foxes/utils/factory.py +2 -2
- foxes/utils/xarray_utils.py +20 -12
- {foxes-1.4.dist-info → foxes-1.5.1.dist-info}/METADATA +32 -52
- {foxes-1.4.dist-info → foxes-1.5.1.dist-info}/RECORD +94 -86
- foxes/input/states/field_data_nc.py +0 -833
- {foxes-1.4.dist-info → foxes-1.5.1.dist-info}/WHEEL +0 -0
- {foxes-1.4.dist-info → foxes-1.5.1.dist-info}/entry_points.txt +0 -0
- {foxes-1.4.dist-info → foxes-1.5.1.dist-info}/licenses/LICENSE +0 -0
- {foxes-1.4.dist-info → foxes-1.5.1.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from foxes.utils import Dict
|
|
2
|
-
from foxes.core import WakeModel,
|
|
2
|
+
from foxes.core import WakeModel, WakeDeflection
|
|
3
3
|
import foxes.variables as FV
|
|
4
4
|
|
|
5
5
|
|
|
@@ -21,7 +21,7 @@ def _read_wind_deficit(
|
|
|
21
21
|
"Bastankhah2016": "Bastankhah2016",
|
|
22
22
|
"TurbOPark": "TurbOPark",
|
|
23
23
|
},
|
|
24
|
-
|
|
24
|
+
_name="wind_def_map",
|
|
25
25
|
)
|
|
26
26
|
|
|
27
27
|
ws_sup_dict = Dict(
|
|
@@ -29,16 +29,18 @@ def _read_wind_deficit(
|
|
|
29
29
|
"Linear": "ws_linear",
|
|
30
30
|
"Squared": "ws_quadratic",
|
|
31
31
|
"Product": "ws_product",
|
|
32
|
+
"Vector": "vector",
|
|
32
33
|
},
|
|
33
|
-
|
|
34
|
+
_name="ws_sup_dict",
|
|
34
35
|
)
|
|
35
36
|
ws_sup_amb_dict = Dict(
|
|
36
37
|
{
|
|
37
38
|
"Linear": "ws_linear_amb",
|
|
38
39
|
"Squared": "ws_quadratic_amb",
|
|
39
40
|
"Product": "ws_product",
|
|
41
|
+
"Vector": "vector",
|
|
40
42
|
},
|
|
41
|
-
|
|
43
|
+
_name="ws_sup_dict",
|
|
42
44
|
)
|
|
43
45
|
|
|
44
46
|
wname = wind_deficit.pop_item("name")
|
|
@@ -49,7 +51,7 @@ def _read_wind_deficit(
|
|
|
49
51
|
print(" Eff ws :", eff_ws)
|
|
50
52
|
print(" Contents:", [k for k in wind_deficit.keys()])
|
|
51
53
|
wind_def_dict = Dict(wmodel_type=wind_def_map[wname], induction=induction)
|
|
52
|
-
kcoef = Dict(wind_deficit["wake_expansion_coefficient"],
|
|
54
|
+
kcoef = Dict(wind_deficit["wake_expansion_coefficient"], _name="kcoef")
|
|
53
55
|
ka = kcoef["k_a"]
|
|
54
56
|
kb = kcoef.get_item("k_b", 0.0)
|
|
55
57
|
amb_ti = kcoef.get_item("free_stream_ti", False)
|
|
@@ -100,7 +102,7 @@ def _read_turbulence(
|
|
|
100
102
|
"CrespoHernandez": "CrespoHernandezTIWake",
|
|
101
103
|
"IEC-TI-2019": "IECTIWake",
|
|
102
104
|
},
|
|
103
|
-
|
|
105
|
+
_name="twake_def_map",
|
|
104
106
|
)
|
|
105
107
|
|
|
106
108
|
ti_sup_dict = Dict(
|
|
@@ -108,7 +110,7 @@ def _read_turbulence(
|
|
|
108
110
|
"Linear": "ti_linear",
|
|
109
111
|
"Squared": "ti_quadratic",
|
|
110
112
|
},
|
|
111
|
-
|
|
113
|
+
_name="ti_sup_dict",
|
|
112
114
|
)
|
|
113
115
|
|
|
114
116
|
wname = turbulence_model.pop_item("name")
|
|
@@ -122,7 +124,7 @@ def _read_turbulence(
|
|
|
122
124
|
tiwake_dict["opening_angle"] = None
|
|
123
125
|
tiwake_dict["iec_type"] = "2019"
|
|
124
126
|
if "wake_expansion_coefficient" in turbulence_model:
|
|
125
|
-
kcoef = Dict(turbulence_model["wake_expansion_coefficient"],
|
|
127
|
+
kcoef = Dict(turbulence_model["wake_expansion_coefficient"], _name="kcoef")
|
|
126
128
|
ka = kcoef["k_a"]
|
|
127
129
|
kb = kcoef.get_item("k_b", 0.0)
|
|
128
130
|
amb_ti = kcoef.get_item("free_stream_ti", False)
|
|
@@ -156,7 +158,7 @@ def _read_blockage(blockage_model, induction, algo_dict, mbook, verbosity):
|
|
|
156
158
|
"SelfSimilarityDeficit": "SelfSimilar",
|
|
157
159
|
"SelfSimilarityDeficit2020": "SelfSimilar2020",
|
|
158
160
|
},
|
|
159
|
-
|
|
161
|
+
_name="twake_def_map",
|
|
160
162
|
)
|
|
161
163
|
|
|
162
164
|
wname = blockage_model.pop_item("name")
|
|
@@ -230,10 +232,12 @@ def _read_deflection(deflection, induction, algo_dict, mbook, verbosity):
|
|
|
230
232
|
"""Reads deflection model"""
|
|
231
233
|
defl_def_map = Dict(
|
|
232
234
|
{
|
|
233
|
-
"None": "
|
|
234
|
-
"Batankhah2016": "
|
|
235
|
+
"None": "NoDeflection",
|
|
236
|
+
"Batankhah2016": "Bastankhah2016Deflection",
|
|
237
|
+
"Jimenez": "JimenezDeflection",
|
|
238
|
+
"JimenezVector": "JimenezDeflection",
|
|
235
239
|
},
|
|
236
|
-
|
|
240
|
+
_name="defl_def_map",
|
|
237
241
|
)
|
|
238
242
|
|
|
239
243
|
wname = deflection.pop_item("name")
|
|
@@ -241,15 +245,24 @@ def _read_deflection(deflection, induction, algo_dict, mbook, verbosity):
|
|
|
241
245
|
print(" Reading deflection_model")
|
|
242
246
|
print(" Name:", wname)
|
|
243
247
|
print(" Contents:", [k for k in deflection.keys()])
|
|
244
|
-
|
|
248
|
+
defl_dict = Dict(wdefl_type=defl_def_map[wname])
|
|
249
|
+
if wname == "Jimenez" and "rotate" not in defl_dict:
|
|
250
|
+
defl_dict["rotate"] = False
|
|
251
|
+
elif wname == "JimenezVector":
|
|
252
|
+
assert "rotate" not in defl_dict, (
|
|
253
|
+
f"Deflection model '{wname}' does not support 'rotate' parameter"
|
|
254
|
+
)
|
|
255
|
+
defl_dict["rotate"] = True
|
|
245
256
|
try:
|
|
246
|
-
mbook.
|
|
257
|
+
mbook.wake_deflections[wname] = WakeDeflection.new(
|
|
258
|
+
**defl_dict, induction=induction
|
|
259
|
+
)
|
|
247
260
|
except TypeError:
|
|
248
|
-
mbook.
|
|
261
|
+
mbook.wake_deflections[wname] = WakeDeflection.new(**defl_dict)
|
|
249
262
|
if verbosity > 2:
|
|
250
|
-
print(f" Created wake
|
|
251
|
-
print(" ", mbook.
|
|
252
|
-
algo_dict["
|
|
263
|
+
print(f" Created wake deflection '{wname}':")
|
|
264
|
+
print(" ", mbook.wake_deflections[wname])
|
|
265
|
+
algo_dict["wake_deflection"] = wname
|
|
253
266
|
|
|
254
267
|
|
|
255
268
|
def _read_analysis(wio_ana, idict, mbook, verbosity):
|
|
@@ -260,7 +273,7 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
|
|
|
260
273
|
|
|
261
274
|
# superposition:
|
|
262
275
|
superposition = Dict(
|
|
263
|
-
wio_ana["superposition_model"],
|
|
276
|
+
wio_ana["superposition_model"], _name=wio_ana.name + ".superposition_model"
|
|
264
277
|
)
|
|
265
278
|
if verbosity > 2:
|
|
266
279
|
print(" Reading superposition_model")
|
|
@@ -272,7 +285,7 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
|
|
|
272
285
|
"1D": "Betz",
|
|
273
286
|
"Madsen": "Madsen",
|
|
274
287
|
},
|
|
275
|
-
|
|
288
|
+
_name="induction mapping",
|
|
276
289
|
)
|
|
277
290
|
induction = imap[wio_ana.get_item("axial_induction_model", "1D")]
|
|
278
291
|
if verbosity > 2:
|
|
@@ -284,7 +297,7 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
|
|
|
284
297
|
)
|
|
285
298
|
algo_dict = idict["algorithm"]
|
|
286
299
|
wind_deficit = Dict(
|
|
287
|
-
wio_ana[wake_model_key],
|
|
300
|
+
wio_ana[wake_model_key], _name=wio_ana.name + "." + wake_model_key
|
|
288
301
|
)
|
|
289
302
|
ka, kb, amb_ti = _read_wind_deficit(
|
|
290
303
|
wake_model_key,
|
|
@@ -298,7 +311,7 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
|
|
|
298
311
|
|
|
299
312
|
# turbulence model:
|
|
300
313
|
if "turbulence_model" in wio_ana:
|
|
301
|
-
turbulence_model = Dict(wio_ana["turbulence_model"],
|
|
314
|
+
turbulence_model = Dict(wio_ana["turbulence_model"], _name="turbulence_model")
|
|
302
315
|
_read_turbulence(
|
|
303
316
|
turbulence_model,
|
|
304
317
|
superposition,
|
|
@@ -315,21 +328,21 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
|
|
|
315
328
|
|
|
316
329
|
# blockage model:
|
|
317
330
|
if "blockage_model" in wio_ana:
|
|
318
|
-
blockage_model = Dict(wio_ana["blockage_model"],
|
|
331
|
+
blockage_model = Dict(wio_ana["blockage_model"], _name="blockage_model")
|
|
319
332
|
_read_blockage(blockage_model, induction, algo_dict, mbook, verbosity)
|
|
320
333
|
elif verbosity > 0:
|
|
321
334
|
print("blockage_model not found, not using a turbine induction model")
|
|
322
335
|
|
|
323
336
|
# rotor_averaging:
|
|
324
337
|
if "rotor_averaging" in wio_ana:
|
|
325
|
-
rotor_averaging = Dict(wio_ana["rotor_averaging"],
|
|
338
|
+
rotor_averaging = Dict(wio_ana["rotor_averaging"], _name="rotor_averaging")
|
|
326
339
|
_read_rotor_averaging(rotor_averaging, algo_dict, verbosity)
|
|
327
340
|
elif verbosity > 0:
|
|
328
341
|
print("rotor_averaging not found, using default settings")
|
|
329
342
|
|
|
330
343
|
# deflection:
|
|
331
344
|
if "deflection_model" in wio_ana:
|
|
332
|
-
deflection = Dict(wio_ana["deflection_model"],
|
|
345
|
+
deflection = Dict(wio_ana["deflection_model"], _name="deflection_model")
|
|
333
346
|
_read_deflection(deflection, induction, algo_dict, mbook, verbosity)
|
|
334
347
|
elif verbosity > 0:
|
|
335
348
|
print("deflection_model not found, using default settings")
|
|
@@ -359,7 +372,7 @@ def read_attributes(wio_attrs, idict, mbook, verbosity=1):
|
|
|
359
372
|
|
|
360
373
|
# read flow model:
|
|
361
374
|
if "flow_model" in wio_attrs:
|
|
362
|
-
flow_model = Dict(wio_attrs["flow_model"],
|
|
375
|
+
flow_model = Dict(wio_attrs["flow_model"], _name="flow_model")
|
|
363
376
|
fmname = flow_model.pop_item("name")
|
|
364
377
|
if verbosity > 2:
|
|
365
378
|
print(" Reading flow_model")
|
|
@@ -369,5 +382,5 @@ def read_attributes(wio_attrs, idict, mbook, verbosity=1):
|
|
|
369
382
|
print(f"Running flow model 'foxes', overruling original choice '{fmname}'")
|
|
370
383
|
|
|
371
384
|
# read analysis:
|
|
372
|
-
wio_ana = Dict(wio_attrs["analysis"],
|
|
385
|
+
wio_ana = Dict(wio_attrs["analysis"], _name=wio_attrs.name + ".analysis")
|
|
373
386
|
_read_analysis(wio_ana, idict, mbook, verbosity)
|
|
@@ -38,7 +38,9 @@ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
38
38
|
print(*args, **kwargs)
|
|
39
39
|
|
|
40
40
|
if "turbine_types" not in wio_farm:
|
|
41
|
-
wio_farm["turbine_types"] =
|
|
41
|
+
wio_farm["turbine_types"] = Dict(
|
|
42
|
+
{0: wio_farm["turbines"]}, _name="turbine_types"
|
|
43
|
+
)
|
|
42
44
|
|
|
43
45
|
ttypes = {}
|
|
44
46
|
for k, wio_trbns in wio_farm["turbine_types"].items():
|
|
@@ -49,18 +51,18 @@ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
49
51
|
_print(" Contents:", [k for k in wio_trbns.keys()], level=3)
|
|
50
52
|
|
|
51
53
|
# read performance:
|
|
52
|
-
performance =
|
|
54
|
+
performance = wio_trbns["performance"]
|
|
53
55
|
_print(" Reading performance", level=3)
|
|
54
56
|
_print(" Contents:", [k for k in performance.keys()], level=3)
|
|
55
57
|
|
|
56
58
|
# P, ct data:
|
|
57
59
|
if "power_curve" in performance:
|
|
58
|
-
power_curve =
|
|
60
|
+
power_curve = performance["power_curve"]
|
|
59
61
|
_print(" Reading power_curve", level=3)
|
|
60
62
|
_print(" Contents:", [k for k in power_curve.keys()], level=3)
|
|
61
63
|
P = power_curve["power_values"]
|
|
62
64
|
ws_P = power_curve["power_wind_speeds"]
|
|
63
|
-
ct_curve =
|
|
65
|
+
ct_curve = performance["Ct_curve"]
|
|
64
66
|
_print(" Reading Ct_curve", level=3)
|
|
65
67
|
_print(" Contents:", [k for k in ct_curve.keys()], level=3)
|
|
66
68
|
ct = ct_curve["Ct_values"]
|
|
@@ -96,12 +98,12 @@ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
96
98
|
|
|
97
99
|
# P, ct data:
|
|
98
100
|
elif "Cp_curve" in performance:
|
|
99
|
-
cp_curve =
|
|
101
|
+
cp_curve = performance["Cp_curve"]
|
|
100
102
|
_print(" Reading Cp_curve", level=3)
|
|
101
103
|
_print(" Contents:", [k for k in cp_curve.keys()], level=3)
|
|
102
104
|
cp = cp_curve["Cp_values"]
|
|
103
105
|
ws_cp = cp_curve["Cp_wind_speeds"]
|
|
104
|
-
ct_curve =
|
|
106
|
+
ct_curve = performance["Ct_curve"]
|
|
105
107
|
_print(" Reading Ct_curve", level=3)
|
|
106
108
|
_print(" Contents:", [k for k in ct_curve.keys()], level=3)
|
|
107
109
|
ct = ct_curve["Ct_values"]
|
|
@@ -154,7 +156,7 @@ def read_layout(lname, ldict, farm, ttypes, verbosity=1):
|
|
|
154
156
|
"""
|
|
155
157
|
if verbosity > 2:
|
|
156
158
|
print(f" Reading '{lname}'")
|
|
157
|
-
cdict =
|
|
159
|
+
cdict = ldict["coordinates"]
|
|
158
160
|
tmap = ldict.get_item("turbine_types", None)
|
|
159
161
|
if verbosity > 2:
|
|
160
162
|
print(" Turbine type map:", tmap)
|
|
@@ -187,7 +189,7 @@ def read_farm(wio_dict, mbook, verbosity):
|
|
|
187
189
|
:group: input.yaml.windio
|
|
188
190
|
|
|
189
191
|
"""
|
|
190
|
-
wio_farm =
|
|
192
|
+
wio_farm = wio_dict["wind_farm"]
|
|
191
193
|
if verbosity > 1:
|
|
192
194
|
print("Reading wind farm")
|
|
193
195
|
print(" Name:", wio_farm.pop_item("name", None))
|
|
@@ -209,10 +211,10 @@ def read_farm(wio_dict, mbook, verbosity):
|
|
|
209
211
|
farm = WindFarm()
|
|
210
212
|
wfarm = wio_farm["layouts"]
|
|
211
213
|
if isinstance(wfarm, dict):
|
|
212
|
-
layouts = Dict(wfarm,
|
|
214
|
+
layouts = Dict(wfarm, _name=wio_farm.name + ".layouts")
|
|
213
215
|
else:
|
|
214
216
|
layouts = {str(i): lf for i, lf in enumerate(wfarm)}
|
|
215
|
-
layouts = Dict(layouts,
|
|
217
|
+
layouts = Dict(layouts, _name=wio_farm.name + ".layouts")
|
|
216
218
|
if verbosity > 2:
|
|
217
219
|
print(" Reading layouts")
|
|
218
220
|
print(" Contents:", [k for k in layouts.keys()])
|
|
@@ -12,9 +12,7 @@ def _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity):
|
|
|
12
12
|
if "turbine_outputs" in wio_outs and wio_outs["turbine_outputs"].get_item(
|
|
13
13
|
"report", True
|
|
14
14
|
):
|
|
15
|
-
turbine_outputs =
|
|
16
|
-
wio_outs["turbine_outputs"], name=wio_outs.name + ".turbine_outputs"
|
|
17
|
-
)
|
|
15
|
+
turbine_outputs = wio_outs["turbine_outputs"]
|
|
18
16
|
turbine_nc_filename = turbine_outputs.pop_item(
|
|
19
17
|
"turbine_nc_filename", "turbine_outputs.nc"
|
|
20
18
|
)
|
|
@@ -27,6 +25,7 @@ def _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity):
|
|
|
27
25
|
vmap = Dict(
|
|
28
26
|
power=FV.P,
|
|
29
27
|
rotor_effective_velocity=FV.REWS,
|
|
28
|
+
_name="vmap",
|
|
30
29
|
)
|
|
31
30
|
ivmap = {d: k for k, d in vmap.items()}
|
|
32
31
|
ivmap.update(
|
|
@@ -56,7 +55,7 @@ def _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity):
|
|
|
56
55
|
verbosity=verbosity,
|
|
57
56
|
)
|
|
58
57
|
],
|
|
59
|
-
|
|
58
|
+
_name=f"outputs.{len(olist)}.StateTurbineTable",
|
|
60
59
|
)
|
|
61
60
|
)
|
|
62
61
|
|
|
@@ -64,13 +63,11 @@ def _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity):
|
|
|
64
63
|
def _read_flow_field(wio_outs, olist, algo, states_isel, verbosity):
|
|
65
64
|
"""Reads the flow field request"""
|
|
66
65
|
if "flow_field" in wio_outs and wio_outs["flow_field"].get_item("report", True):
|
|
67
|
-
flow_field =
|
|
66
|
+
flow_field = wio_outs["flow_field"]
|
|
68
67
|
flow_nc_filename = flow_field.pop_item("flow_nc_filename", "flow_field.nc")
|
|
69
68
|
output_variables = flow_field.pop_item("output_variables")
|
|
70
69
|
|
|
71
|
-
z_planes =
|
|
72
|
-
flow_field.pop_item("z_planes"), name=flow_field.name + ".z_planes"
|
|
73
|
-
)
|
|
70
|
+
z_planes = flow_field.pop_item("z_planes")
|
|
74
71
|
z_sampling = z_planes["z_sampling"]
|
|
75
72
|
xy_sampling = z_planes["xy_sampling"]
|
|
76
73
|
|
|
@@ -85,6 +82,7 @@ def _read_flow_field(wio_outs, olist, algo, states_isel, verbosity):
|
|
|
85
82
|
vmap = Dict(
|
|
86
83
|
wind_speed=FV.WS,
|
|
87
84
|
wind_direction=FV.WD,
|
|
85
|
+
_name="vmap",
|
|
88
86
|
)
|
|
89
87
|
|
|
90
88
|
z_list = []
|
|
@@ -147,7 +145,7 @@ def _read_flow_field(wio_outs, olist, algo, states_isel, verbosity):
|
|
|
147
145
|
verbosity=verbosity,
|
|
148
146
|
)
|
|
149
147
|
],
|
|
150
|
-
|
|
148
|
+
_name=f"outputs.output{len(olist)}.SliceData",
|
|
151
149
|
)
|
|
152
150
|
)
|
|
153
151
|
else:
|
|
@@ -187,13 +185,25 @@ def read_outputs(wio_outs, idict, algo, verbosity=1):
|
|
|
187
185
|
print(" Contents :", [k for k in wio_outs.keys()])
|
|
188
186
|
|
|
189
187
|
# read subset:
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
188
|
+
run_configuration = wio_outs.pop_item("run_configuration", {})
|
|
189
|
+
if "times_run" in run_configuration:
|
|
190
|
+
times_run = run_configuration.pop_item("times_run")
|
|
191
|
+
if times_run.get_item("all_occurences"):
|
|
192
|
+
states_isel = None
|
|
193
|
+
else:
|
|
194
|
+
states_isel = times_run.get_item("subset")
|
|
195
|
+
elif "wind_speeds_run" in run_configuration:
|
|
196
|
+
wind_speeds_run = run_configuration.get_item("wind_speeds_run")
|
|
197
|
+
directions_run = run_configuration.get_item("directions_run")
|
|
198
|
+
if not wind_speeds_run.get_item("all_values"):
|
|
199
|
+
raise NotImplementedError(
|
|
200
|
+
f"Wind speed and direction subsets are not yet supported, got {wind_speeds_run.name} {wind_speeds_run}"
|
|
201
|
+
)
|
|
202
|
+
if not directions_run.get_item("all_values"):
|
|
203
|
+
raise NotImplementedError(
|
|
204
|
+
f"Wind speed and direction subsets are not yet supported, got {directions_run.name} {directions_run}"
|
|
205
|
+
)
|
|
194
206
|
states_isel = None
|
|
195
|
-
else:
|
|
196
|
-
states_isel = cases_run.pop_item("subset")
|
|
197
207
|
|
|
198
208
|
# read turbine_outputs:
|
|
199
209
|
_read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity)
|
|
@@ -197,7 +197,7 @@ def _get_WeibullSectors(
|
|
|
197
197
|
dict(
|
|
198
198
|
states_type="WeibullSectors",
|
|
199
199
|
data_source=sdata,
|
|
200
|
-
ws_bins=
|
|
200
|
+
ws_bins=np.arange(60) / 2 if FV.WS not in sdata else None,
|
|
201
201
|
output_vars=ovars,
|
|
202
202
|
var2ncvar={FV.WEIGHT: "sector_probability"},
|
|
203
203
|
fixed_vars=fix,
|
|
@@ -208,6 +208,113 @@ def _get_WeibullSectors(
|
|
|
208
208
|
return False
|
|
209
209
|
|
|
210
210
|
|
|
211
|
+
def _get_WeibullPointCloud(
|
|
212
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
213
|
+
):
|
|
214
|
+
"""Try to generate Weibull sector parameters
|
|
215
|
+
:group: input.yaml.windio
|
|
216
|
+
"""
|
|
217
|
+
if (
|
|
218
|
+
FV.WD in coords
|
|
219
|
+
and FV.WEIBULL_A in fields
|
|
220
|
+
and FV.WEIBULL_k in fields
|
|
221
|
+
and "sector_probability" in fields
|
|
222
|
+
and FV.X in fields
|
|
223
|
+
and FV.Y in fields
|
|
224
|
+
and len(dims[FV.X]) == 1
|
|
225
|
+
and dims[FV.X] == dims[FV.Y]
|
|
226
|
+
and dims[FV.X][0] != FV.WD
|
|
227
|
+
and dims[FV.X][0] in coords
|
|
228
|
+
):
|
|
229
|
+
if verbosity > 2:
|
|
230
|
+
print(" selecting class 'WeibullPointCloud'")
|
|
231
|
+
|
|
232
|
+
data = {}
|
|
233
|
+
fix = {}
|
|
234
|
+
for v, d in fields.items():
|
|
235
|
+
if len(dims[v]) == 0:
|
|
236
|
+
fix[v] = d
|
|
237
|
+
elif v not in fixval:
|
|
238
|
+
data[v] = (dims[v], d)
|
|
239
|
+
fix.update({v: d for v, d in fixval.items() if v not in data})
|
|
240
|
+
|
|
241
|
+
sdata = Dataset(
|
|
242
|
+
coords=coords,
|
|
243
|
+
data_vars=data,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
states_dict.update(
|
|
247
|
+
dict(
|
|
248
|
+
states_type="WeibullPointCloud",
|
|
249
|
+
data_source=sdata,
|
|
250
|
+
output_vars=ovars,
|
|
251
|
+
var2ncvar={},
|
|
252
|
+
fixed_vars=fix,
|
|
253
|
+
point_coord=dims[FV.X][0],
|
|
254
|
+
wd_coord=FV.WD,
|
|
255
|
+
ws_coord=FV.WS if FV.WS in sdata.coords else None,
|
|
256
|
+
ws_bins=np.arange(60) / 2 if FV.WS not in sdata else None,
|
|
257
|
+
x_ncvar=FV.X,
|
|
258
|
+
y_ncvar=FV.Y,
|
|
259
|
+
h_ncvar=FV.H if FV.H in sdata.data_vars else None,
|
|
260
|
+
weight_ncvar="sector_probability",
|
|
261
|
+
)
|
|
262
|
+
)
|
|
263
|
+
return True
|
|
264
|
+
return False
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def _get_WeibullField(
|
|
268
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
269
|
+
):
|
|
270
|
+
"""Try to generate Weibull sector parameters
|
|
271
|
+
:group: input.yaml.windio
|
|
272
|
+
"""
|
|
273
|
+
if (
|
|
274
|
+
FV.WD in coords
|
|
275
|
+
and FV.X in coords
|
|
276
|
+
and FV.Y in coords
|
|
277
|
+
and FV.WEIBULL_A in fields
|
|
278
|
+
and FV.WEIBULL_k in fields
|
|
279
|
+
and "sector_probability" in fields
|
|
280
|
+
):
|
|
281
|
+
if verbosity > 2:
|
|
282
|
+
print(" selecting class 'WeibullField'")
|
|
283
|
+
|
|
284
|
+
data = {}
|
|
285
|
+
fix = {}
|
|
286
|
+
for v, d in fields.items():
|
|
287
|
+
if len(dims[v]) == 0:
|
|
288
|
+
fix[v] = d
|
|
289
|
+
elif v not in fixval:
|
|
290
|
+
data[v] = (dims[v], d)
|
|
291
|
+
fix.update({v: d for v, d in fixval.items() if v not in data})
|
|
292
|
+
|
|
293
|
+
sdata = Dataset(
|
|
294
|
+
coords=coords,
|
|
295
|
+
data_vars=data,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
states_dict.update(
|
|
299
|
+
dict(
|
|
300
|
+
states_type="WeibullField",
|
|
301
|
+
data_source=sdata,
|
|
302
|
+
output_vars=ovars,
|
|
303
|
+
wd_coord=FV.WD,
|
|
304
|
+
x_coord=FV.X,
|
|
305
|
+
y_coord=FV.Y,
|
|
306
|
+
h_coord=FV.H if FV.H in sdata.coords else None,
|
|
307
|
+
weight_ncvar="sector_probability",
|
|
308
|
+
var2ncvar={},
|
|
309
|
+
fixed_vars=fix,
|
|
310
|
+
ws_bins=np.arange(60) / 2 if FV.WS not in sdata.coords else None,
|
|
311
|
+
ws_coord=FV.WS if FV.WS in sdata.coords else None,
|
|
312
|
+
)
|
|
313
|
+
)
|
|
314
|
+
return True
|
|
315
|
+
return False
|
|
316
|
+
|
|
317
|
+
|
|
211
318
|
def get_states(coords, fields, dims, verbosity=1):
|
|
212
319
|
"""
|
|
213
320
|
Reads states parameters from windio input
|
|
@@ -235,7 +342,7 @@ def get_states(coords, fields, dims, verbosity=1):
|
|
|
235
342
|
print(" Creating states")
|
|
236
343
|
|
|
237
344
|
ovars = [FV.WS, FV.WD, FV.TI, FV.RHO]
|
|
238
|
-
fixval = {FV.
|
|
345
|
+
fixval = {FV.RHO: 1.225}
|
|
239
346
|
profiles = _get_profiles(coords, fields, dims, ovars, fixval, verbosity)
|
|
240
347
|
|
|
241
348
|
states_dict = {}
|
|
@@ -249,9 +356,15 @@ def get_states(coords, fields, dims, verbosity=1):
|
|
|
249
356
|
or _get_MultiHeightNCTimeseries(
|
|
250
357
|
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
251
358
|
)
|
|
359
|
+
or _get_WeibullPointCloud(
|
|
360
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
361
|
+
)
|
|
252
362
|
or _get_WeibullSectors(
|
|
253
363
|
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
254
364
|
)
|
|
365
|
+
or _get_WeibullField(
|
|
366
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
367
|
+
)
|
|
255
368
|
):
|
|
256
369
|
return States.new(**states_dict)
|
|
257
370
|
else:
|
|
@@ -284,32 +397,28 @@ def read_site(wio_dict, verbosity=1):
|
|
|
284
397
|
if verbosity >= level:
|
|
285
398
|
print(*args, **kwargs)
|
|
286
399
|
|
|
287
|
-
wio_site =
|
|
400
|
+
wio_site = wio_dict["site"]
|
|
288
401
|
_print("Reading site")
|
|
289
402
|
_print(" Name:", wio_site.pop_item("name", None))
|
|
290
403
|
_print(" Contents:", [k for k in wio_site.keys()])
|
|
291
404
|
_print(" Ignoring boundaries", level=2)
|
|
292
405
|
|
|
293
406
|
# read energy_resource:
|
|
294
|
-
energy_resource =
|
|
295
|
-
wio_site["energy_resource"], name=wio_site.name + ".energy_resource"
|
|
296
|
-
)
|
|
407
|
+
energy_resource = wio_site["energy_resource"]
|
|
297
408
|
_print(" Reading energy_resource", level=2)
|
|
298
409
|
_print(" Name:", energy_resource.pop_item("name", None), level=2)
|
|
299
410
|
_print(" Contents:", [k for k in energy_resource.keys()], level=2)
|
|
300
411
|
|
|
301
412
|
# read wind_resource:
|
|
302
|
-
wind_resource =
|
|
303
|
-
energy_resource["wind_resource"], name=energy_resource.name + ".wind_resource"
|
|
304
|
-
)
|
|
413
|
+
wind_resource = energy_resource["wind_resource"]
|
|
305
414
|
_print(" Reading wind_resource", level=3)
|
|
306
415
|
_print(" Name:", wind_resource.pop_item("name", None), level=3)
|
|
307
416
|
_print(" Contents:", [k for k in wind_resource.keys()], level=3)
|
|
308
417
|
|
|
309
418
|
# read fields
|
|
310
|
-
coords = Dict(
|
|
311
|
-
fields = Dict(
|
|
312
|
-
dims = Dict(
|
|
419
|
+
coords = Dict(_name="coords")
|
|
420
|
+
fields = Dict(_name="fields")
|
|
421
|
+
dims = Dict(_name="dims")
|
|
313
422
|
for n, d in wind_resource.items():
|
|
314
423
|
read_wind_resource_field(n, d, coords, fields, dims, verbosity)
|
|
315
424
|
if verbosity > 2:
|
|
@@ -41,40 +41,52 @@ def read_windio(wio_dict, verbosity=1):
|
|
|
41
41
|
print(*args, **kwargs)
|
|
42
42
|
|
|
43
43
|
if not isinstance(wio_dict, Dict):
|
|
44
|
-
|
|
44
|
+
tmp = Dict(_name="windio")
|
|
45
|
+
for k, d in wio_dict.items():
|
|
46
|
+
tmp[k] = d
|
|
47
|
+
wio_dict = tmp
|
|
45
48
|
|
|
46
49
|
_print("Reading windio data")
|
|
47
50
|
_print(" Name:", wio_dict.pop_item("name", None))
|
|
48
51
|
_print(" Contents:", [k for k in wio_dict.keys()])
|
|
49
52
|
|
|
50
53
|
idict = Dict(
|
|
51
|
-
wind_farm=Dict(
|
|
54
|
+
wind_farm=Dict(_name="wio2fxs.farm"),
|
|
52
55
|
algorithm=Dict(
|
|
53
56
|
algo_type="Downwind",
|
|
54
57
|
wake_models=[],
|
|
55
|
-
|
|
58
|
+
_name="wio2fxs.algorithm",
|
|
56
59
|
verbosity=verbosity - 3,
|
|
57
60
|
),
|
|
58
|
-
calc_farm=Dict(run=True,
|
|
59
|
-
|
|
61
|
+
calc_farm=Dict(run=True, _name="wio2fxs.calc_farm"),
|
|
62
|
+
_name="wio2fxs",
|
|
60
63
|
)
|
|
61
64
|
|
|
62
65
|
mbook = ModelBook()
|
|
63
66
|
states = read_site(wio_dict, verbosity)
|
|
64
67
|
farm = read_farm(wio_dict, mbook, verbosity)
|
|
65
68
|
|
|
66
|
-
wio_attrs =
|
|
69
|
+
wio_attrs = wio_dict["attributes"]
|
|
67
70
|
read_attributes(wio_attrs, idict, mbook, verbosity=verbosity)
|
|
68
71
|
|
|
72
|
+
# special case WeibullPointCloud:
|
|
73
|
+
if (
|
|
74
|
+
type(states).__name__ == "WeibullPointCloud"
|
|
75
|
+
and idict["algorithm"]["rotor_model"] == "centre"
|
|
76
|
+
):
|
|
77
|
+
_print(
|
|
78
|
+
"Found WeibullPointCloud states, changing rotor model from 'centre' to 'direct_mdata'",
|
|
79
|
+
level=3,
|
|
80
|
+
)
|
|
81
|
+
idict["algorithm"]["rotor_model"] = "direct_mdata"
|
|
82
|
+
|
|
69
83
|
algo = Algorithm.new(
|
|
70
84
|
farm=farm, states=states, mbook=mbook, **idict.pop_item("algorithm")
|
|
71
85
|
)
|
|
72
86
|
|
|
73
87
|
odir = None
|
|
74
88
|
if "model_outputs_specification" in wio_attrs:
|
|
75
|
-
outputs =
|
|
76
|
-
wio_attrs["model_outputs_specification"], name=wio_attrs.name + ".outputs"
|
|
77
|
-
)
|
|
89
|
+
outputs = wio_attrs["model_outputs_specification"]
|
|
78
90
|
odir = read_outputs(outputs, idict, algo, verbosity=verbosity)
|
|
79
91
|
|
|
80
92
|
return idict, algo, odir
|
|
@@ -171,7 +183,7 @@ def foxes_windio():
|
|
|
171
183
|
conda_hint="",
|
|
172
184
|
)
|
|
173
185
|
|
|
174
|
-
wio = Dict(yml_utils.load_yaml(wio_file),
|
|
186
|
+
wio = Dict(yml_utils.load_yaml(wio_file), _name="windio")
|
|
175
187
|
idict, algo, odir = read_windio(wio, verbosity=args.verbosity)
|
|
176
188
|
|
|
177
189
|
if args.output_dir is not None:
|