foxes 0.8.1__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 +25 -13
- foxes/variables.py +37 -0
- {foxes-0.8.1.dist-info → foxes-1.0.dist-info}/METADATA +72 -34
- foxes-1.0.dist-info/RECORD +307 -0
- {foxes-0.8.1.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/plotly_helpers.py +0 -19
- foxes/utils/runners/__init__.py +0 -1
- foxes/utils/runners/runners.py +0 -280
- foxes-0.8.1.dist-info/RECORD +0 -248
- foxes-0.8.1.dist-info/top_level.txt +0 -1
- foxes-0.8.1.dist-info/zip-safe +0 -1
- {foxes-0.8.1.dist-info → foxes-1.0.dist-info}/LICENSE +0 -0
foxes/input/windio/read_farm.py
CHANGED
|
@@ -6,14 +6,14 @@ from foxes.core import Turbine, TurbineType
|
|
|
6
6
|
import foxes.variables as FV
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def
|
|
9
|
+
def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
|
|
10
10
|
"""
|
|
11
11
|
Reads the turbine type from windio
|
|
12
12
|
|
|
13
13
|
Parameters
|
|
14
14
|
----------
|
|
15
|
-
|
|
16
|
-
The windio
|
|
15
|
+
wio_farm: dict
|
|
16
|
+
The windio farm data
|
|
17
17
|
algo_dict: dict
|
|
18
18
|
The algorithm dictionary
|
|
19
19
|
ws_exp_P: int
|
|
@@ -25,107 +25,116 @@ def read_turbine_type(wio_trbns, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
|
|
|
25
25
|
|
|
26
26
|
Returns
|
|
27
27
|
-------
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
ttypes: dict
|
|
29
|
+
Mapping from turbine type key to turbine
|
|
30
|
+
type name in the model book
|
|
30
31
|
|
|
31
32
|
:group: input.windio
|
|
32
33
|
|
|
33
34
|
"""
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
print(" Reading wio_trbns")
|
|
37
|
-
print(" Name:", tname)
|
|
38
|
-
print(" Contents:", [k for k in wio_trbns.keys()])
|
|
39
|
-
|
|
40
|
-
# read performance:
|
|
41
|
-
performance = Dict(wio_trbns["performance"], name="performance")
|
|
42
|
-
if verbosity > 2:
|
|
43
|
-
print(" Reading performance")
|
|
44
|
-
print(" Contents:", [k for k in performance.keys()])
|
|
45
|
-
|
|
46
|
-
# P, ct data:
|
|
47
|
-
if "power_curve" in performance:
|
|
48
|
-
power_curve = Dict(performance["power_curve"], name="power_curve")
|
|
49
|
-
if verbosity > 2:
|
|
50
|
-
print(" Reading power_curve")
|
|
51
|
-
print(" Contents:", [k for k in power_curve.keys()])
|
|
52
|
-
P = power_curve["power_values"]
|
|
53
|
-
ws_P = power_curve["power_wind_speeds"]
|
|
54
|
-
ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
|
|
55
|
-
if verbosity > 2:
|
|
56
|
-
print(" Reading Ct_curve")
|
|
57
|
-
print(" Contents:", [k for k in ct_curve.keys()])
|
|
58
|
-
ct = ct_curve["Ct_values"]
|
|
59
|
-
ws_ct = ct_curve["Ct_wind_speeds"]
|
|
60
|
-
|
|
61
|
-
data_P = pd.DataFrame(data={"ws": ws_P, "P": P})
|
|
62
|
-
data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
|
|
63
|
-
|
|
64
|
-
def _get_wse_var(wse):
|
|
65
|
-
if wse not in [1, 2, 3]:
|
|
66
|
-
raise ValueError(f"Expecting wind speed exponent 1, 2 or 3, got {wse}")
|
|
67
|
-
return FV.REWS if wse == 1 else (FV.REWS2 if wse == 2 else FV.REWS3)
|
|
68
|
-
|
|
69
|
-
if verbosity > 2:
|
|
70
|
-
print(f" Creating model '{tname}'")
|
|
71
|
-
print(f" Turbine type class: PCtFromTwo")
|
|
72
|
-
algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
|
|
73
|
-
ttype_type="PCtFromTwo",
|
|
74
|
-
data_source_P=data_P,
|
|
75
|
-
data_source_ct=data_ct,
|
|
76
|
-
col_ws_P_file="ws",
|
|
77
|
-
col_ws_ct_file="ws",
|
|
78
|
-
col_P="P",
|
|
79
|
-
col_ct="ct",
|
|
80
|
-
H=wio_trbns["hub_height"],
|
|
81
|
-
D=wio_trbns["rotor_diameter"],
|
|
82
|
-
var_ws_ct=_get_wse_var(ws_exp_ct),
|
|
83
|
-
var_ws_P=_get_wse_var(ws_exp_P),
|
|
84
|
-
rho=1.225,
|
|
85
|
-
)
|
|
86
|
-
if verbosity > 2:
|
|
87
|
-
print(" ", algo_dict["mbook"].turbine_types[tname])
|
|
35
|
+
if "turbine_types" not in wio_farm:
|
|
36
|
+
wio_farm["turbine_types"] = {0: wio_farm["turbines"]}
|
|
88
37
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
print(" Reading Cp_curve")
|
|
94
|
-
print(" Contents:", [k for k in cp_curve.keys()])
|
|
95
|
-
cp = cp_curve["Cp_values"]
|
|
96
|
-
ws_cp = cp_curve["Cp_wind_speeds"]
|
|
97
|
-
ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
|
|
38
|
+
ttypes = {}
|
|
39
|
+
for k, wio_trbns in wio_farm["turbine_types"].items():
|
|
40
|
+
tname = wio_trbns.pop("name")
|
|
41
|
+
ttypes[k] = tname
|
|
98
42
|
if verbosity > 2:
|
|
99
|
-
print("
|
|
100
|
-
print("
|
|
101
|
-
|
|
102
|
-
ws_ct = ct_curve["Ct_wind_speeds"]
|
|
103
|
-
|
|
104
|
-
data_cp = pd.DataFrame(data={"ws": ws_cp, "cp": cp})
|
|
105
|
-
data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
|
|
43
|
+
print(" Reading turbine type", k)
|
|
44
|
+
print(" Name:", tname)
|
|
45
|
+
print(" Contents:", [k for k in wio_trbns.keys()])
|
|
106
46
|
|
|
47
|
+
# read performance:
|
|
48
|
+
performance = Dict(wio_trbns["performance"], name="performance")
|
|
107
49
|
if verbosity > 2:
|
|
108
|
-
print(
|
|
109
|
-
print(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
50
|
+
print(" Reading performance")
|
|
51
|
+
print(" Contents:", [k for k in performance.keys()])
|
|
52
|
+
|
|
53
|
+
# P, ct data:
|
|
54
|
+
if "power_curve" in performance:
|
|
55
|
+
power_curve = Dict(performance["power_curve"], name="power_curve")
|
|
56
|
+
if verbosity > 2:
|
|
57
|
+
print(" Reading power_curve")
|
|
58
|
+
print(" Contents:", [k for k in power_curve.keys()])
|
|
59
|
+
P = power_curve["power_values"]
|
|
60
|
+
ws_P = power_curve["power_wind_speeds"]
|
|
61
|
+
ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
|
|
62
|
+
if verbosity > 2:
|
|
63
|
+
print(" Reading Ct_curve")
|
|
64
|
+
print(" Contents:", [k for k in ct_curve.keys()])
|
|
65
|
+
ct = ct_curve["Ct_values"]
|
|
66
|
+
ws_ct = ct_curve["Ct_wind_speeds"]
|
|
67
|
+
|
|
68
|
+
data_P = pd.DataFrame(data={"ws": ws_P, "P": P})
|
|
69
|
+
data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
|
|
70
|
+
|
|
71
|
+
def _get_wse_var(wse):
|
|
72
|
+
if wse not in [1, 2, 3]:
|
|
73
|
+
raise ValueError(
|
|
74
|
+
f"Expecting wind speed exponent 1, 2 or 3, got {wse}"
|
|
75
|
+
)
|
|
76
|
+
return FV.REWS if wse == 1 else (FV.REWS2 if wse == 2 else FV.REWS3)
|
|
77
|
+
|
|
78
|
+
if verbosity > 2:
|
|
79
|
+
print(f" Creating model '{tname}'")
|
|
80
|
+
print(f" Turbine type class: PCtFromTwo")
|
|
81
|
+
algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
|
|
82
|
+
ttype_type="PCtFromTwo",
|
|
83
|
+
data_source_P=data_P,
|
|
84
|
+
data_source_ct=data_ct,
|
|
85
|
+
col_ws_P_file="ws",
|
|
86
|
+
col_ws_ct_file="ws",
|
|
87
|
+
col_P="P",
|
|
88
|
+
col_ct="ct",
|
|
89
|
+
H=wio_trbns["hub_height"],
|
|
90
|
+
D=wio_trbns["rotor_diameter"],
|
|
91
|
+
var_ws_ct=_get_wse_var(ws_exp_ct),
|
|
92
|
+
var_ws_P=_get_wse_var(ws_exp_P),
|
|
93
|
+
rho=1.225,
|
|
94
|
+
)
|
|
95
|
+
if verbosity > 2:
|
|
96
|
+
print(" ", algo_dict["mbook"].turbine_types[tname])
|
|
97
|
+
|
|
98
|
+
# P, ct data:
|
|
99
|
+
elif "Cp_curve" in performance:
|
|
100
|
+
cp_curve = Dict(performance["Cp_curve"], name="Cp_curve")
|
|
101
|
+
if verbosity > 2:
|
|
102
|
+
print(" Reading Cp_curve")
|
|
103
|
+
print(" Contents:", [k for k in cp_curve.keys()])
|
|
104
|
+
cp = cp_curve["Cp_values"]
|
|
105
|
+
ws_cp = cp_curve["Cp_wind_speeds"]
|
|
106
|
+
ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
|
|
107
|
+
if verbosity > 2:
|
|
108
|
+
print(" Reading Ct_curve")
|
|
109
|
+
print(" Contents:", [k for k in ct_curve.keys()])
|
|
110
|
+
ct = ct_curve["Ct_values"]
|
|
111
|
+
ws_ct = ct_curve["Ct_wind_speeds"]
|
|
112
|
+
|
|
113
|
+
data_cp = pd.DataFrame(data={"ws": ws_cp, "cp": cp})
|
|
114
|
+
data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
|
|
115
|
+
|
|
116
|
+
if verbosity > 2:
|
|
117
|
+
print(f" Creating model '{tname}'")
|
|
118
|
+
print(f" Turbine type class: CpCtFromTwo")
|
|
119
|
+
algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
|
|
120
|
+
ttype_type="CpCtFromTwo",
|
|
121
|
+
data_source_cp=data_cp,
|
|
122
|
+
data_source_ct=data_ct,
|
|
123
|
+
col_ws_cp_file="ws",
|
|
124
|
+
col_ws_ct_file="ws",
|
|
125
|
+
col_cp="cp",
|
|
126
|
+
col_ct="ct",
|
|
127
|
+
H=wio_trbns["hub_height"],
|
|
128
|
+
D=wio_trbns["rotor_diameter"],
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
else:
|
|
132
|
+
raise KeyError(f"Expecting either 'power_curve' or 'Cp_curve'")
|
|
133
|
+
|
|
134
|
+
return ttypes
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def read_layout(lname, ldict, algo_dict, ttypes, verbosity=1):
|
|
129
138
|
"""
|
|
130
139
|
Read wind farm layout from windio input
|
|
131
140
|
|
|
@@ -137,8 +146,9 @@ def read_layout(lname, ldict, algo_dict, ttype, verbosity=1):
|
|
|
137
146
|
The layout data
|
|
138
147
|
algo_dict: dict
|
|
139
148
|
The algorithm dictionary
|
|
140
|
-
|
|
141
|
-
|
|
149
|
+
ttypes: dict
|
|
150
|
+
Mapping from turbine type key to turbine
|
|
151
|
+
type name in the model book
|
|
142
152
|
verbosity: int
|
|
143
153
|
The verbosity level, 0=silent
|
|
144
154
|
|
|
@@ -154,10 +164,14 @@ def read_layout(lname, ldict, algo_dict, ttype, verbosity=1):
|
|
|
154
164
|
print(f" Reading '{lname}'")
|
|
155
165
|
cdict = Dict(ldict["coordinates"], name="coordinates")
|
|
156
166
|
farm = algo_dict["farm"]
|
|
157
|
-
|
|
167
|
+
tmap = ldict.get("turbine_types", None)
|
|
168
|
+
if verbosity > 2:
|
|
169
|
+
print(f" Turbine type map:", tmap)
|
|
170
|
+
for i, xy in enumerate(zip(cdict["x"], cdict["y"])):
|
|
171
|
+
tt = ttypes[tmap[i] if tmap is not None else 0]
|
|
158
172
|
farm.add_turbine(
|
|
159
|
-
Turbine(xy=np.array(xy), turbine_models=[
|
|
160
|
-
verbosity=verbosity-3,
|
|
173
|
+
Turbine(xy=np.array(xy), turbine_models=[tt]),
|
|
174
|
+
verbosity=verbosity - 3,
|
|
161
175
|
)
|
|
162
176
|
if verbosity > 2:
|
|
163
|
-
print(f" Added {farm.n_turbines}
|
|
177
|
+
print(f" Added {farm.n_turbines} turbines")
|
|
@@ -28,6 +28,7 @@ wio2foxes = {
|
|
|
28
28
|
"""
|
|
29
29
|
foxes2wio = {d: k for k, d in wio2foxes.items()}
|
|
30
30
|
|
|
31
|
+
|
|
31
32
|
def _read_nondimensional_coordinate(name, wio_data, coords):
|
|
32
33
|
"""read nondimensional coordinate
|
|
33
34
|
:group: input.windio
|
|
@@ -37,6 +38,7 @@ def _read_nondimensional_coordinate(name, wio_data, coords):
|
|
|
37
38
|
return True
|
|
38
39
|
return False
|
|
39
40
|
|
|
41
|
+
|
|
40
42
|
def _read_dimensional_coordinate(name, wio_data, coords):
|
|
41
43
|
"""read dimensional coordinate
|
|
42
44
|
:group: input.windio
|
|
@@ -48,6 +50,7 @@ def _read_dimensional_coordinate(name, wio_data, coords):
|
|
|
48
50
|
return True
|
|
49
51
|
return False
|
|
50
52
|
|
|
53
|
+
|
|
51
54
|
def _read_multi_dimensional_coordinate(name, wio_data, coords):
|
|
52
55
|
"""Read multi dimensional coordinate
|
|
53
56
|
:group: input.windio
|
|
@@ -56,6 +59,7 @@ def _read_multi_dimensional_coordinate(name, wio_data, coords):
|
|
|
56
59
|
name, wio_data, coords
|
|
57
60
|
) or _read_dimensional_coordinate(name, wio_data, coords)
|
|
58
61
|
|
|
62
|
+
|
|
59
63
|
def _read_nondimensional_data(name, wio_data, fields, dims):
|
|
60
64
|
"""read nondimensional data
|
|
61
65
|
:group: input.windio
|
|
@@ -67,6 +71,7 @@ def _read_nondimensional_data(name, wio_data, fields, dims):
|
|
|
67
71
|
return True
|
|
68
72
|
return False
|
|
69
73
|
|
|
74
|
+
|
|
70
75
|
def _read_dimensional_data(name, wio_data, fields, dims):
|
|
71
76
|
"""read dimensional data
|
|
72
77
|
:group: input.windio
|
|
@@ -83,6 +88,7 @@ def _read_dimensional_data(name, wio_data, fields, dims):
|
|
|
83
88
|
return True
|
|
84
89
|
return False
|
|
85
90
|
|
|
91
|
+
|
|
86
92
|
def _read_multi_dimensional_data(name, wio_data, fields, dims):
|
|
87
93
|
"""Read multi dimensional data
|
|
88
94
|
:group: input.windio
|
|
@@ -91,14 +97,15 @@ def _read_multi_dimensional_data(name, wio_data, fields, dims):
|
|
|
91
97
|
name, wio_data, fields, dims
|
|
92
98
|
) or _read_dimensional_data(name, wio_data, fields, dims)
|
|
93
99
|
|
|
100
|
+
|
|
94
101
|
def read_wind_resource_field(
|
|
95
|
-
name,
|
|
96
|
-
wio_data,
|
|
97
|
-
coords,
|
|
98
|
-
fields,
|
|
99
|
-
dims,
|
|
102
|
+
name,
|
|
103
|
+
wio_data,
|
|
104
|
+
coords,
|
|
105
|
+
fields,
|
|
106
|
+
dims,
|
|
100
107
|
verbosity,
|
|
101
|
-
|
|
108
|
+
):
|
|
102
109
|
"""
|
|
103
110
|
Reads wind resource data into fields and dims
|
|
104
111
|
|
|
@@ -5,28 +5,39 @@ from foxes.utils import Dict
|
|
|
5
5
|
import foxes.variables as FV
|
|
6
6
|
import foxes.constants as FC
|
|
7
7
|
|
|
8
|
+
from .read_fields import foxes2wio
|
|
9
|
+
|
|
10
|
+
|
|
8
11
|
def _read_turbine_outputs(wio_outs, odir, out_dicts, verbosity):
|
|
9
|
-
"""
|
|
10
|
-
if "turbine_outputs" in wio_outs and wio_outs["turbine_outputs"].get(
|
|
12
|
+
"""Reads the turbine outputs request"""
|
|
13
|
+
if "turbine_outputs" in wio_outs and wio_outs["turbine_outputs"].get(
|
|
14
|
+
"report", True
|
|
15
|
+
):
|
|
11
16
|
turbine_outputs = Dict(wio_outs["turbine_outputs"], name="turbine_outputs")
|
|
12
|
-
turbine_nc_filename = turbine_outputs.pop(
|
|
17
|
+
turbine_nc_filename = turbine_outputs.pop(
|
|
18
|
+
"turbine_nc_filename", "turbine_outputs.nc"
|
|
19
|
+
)
|
|
13
20
|
output_variables = turbine_outputs["output_variables"]
|
|
14
21
|
if verbosity > 2:
|
|
15
22
|
print(" Reading turbine_outputs")
|
|
16
23
|
print(" File name:", turbine_nc_filename)
|
|
17
24
|
print(" output_variables:", output_variables)
|
|
18
|
-
|
|
25
|
+
|
|
19
26
|
vmap = Dict(
|
|
20
27
|
power=FV.P,
|
|
21
28
|
rotor_effective_velocity=FV.REWS,
|
|
22
29
|
)
|
|
23
30
|
ivmap = {d: k for k, d in vmap.items()}
|
|
24
|
-
ivmap.update(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
ivmap.update(
|
|
32
|
+
{
|
|
33
|
+
FC.STATE: "time",
|
|
34
|
+
FC.TURBINE: "turbine",
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
out_dicts.append(
|
|
39
|
+
Dict(
|
|
40
|
+
{
|
|
30
41
|
"output_type": "StateTurbineTable",
|
|
31
42
|
"farm_results": True,
|
|
32
43
|
"algo": False,
|
|
@@ -34,16 +45,23 @@ def _read_turbine_outputs(wio_outs, odir, out_dicts, verbosity):
|
|
|
34
45
|
"run_kwargs": dict(
|
|
35
46
|
variables=[vmap[v] for v in output_variables],
|
|
36
47
|
name_map=ivmap,
|
|
37
|
-
to_file=odir/turbine_nc_filename,
|
|
48
|
+
to_file=odir / turbine_nc_filename,
|
|
49
|
+
round={
|
|
50
|
+
vw: FV.get_default_digits(vf) for vw, vf in vmap.items()
|
|
51
|
+
},
|
|
38
52
|
verbosity=verbosity,
|
|
39
53
|
),
|
|
40
54
|
"output_yaml_update": {
|
|
41
55
|
"power_table": f"include {turbine_nc_filename}",
|
|
42
56
|
},
|
|
43
|
-
},
|
|
57
|
+
},
|
|
58
|
+
name="turbine_outputs",
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
|
|
44
62
|
|
|
45
63
|
def _read_flow_field(wio_outs, odir, out_dicts, verbosity):
|
|
46
|
-
"""
|
|
64
|
+
"""Reads the flow field request"""
|
|
47
65
|
if "flow_field" in wio_outs and wio_outs["flow_field"].get("report", True):
|
|
48
66
|
flow_field = Dict(wio_outs["flow_field"], name="flow_field")
|
|
49
67
|
flow_nc_filename = flow_field.pop("flow_nc_filename", "flow_field.nc")
|
|
@@ -51,10 +69,15 @@ def _read_flow_field(wio_outs, odir, out_dicts, verbosity):
|
|
|
51
69
|
z_planes = Dict(flow_field.pop("z_planes"), name="z_planes")
|
|
52
70
|
z_sampling = z_planes["z_sampling"]
|
|
53
71
|
xy_sampling = z_planes["xy_sampling"]
|
|
72
|
+
cases_run = Dict(flow_field.pop("cases_run", {}), name="cases_run")
|
|
73
|
+
states_isel = cases_run.get("subset", None)
|
|
74
|
+
if "all_occurences" in cases_run and cases_run.pop("all_occurences"):
|
|
75
|
+
states_isel = None
|
|
54
76
|
if verbosity > 2:
|
|
55
77
|
print(" Reading flow_field")
|
|
56
78
|
print(" File name :", flow_nc_filename)
|
|
57
79
|
print(" output_variables:", output_variables)
|
|
80
|
+
print(" states subset :", states_isel)
|
|
58
81
|
print(" z_sampling :", z_sampling)
|
|
59
82
|
print(" xy_sampling :", xy_sampling)
|
|
60
83
|
|
|
@@ -62,29 +85,47 @@ def _read_flow_field(wio_outs, odir, out_dicts, verbosity):
|
|
|
62
85
|
wind_speed=FV.WS,
|
|
63
86
|
wind_direction=FV.WD,
|
|
64
87
|
)
|
|
65
|
-
|
|
88
|
+
|
|
89
|
+
if z_sampling in ["hub_height", "default"]:
|
|
90
|
+
z = None
|
|
91
|
+
elif isinstance(z_sampling, (int, float)):
|
|
92
|
+
z = z_sampling
|
|
93
|
+
else:
|
|
94
|
+
raise NotImplementedError(
|
|
95
|
+
f"z_sampling '{z_sampling}' of type '{type(z_sampling).__name__}' is not supported (yet). Please give 'hub_height', 'default' or a float."
|
|
96
|
+
)
|
|
97
|
+
|
|
66
98
|
if xy_sampling == "default":
|
|
67
|
-
out_dicts.append(
|
|
99
|
+
out_dicts.append(
|
|
100
|
+
Dict(
|
|
101
|
+
{
|
|
68
102
|
"output_type": "SliceData",
|
|
69
103
|
"farm_results": True,
|
|
70
104
|
"algo": True,
|
|
71
105
|
"verbosity_delta": 3,
|
|
72
106
|
"run_func": "get_states_data_xy",
|
|
73
107
|
"run_kwargs": dict(
|
|
74
|
-
|
|
108
|
+
states_isel=states_isel,
|
|
109
|
+
n_img_points=(100, 100),
|
|
75
110
|
variables=[vmap[v] for v in output_variables],
|
|
76
|
-
z=
|
|
77
|
-
to_file=odir/flow_nc_filename,
|
|
111
|
+
z=z,
|
|
112
|
+
to_file=odir / flow_nc_filename,
|
|
113
|
+
label_map=foxes2wio,
|
|
78
114
|
verbosity=verbosity,
|
|
79
115
|
),
|
|
80
116
|
"output_yaml_update": {
|
|
81
117
|
"flow_field": f"include {flow_nc_filename}",
|
|
82
118
|
},
|
|
83
|
-
},
|
|
119
|
+
},
|
|
120
|
+
name="flow_field",
|
|
121
|
+
)
|
|
122
|
+
)
|
|
84
123
|
else:
|
|
85
|
-
raise NotImplementedError(
|
|
86
|
-
|
|
87
|
-
|
|
124
|
+
raise NotImplementedError(
|
|
125
|
+
f"xy_sampling '{xy_sampling}' is not supported (yet)"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
88
129
|
def read_outputs(wio_outs, algo_dict, verbosity):
|
|
89
130
|
"""
|
|
90
131
|
Reads the windio outputs
|
foxes/input/windio/runner.py
CHANGED
|
@@ -5,7 +5,7 @@ from foxes.output import Output
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def _write_yaml(data, fpath):
|
|
8
|
-
"""
|
|
8
|
+
"""Write the data to yaml"""
|
|
9
9
|
rmap = {
|
|
10
10
|
"include": "!include",
|
|
11
11
|
}
|
|
@@ -13,11 +13,12 @@ def _write_yaml(data, fpath):
|
|
|
13
13
|
yaml.dump(data, file)
|
|
14
14
|
with open(fpath, "r") as f:
|
|
15
15
|
s = f.read()
|
|
16
|
-
with open(fpath,
|
|
16
|
+
with open(fpath, "w") as f:
|
|
17
17
|
for k1, k2 in rmap.items():
|
|
18
18
|
s = s.replace(k1, k2)
|
|
19
19
|
f.write(s)
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
|
|
21
22
|
class WindioRunner:
|
|
22
23
|
"""
|
|
23
24
|
Runner for windio input
|
|
@@ -40,6 +41,10 @@ class WindioRunner:
|
|
|
40
41
|
Name of the written input data file
|
|
41
42
|
file_name_output_yaml: str
|
|
42
43
|
Name of the written output data file
|
|
44
|
+
write_input_yaml: bool
|
|
45
|
+
Flag for writing file_name_input_yaml
|
|
46
|
+
write_output_yaml: bool
|
|
47
|
+
Flag for writing file_name_output_yaml
|
|
43
48
|
verbosity: int
|
|
44
49
|
The verbosity level, 0 = silent
|
|
45
50
|
|
|
@@ -48,15 +53,17 @@ class WindioRunner:
|
|
|
48
53
|
"""
|
|
49
54
|
|
|
50
55
|
def __init__(
|
|
51
|
-
self,
|
|
52
|
-
algo_dict,
|
|
56
|
+
self,
|
|
57
|
+
algo_dict,
|
|
53
58
|
output_dir=".",
|
|
54
|
-
output_dicts=[],
|
|
55
|
-
wio_input_data=None,
|
|
59
|
+
output_dicts=[],
|
|
60
|
+
wio_input_data=None,
|
|
56
61
|
file_name_input_yaml="recorded_input.yaml",
|
|
57
62
|
file_name_output_yaml="recorded_output.yaml",
|
|
63
|
+
write_input_yaml=False,
|
|
64
|
+
write_output_yaml=False,
|
|
58
65
|
verbosity=1,
|
|
59
|
-
|
|
66
|
+
):
|
|
60
67
|
"""
|
|
61
68
|
Conbstructor
|
|
62
69
|
|
|
@@ -74,6 +81,10 @@ class WindioRunner:
|
|
|
74
81
|
Name of the written input data file
|
|
75
82
|
file_name_output_yaml: str
|
|
76
83
|
Name of the written output data file
|
|
84
|
+
write_input_yaml: bool
|
|
85
|
+
Flag for writing file_name_input_yaml
|
|
86
|
+
write_output_yaml: bool
|
|
87
|
+
Flag for writing file_name_output_yaml
|
|
77
88
|
verbosity: int
|
|
78
89
|
The verbosity level, 0 = silent
|
|
79
90
|
|
|
@@ -84,15 +95,17 @@ class WindioRunner:
|
|
|
84
95
|
self.wio_input_data = wio_input_data
|
|
85
96
|
self.file_name_input_yaml = file_name_input_yaml
|
|
86
97
|
self.file_name_output_yaml = file_name_output_yaml
|
|
98
|
+
self.write_input_yaml = write_input_yaml
|
|
99
|
+
self.write_output_yaml = write_output_yaml
|
|
87
100
|
self.verbosity = verbosity
|
|
88
101
|
self.farm_results = None
|
|
89
102
|
self.output_results = None
|
|
90
103
|
|
|
91
104
|
self.__initialized = False
|
|
92
|
-
|
|
105
|
+
|
|
93
106
|
self._output_yaml = {}
|
|
94
|
-
if
|
|
95
|
-
fpath = output_dir/file_name_input_yaml
|
|
107
|
+
if self.write_input_yaml and len(wio_input_data):
|
|
108
|
+
fpath = output_dir / file_name_input_yaml
|
|
96
109
|
self.print(f"Writing file", fpath)
|
|
97
110
|
_write_yaml(wio_input_data, fpath)
|
|
98
111
|
self._output_yaml["wind_energy_system"] = f"include {file_name_input_yaml}"
|
|
@@ -131,7 +144,7 @@ class WindioRunner:
|
|
|
131
144
|
run_fname = odict.pop("run_func")
|
|
132
145
|
run_args = odict.pop("run_args", ())
|
|
133
146
|
run_kwargs = odict.pop("run_kwargs", {})
|
|
134
|
-
|
|
147
|
+
|
|
135
148
|
_odict = odict.copy()
|
|
136
149
|
if "output_yaml_update" in _odict:
|
|
137
150
|
self._output_yaml.update(_odict.pop("output_yaml_update"))
|
|
@@ -142,11 +155,12 @@ class WindioRunner:
|
|
|
142
155
|
o = Output.new(**_odict)
|
|
143
156
|
f = getattr(o, run_fname)
|
|
144
157
|
self.output_results.append(f(*run_args, **run_kwargs))
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
158
|
+
|
|
159
|
+
if self.write_output_yaml:
|
|
160
|
+
fpath = self.output_dir / self.file_name_output_yaml
|
|
161
|
+
self.print(f"Writing file", fpath)
|
|
162
|
+
_write_yaml(self._output_yaml, fpath)
|
|
163
|
+
|
|
150
164
|
def run(self):
|
|
151
165
|
"""Runs all calculations"""
|
|
152
166
|
self.run_farm_calc()
|