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
|
@@ -5,7 +5,9 @@ import foxes.variables as FV
|
|
|
5
5
|
from .read_outputs import read_outputs
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def _read_wind_deficit(
|
|
8
|
+
def _read_wind_deficit(
|
|
9
|
+
wake_model_key, wind_deficit, superposition, induction, algo_dict, verbosity
|
|
10
|
+
):
|
|
9
11
|
"""Reads the wind deficit wake model"""
|
|
10
12
|
|
|
11
13
|
wind_def_map = Dict(
|
|
@@ -22,6 +24,7 @@ def _read_wind_deficit(wind_deficit, superposition, induction, algo_dict, verbos
|
|
|
22
24
|
{
|
|
23
25
|
"Linear": "ws_linear",
|
|
24
26
|
"Quadratic": "ws_quadratic",
|
|
27
|
+
"Product": "ws_product",
|
|
25
28
|
},
|
|
26
29
|
name="ws_sup_dict",
|
|
27
30
|
)
|
|
@@ -29,14 +32,15 @@ def _read_wind_deficit(wind_deficit, superposition, induction, algo_dict, verbos
|
|
|
29
32
|
{
|
|
30
33
|
"Linear": "ws_linear_amb",
|
|
31
34
|
"Quadratic": "ws_quadratic_amb",
|
|
35
|
+
"Product": "ws_product",
|
|
32
36
|
},
|
|
33
37
|
name="ws_sup_dict",
|
|
34
38
|
)
|
|
35
|
-
|
|
39
|
+
|
|
36
40
|
wname = wind_deficit.pop("name")
|
|
37
41
|
eff_ws = wind_deficit.pop("use_effective_ws", True)
|
|
38
42
|
if verbosity > 2:
|
|
39
|
-
print(" Reading
|
|
43
|
+
print(" Reading", wake_model_key)
|
|
40
44
|
print(" Name :", wname)
|
|
41
45
|
print(" Eff ws :", eff_ws)
|
|
42
46
|
print(" Contents:", [k for k in wind_deficit.keys()])
|
|
@@ -73,6 +77,7 @@ def _read_wind_deficit(wind_deficit, superposition, induction, algo_dict, verbos
|
|
|
73
77
|
|
|
74
78
|
return ka, kb, amb_ti
|
|
75
79
|
|
|
80
|
+
|
|
76
81
|
def _read_turbulence(
|
|
77
82
|
turbulence_model, superposition, induction, algo_dict, ka, kb, amb_ti, verbosity
|
|
78
83
|
):
|
|
@@ -99,7 +104,7 @@ def _read_turbulence(
|
|
|
99
104
|
print(" Reading turbulence_model")
|
|
100
105
|
print(" Name:", wname)
|
|
101
106
|
print(" Contents:", [k for k in turbulence_model.keys()])
|
|
102
|
-
if wname
|
|
107
|
+
if wname not in ["None", "none"]:
|
|
103
108
|
tiwake_dict = dict(wmodel_type=twake_def_map[wname], induction=induction)
|
|
104
109
|
if wname == "IEC-TI-2019":
|
|
105
110
|
tiwake_dict["opening_angle"] = None
|
|
@@ -129,6 +134,7 @@ def _read_turbulence(
|
|
|
129
134
|
print(" ", algo_dict["mbook"].wake_models[wname])
|
|
130
135
|
algo_dict["wake_models"].append(wname)
|
|
131
136
|
|
|
137
|
+
|
|
132
138
|
def _read_blockage(blockage_model, induction, algo_dict, verbosity):
|
|
133
139
|
"""Reads the blockage model"""
|
|
134
140
|
indc_def_map = Dict(
|
|
@@ -146,7 +152,7 @@ def _read_blockage(blockage_model, induction, algo_dict, verbosity):
|
|
|
146
152
|
print(" Reading blockage_model")
|
|
147
153
|
print(" Name:", wname)
|
|
148
154
|
print(" Contents:", [k for k in blockage_model.keys()])
|
|
149
|
-
if wname
|
|
155
|
+
if wname not in ["None", "none"]:
|
|
150
156
|
indc_dict = Dict(wmodel_type=indc_def_map[wname], induction=induction)
|
|
151
157
|
algo_dict["mbook"].wake_models[wname] = WakeModel.new(**indc_dict)
|
|
152
158
|
if verbosity > 2:
|
|
@@ -155,6 +161,7 @@ def _read_blockage(blockage_model, induction, algo_dict, verbosity):
|
|
|
155
161
|
algo_dict["wake_models"].append(wname)
|
|
156
162
|
algo_dict["algo_type"] = "Iterative"
|
|
157
163
|
|
|
164
|
+
|
|
158
165
|
def _read_rotor_averaging(rotor_averaging, algo_dict, verbosity):
|
|
159
166
|
"""Reads the rotor averaging"""
|
|
160
167
|
if verbosity > 2:
|
|
@@ -177,16 +184,20 @@ def _read_rotor_averaging(rotor_averaging, algo_dict, verbosity):
|
|
|
177
184
|
print(" wake_averaging :", wake_averaging)
|
|
178
185
|
print(" ws exponent power :", wse_P)
|
|
179
186
|
print(" ws exponent ct :", wse_ct)
|
|
187
|
+
|
|
180
188
|
if background_averaging in ["center", "centre"]:
|
|
181
189
|
algo_dict["rotor_model"] = "centre"
|
|
190
|
+
elif background_averaging in ["none", "None", None]:
|
|
191
|
+
algo_dict["rotor_model"] = None
|
|
182
192
|
elif background_averaging == "grid":
|
|
183
193
|
algo_dict["rotor_model"] = f"grid{nx*ny}"
|
|
184
194
|
else:
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
)
|
|
195
|
+
algo_dict["rotor_model"] = background_averaging
|
|
196
|
+
|
|
188
197
|
if wake_averaging in ["centre", "center"]:
|
|
189
198
|
algo_dict["partial_wakes"] = "centre"
|
|
199
|
+
elif wake_averaging in ["none", "None", "auto", None]:
|
|
200
|
+
algo_dict["partial_wakes"] = None
|
|
190
201
|
elif wake_averaging == "grid":
|
|
191
202
|
if background_averaging == "grid":
|
|
192
203
|
algo_dict["partial_wakes"] = "rotor_points"
|
|
@@ -197,10 +208,12 @@ def _read_rotor_averaging(rotor_averaging, algo_dict, verbosity):
|
|
|
197
208
|
algo_dict["partial_wakes"] = grid
|
|
198
209
|
else:
|
|
199
210
|
algo_dict["partial_wakes"] = wake_averaging
|
|
211
|
+
|
|
200
212
|
if verbosity > 2:
|
|
201
213
|
print(" --> rotor_model :", algo_dict["rotor_model"])
|
|
202
214
|
print(" --> partial_wakes :", algo_dict["partial_wakes"])
|
|
203
215
|
|
|
216
|
+
|
|
204
217
|
def _read_deflection(deflection, induction, algo_dict, verbosity):
|
|
205
218
|
"""Reads deflection model"""
|
|
206
219
|
defl_def_map = Dict(
|
|
@@ -228,6 +241,7 @@ def _read_deflection(deflection, induction, algo_dict, verbosity):
|
|
|
228
241
|
print(" ", algo_dict["mbook"].wake_frames[wname])
|
|
229
242
|
algo_dict["wake_frame"] = wname
|
|
230
243
|
|
|
244
|
+
|
|
231
245
|
def _read_analysis(wio_ana, algo_dict, verbosity):
|
|
232
246
|
"""Reads the windio analyses"""
|
|
233
247
|
if verbosity > 2:
|
|
@@ -253,16 +267,26 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
|
|
|
253
267
|
print(" axial induction model:", induction)
|
|
254
268
|
|
|
255
269
|
# wind deficit model:
|
|
256
|
-
|
|
270
|
+
wake_model_key = (
|
|
271
|
+
"wind_deficit_model" if "wind_deficit_model" in wio_ana else "wake_model"
|
|
272
|
+
)
|
|
273
|
+
wind_deficit = Dict(wio_ana[wake_model_key], name=wake_model_key)
|
|
257
274
|
ka, kb, amb_ti = _read_wind_deficit(
|
|
258
|
-
wind_deficit, superposition, induction, algo_dict, verbosity
|
|
275
|
+
wake_model_key, wind_deficit, superposition, induction, algo_dict, verbosity
|
|
259
276
|
)
|
|
260
277
|
|
|
261
278
|
# turbulence model:
|
|
262
279
|
if "turbulence_model" in wio_ana:
|
|
263
280
|
turbulence_model = Dict(wio_ana["turbulence_model"], name="turbulence_model")
|
|
264
281
|
_read_turbulence(
|
|
265
|
-
turbulence_model,
|
|
282
|
+
turbulence_model,
|
|
283
|
+
superposition,
|
|
284
|
+
induction,
|
|
285
|
+
algo_dict,
|
|
286
|
+
ka,
|
|
287
|
+
kb,
|
|
288
|
+
amb_ti,
|
|
289
|
+
verbosity,
|
|
266
290
|
)
|
|
267
291
|
elif verbosity > 0:
|
|
268
292
|
print("turbulence_model not found, not using a TI wake model")
|
|
@@ -273,22 +297,23 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
|
|
|
273
297
|
_read_blockage(blockage_model, induction, algo_dict, verbosity)
|
|
274
298
|
elif verbosity > 0:
|
|
275
299
|
print("blockage_model not found, not using a turbine induction model")
|
|
276
|
-
|
|
300
|
+
|
|
277
301
|
# rotor_averaging:
|
|
278
302
|
if "rotor_averaging" in wio_ana:
|
|
279
303
|
rotor_averaging = Dict(wio_ana["rotor_averaging"], name="rotor_averaging")
|
|
280
304
|
_read_rotor_averaging(rotor_averaging, algo_dict, verbosity)
|
|
281
305
|
elif verbosity > 0:
|
|
282
306
|
print("rotor_averaging not found, using default settings")
|
|
283
|
-
|
|
307
|
+
|
|
284
308
|
# deflection:
|
|
285
309
|
if "deflection_model" in wio_ana:
|
|
286
310
|
deflection = Dict(wio_ana["deflection_model"], name="deflection_model")
|
|
287
311
|
_read_deflection(deflection, induction, algo_dict, verbosity)
|
|
288
312
|
elif verbosity > 0:
|
|
289
313
|
print("deflection_model not found, using default settings")
|
|
290
|
-
|
|
291
|
-
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def read_attributes(wio, algo_dict, verbosity=1, **output_pars):
|
|
292
317
|
"""
|
|
293
318
|
Reads the attributes part of windio
|
|
294
319
|
|
|
@@ -300,11 +325,15 @@ def read_attributes(wio, algo_dict, verbosity):
|
|
|
300
325
|
The algorithm dictionary
|
|
301
326
|
verbosity: int
|
|
302
327
|
The verbosity level, 0=silent
|
|
328
|
+
**output_pars: dict, optional
|
|
329
|
+
Additional parameters for output reading
|
|
303
330
|
|
|
304
331
|
Returns
|
|
305
332
|
-------
|
|
306
333
|
out_dicts: list of dict
|
|
307
334
|
The output dictionaries
|
|
335
|
+
odir: pathlib.Path
|
|
336
|
+
Path to the output folder
|
|
308
337
|
|
|
309
338
|
:group: input.windio
|
|
310
339
|
|
|
@@ -333,6 +362,8 @@ def read_attributes(wio, algo_dict, verbosity):
|
|
|
333
362
|
out_dicts = []
|
|
334
363
|
if "outputs" in wio_attrs:
|
|
335
364
|
outputs = Dict(wio_attrs["outputs"], name="outputs")
|
|
336
|
-
out_dicts = read_outputs(
|
|
365
|
+
out_dicts, odir = read_outputs(
|
|
366
|
+
outputs, algo_dict, verbosity=verbosity, **output_pars
|
|
367
|
+
)
|
|
337
368
|
|
|
338
|
-
return out_dicts
|
|
369
|
+
return out_dicts, odir
|
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
|
|
|
@@ -136,6 +143,9 @@ def read_wind_resource_field(
|
|
|
136
143
|
"lapse_rate",
|
|
137
144
|
"capping_inversion_thickness",
|
|
138
145
|
"capping_inversion_strength",
|
|
146
|
+
"tau_x",
|
|
147
|
+
"tau_y",
|
|
148
|
+
"fc",
|
|
139
149
|
]:
|
|
140
150
|
if verbosity > 2:
|
|
141
151
|
print(f" Ignoring variable '{name}'")
|