foxes 1.3__py3-none-any.whl → 1.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of foxes might be problematic. Click here for more details.
- docs/source/conf.py +3 -3
- examples/abl_states/run.py +2 -2
- examples/compare_rotors_pwakes/run.py +1 -1
- examples/compare_wakes/run.py +1 -2
- examples/dyn_wakes/run.py +29 -6
- examples/field_data_nc/run.py +1 -1
- examples/induction/run.py +3 -3
- examples/multi_height/run.py +1 -1
- examples/power_mask/run.py +2 -2
- examples/quickstart/run.py +0 -1
- examples/random_timeseries/run.py +3 -4
- examples/scan_row/run.py +3 -3
- examples/sequential/run.py +33 -10
- examples/single_state/run.py +3 -4
- examples/states_lookup_table/run.py +3 -3
- examples/streamline_wakes/run.py +29 -6
- examples/tab_file/run.py +3 -3
- examples/timelines/run.py +29 -5
- examples/timeseries/run.py +3 -3
- examples/timeseries_slurm/run.py +3 -3
- examples/wind_rose/run.py +3 -3
- examples/yawed_wake/run.py +19 -9
- foxes/__init__.py +21 -17
- foxes/algorithms/__init__.py +6 -6
- foxes/algorithms/downwind/__init__.py +2 -2
- foxes/algorithms/downwind/downwind.py +49 -17
- foxes/algorithms/downwind/models/__init__.py +6 -6
- foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -9
- foxes/algorithms/downwind/models/init_farm_data.py +58 -29
- foxes/algorithms/downwind/models/point_wakes_calc.py +7 -13
- foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
- foxes/algorithms/downwind/models/set_amb_point_results.py +6 -6
- foxes/algorithms/iterative/__init__.py +7 -3
- foxes/algorithms/iterative/iterative.py +1 -2
- foxes/algorithms/iterative/models/__init__.py +7 -3
- foxes/algorithms/iterative/models/farm_wakes_calc.py +9 -5
- foxes/algorithms/sequential/__init__.py +3 -3
- foxes/algorithms/sequential/models/__init__.py +2 -2
- foxes/algorithms/sequential/sequential.py +3 -4
- foxes/config/__init__.py +5 -1
- foxes/constants.py +16 -0
- foxes/core/__init__.py +45 -22
- foxes/core/algorithm.py +5 -6
- foxes/core/data.py +94 -22
- foxes/core/data_calc_model.py +4 -2
- foxes/core/engine.py +42 -53
- foxes/core/farm_controller.py +2 -2
- foxes/core/farm_data_model.py +16 -13
- foxes/core/ground_model.py +4 -13
- foxes/core/model.py +24 -6
- foxes/core/partial_wakes_model.py +147 -10
- foxes/core/point_data_model.py +21 -17
- foxes/core/rotor_model.py +4 -3
- foxes/core/states.py +2 -3
- foxes/core/turbine.py +2 -1
- foxes/core/wake_deflection.py +130 -0
- foxes/core/wake_model.py +222 -9
- foxes/core/wake_superposition.py +122 -4
- foxes/core/wind_farm.py +6 -6
- foxes/data/__init__.py +7 -2
- 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/data/states/weibull_sectors_12.csv +13 -0
- foxes/data/states/weibull_sectors_12.nc +0 -0
- foxes/engines/__init__.py +14 -15
- foxes/engines/dask.py +42 -20
- foxes/engines/default.py +2 -2
- foxes/engines/numpy.py +11 -13
- foxes/engines/pool.py +20 -11
- foxes/engines/single.py +8 -6
- foxes/input/__init__.py +3 -3
- foxes/input/farm_layout/__init__.py +9 -8
- foxes/input/farm_layout/from_arrays.py +68 -0
- foxes/input/farm_layout/from_csv.py +1 -1
- foxes/input/farm_layout/ring.py +0 -1
- foxes/input/states/__init__.py +28 -12
- foxes/input/states/create/__init__.py +3 -2
- foxes/input/states/dataset_states.py +710 -0
- foxes/input/states/field_data.py +531 -0
- foxes/input/states/multi_height.py +11 -6
- foxes/input/states/one_point_flow.py +1 -4
- foxes/input/states/point_cloud_data.py +618 -0
- foxes/input/states/scan.py +2 -0
- foxes/input/states/single.py +3 -1
- foxes/input/states/states_table.py +23 -30
- foxes/input/states/weibull_sectors.py +330 -0
- foxes/input/states/wrg_states.py +8 -6
- foxes/input/yaml/__init__.py +9 -3
- foxes/input/yaml/dict.py +42 -41
- foxes/input/yaml/windio/__init__.py +10 -5
- foxes/input/yaml/windio/read_attributes.py +42 -29
- foxes/input/yaml/windio/read_farm.py +17 -15
- foxes/input/yaml/windio/read_fields.py +4 -2
- foxes/input/yaml/windio/read_outputs.py +25 -15
- foxes/input/yaml/windio/read_site.py +172 -11
- foxes/input/yaml/windio/windio.py +23 -11
- foxes/input/yaml/yaml.py +1 -0
- foxes/models/__init__.py +15 -14
- foxes/models/axial_induction/__init__.py +2 -2
- foxes/models/farm_controllers/__init__.py +1 -1
- foxes/models/farm_models/__init__.py +1 -1
- foxes/models/ground_models/__init__.py +3 -2
- foxes/models/ground_models/wake_mirror.py +3 -3
- foxes/models/model_book.py +190 -63
- foxes/models/partial_wakes/__init__.py +6 -6
- foxes/models/partial_wakes/axiwake.py +30 -5
- foxes/models/partial_wakes/centre.py +47 -0
- foxes/models/partial_wakes/rotor_points.py +41 -11
- foxes/models/partial_wakes/segregated.py +2 -25
- foxes/models/partial_wakes/top_hat.py +27 -2
- foxes/models/point_models/__init__.py +4 -4
- foxes/models/rotor_models/__init__.py +4 -3
- foxes/models/rotor_models/centre.py +1 -1
- foxes/models/rotor_models/direct_infusion.py +241 -0
- foxes/models/turbine_models/__init__.py +11 -11
- 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 -9
- 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 -6
- foxes/models/turbine_types/PCt_from_two.py +1 -2
- foxes/models/turbine_types/__init__.py +10 -9
- 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/models/vertical_profiles/__init__.py +7 -7
- foxes/models/wake_deflections/__init__.py +3 -0
- foxes/models/{wake_frames/yawed_wakes.py → wake_deflections/bastankhah2016.py} +32 -111
- foxes/models/wake_deflections/jimenez.py +277 -0
- foxes/models/wake_deflections/no_deflection.py +94 -0
- foxes/models/wake_frames/__init__.py +6 -7
- foxes/models/wake_frames/dynamic_wakes.py +12 -3
- foxes/models/wake_frames/rotor_wd.py +3 -1
- foxes/models/wake_frames/seq_dynamic_wakes.py +41 -7
- foxes/models/wake_frames/streamlines.py +8 -6
- foxes/models/wake_frames/timelines.py +9 -3
- foxes/models/wake_models/__init__.py +7 -7
- foxes/models/wake_models/dist_sliced.py +50 -84
- foxes/models/wake_models/gaussian.py +20 -0
- foxes/models/wake_models/induction/__init__.py +5 -5
- foxes/models/wake_models/induction/rankine_half_body.py +30 -71
- foxes/models/wake_models/induction/rathmann.py +65 -64
- foxes/models/wake_models/induction/self_similar.py +65 -68
- foxes/models/wake_models/induction/self_similar2020.py +0 -3
- foxes/models/wake_models/induction/vortex_sheet.py +71 -75
- foxes/models/wake_models/ti/__init__.py +2 -2
- foxes/models/wake_models/ti/crespo_hernandez.py +5 -3
- foxes/models/wake_models/ti/iec_ti.py +6 -4
- foxes/models/wake_models/top_hat.py +58 -7
- foxes/models/wake_models/wind/__init__.py +6 -4
- foxes/models/wake_models/wind/bastankhah14.py +25 -7
- foxes/models/wake_models/wind/bastankhah16.py +35 -3
- foxes/models/wake_models/wind/jensen.py +15 -2
- foxes/models/wake_models/wind/turbopark.py +28 -2
- foxes/models/wake_superpositions/__init__.py +18 -9
- foxes/models/wake_superpositions/ti_linear.py +4 -4
- foxes/models/wake_superpositions/ti_max.py +4 -4
- foxes/models/wake_superpositions/ti_pow.py +4 -4
- foxes/models/wake_superpositions/ti_quadratic.py +4 -4
- foxes/models/wake_superpositions/wind_vector.py +257 -0
- foxes/models/wake_superpositions/ws_linear.py +9 -10
- foxes/models/wake_superpositions/ws_max.py +8 -8
- foxes/models/wake_superpositions/ws_pow.py +8 -8
- foxes/models/wake_superpositions/ws_product.py +4 -4
- foxes/models/wake_superpositions/ws_quadratic.py +8 -8
- foxes/output/__init__.py +21 -19
- foxes/output/farm_layout.py +4 -2
- foxes/output/farm_results_eval.py +19 -16
- foxes/output/flow_plots_2d/__init__.py +2 -2
- foxes/output/flow_plots_2d/flow_plots.py +18 -0
- foxes/output/flow_plots_2d/get_fig.py +5 -2
- foxes/output/output.py +6 -1
- foxes/output/results_writer.py +1 -1
- foxes/output/rose_plot.py +13 -3
- foxes/output/rotor_point_plots.py +3 -0
- foxes/output/seq_plugins/__init__.py +2 -2
- foxes/output/seq_plugins/seq_flow_ani_plugin.py +0 -3
- foxes/output/seq_plugins/seq_wake_debug_plugin.py +0 -1
- foxes/output/state_turbine_map.py +3 -0
- foxes/output/turbine_type_curves.py +10 -8
- foxes/utils/__init__.py +37 -19
- foxes/utils/abl/__init__.py +4 -4
- foxes/utils/cubic_roots.py +1 -1
- foxes/utils/data_book.py +4 -3
- foxes/utils/dict.py +49 -37
- foxes/utils/exec_python.py +5 -5
- foxes/utils/factory.py +3 -5
- foxes/utils/geom2d/__init__.py +7 -5
- foxes/utils/geopandas_utils.py +2 -2
- foxes/utils/pandas_utils.py +4 -3
- foxes/utils/tab_files.py +0 -1
- foxes/utils/weibull.py +28 -0
- foxes/utils/wrg_utils.py +3 -1
- foxes/utils/xarray_utils.py +9 -2
- foxes/variables.py +67 -9
- {foxes-1.3.dist-info → foxes-1.5.dist-info}/METADATA +34 -63
- foxes-1.5.dist-info/RECORD +328 -0
- {foxes-1.3.dist-info → foxes-1.5.dist-info}/WHEEL +1 -1
- tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +2 -3
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +1 -1
- tests/1_verification/flappy_0_6/abl_states/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +0 -2
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +0 -1
- tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +0 -2
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +0 -1
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +0 -1
- foxes/input/states/field_data_nc.py +0 -847
- foxes/output/round.py +0 -10
- foxes/utils/pandas_helpers.py +0 -178
- foxes-1.3.dist-info/RECORD +0 -313
- {foxes-1.3.dist-info → foxes-1.5.dist-info}/entry_points.txt +0 -0
- {foxes-1.3.dist-info → foxes-1.5.dist-info/licenses}/LICENSE +0 -0
- {foxes-1.3.dist-info → foxes-1.5.dist-info}/top_level.txt +0 -0
|
@@ -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)
|
|
@@ -159,6 +159,162 @@ def _get_MultiHeightNCTimeseries(
|
|
|
159
159
|
return False
|
|
160
160
|
|
|
161
161
|
|
|
162
|
+
def _get_WeibullSectors(
|
|
163
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
164
|
+
):
|
|
165
|
+
"""Try to generate Weibull sector parameters
|
|
166
|
+
:group: input.yaml.windio
|
|
167
|
+
"""
|
|
168
|
+
if (
|
|
169
|
+
FV.WEIBULL_A in fields
|
|
170
|
+
and FV.WEIBULL_k in fields
|
|
171
|
+
and "sector_probability" in fields
|
|
172
|
+
and len(dims[FV.WEIBULL_A]) == 1
|
|
173
|
+
and len(dims[FV.WEIBULL_k]) == 1
|
|
174
|
+
and len(dims["sector_probability"]) == 1
|
|
175
|
+
):
|
|
176
|
+
if verbosity > 2:
|
|
177
|
+
print(" selecting class 'WeibullSectors'")
|
|
178
|
+
|
|
179
|
+
data = {}
|
|
180
|
+
fix = {}
|
|
181
|
+
c = dims[FV.WEIBULL_A][0]
|
|
182
|
+
for v, d in fields.items():
|
|
183
|
+
if dims[v] == (c,):
|
|
184
|
+
data[v] = d
|
|
185
|
+
elif len(dims[v]) == 0:
|
|
186
|
+
fix[v] = d
|
|
187
|
+
elif verbosity > 2:
|
|
188
|
+
print(f" ignoring field '{v}' with dims {dims[v]}")
|
|
189
|
+
fix.update({v: d for v, d in fixval.items() if v not in data})
|
|
190
|
+
|
|
191
|
+
if FV.WD in coords:
|
|
192
|
+
data[FV.WD] = coords[FV.WD]
|
|
193
|
+
|
|
194
|
+
sdata = pd.DataFrame(index=range(len(fields[FV.WEIBULL_A])), data=data)
|
|
195
|
+
sdata.index.name = "sector"
|
|
196
|
+
states_dict.update(
|
|
197
|
+
dict(
|
|
198
|
+
states_type="WeibullSectors",
|
|
199
|
+
data_source=sdata,
|
|
200
|
+
ws_bins=np.arange(60) / 2 if FV.WS not in sdata else None,
|
|
201
|
+
output_vars=ovars,
|
|
202
|
+
var2ncvar={FV.WEIGHT: "sector_probability"},
|
|
203
|
+
fixed_vars=fix,
|
|
204
|
+
profiles=profiles,
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
return True
|
|
208
|
+
return False
|
|
209
|
+
|
|
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
|
+
|
|
162
318
|
def get_states(coords, fields, dims, verbosity=1):
|
|
163
319
|
"""
|
|
164
320
|
Reads states parameters from windio input
|
|
@@ -186,7 +342,7 @@ def get_states(coords, fields, dims, verbosity=1):
|
|
|
186
342
|
print(" Creating states")
|
|
187
343
|
|
|
188
344
|
ovars = [FV.WS, FV.WD, FV.TI, FV.RHO]
|
|
189
|
-
fixval = {FV.
|
|
345
|
+
fixval = {FV.RHO: 1.225}
|
|
190
346
|
profiles = _get_profiles(coords, fields, dims, ovars, fixval, verbosity)
|
|
191
347
|
|
|
192
348
|
states_dict = {}
|
|
@@ -200,6 +356,15 @@ def get_states(coords, fields, dims, verbosity=1):
|
|
|
200
356
|
or _get_MultiHeightNCTimeseries(
|
|
201
357
|
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
202
358
|
)
|
|
359
|
+
or _get_WeibullPointCloud(
|
|
360
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
361
|
+
)
|
|
362
|
+
or _get_WeibullSectors(
|
|
363
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
364
|
+
)
|
|
365
|
+
or _get_WeibullField(
|
|
366
|
+
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
367
|
+
)
|
|
203
368
|
):
|
|
204
369
|
return States.new(**states_dict)
|
|
205
370
|
else:
|
|
@@ -232,32 +397,28 @@ def read_site(wio_dict, verbosity=1):
|
|
|
232
397
|
if verbosity >= level:
|
|
233
398
|
print(*args, **kwargs)
|
|
234
399
|
|
|
235
|
-
wio_site =
|
|
400
|
+
wio_site = wio_dict["site"]
|
|
236
401
|
_print("Reading site")
|
|
237
402
|
_print(" Name:", wio_site.pop_item("name", None))
|
|
238
403
|
_print(" Contents:", [k for k in wio_site.keys()])
|
|
239
404
|
_print(" Ignoring boundaries", level=2)
|
|
240
405
|
|
|
241
406
|
# read energy_resource:
|
|
242
|
-
energy_resource =
|
|
243
|
-
wio_site["energy_resource"], name=wio_site.name + ".energy_resource"
|
|
244
|
-
)
|
|
407
|
+
energy_resource = wio_site["energy_resource"]
|
|
245
408
|
_print(" Reading energy_resource", level=2)
|
|
246
409
|
_print(" Name:", energy_resource.pop_item("name", None), level=2)
|
|
247
410
|
_print(" Contents:", [k for k in energy_resource.keys()], level=2)
|
|
248
411
|
|
|
249
412
|
# read wind_resource:
|
|
250
|
-
wind_resource =
|
|
251
|
-
energy_resource["wind_resource"], name=energy_resource.name + ".wind_resource"
|
|
252
|
-
)
|
|
413
|
+
wind_resource = energy_resource["wind_resource"]
|
|
253
414
|
_print(" Reading wind_resource", level=3)
|
|
254
415
|
_print(" Name:", wind_resource.pop_item("name", None), level=3)
|
|
255
416
|
_print(" Contents:", [k for k in wind_resource.keys()], level=3)
|
|
256
417
|
|
|
257
418
|
# read fields
|
|
258
|
-
coords = Dict(
|
|
259
|
-
fields = Dict(
|
|
260
|
-
dims = Dict(
|
|
419
|
+
coords = Dict(_name="coords")
|
|
420
|
+
fields = Dict(_name="fields")
|
|
421
|
+
dims = Dict(_name="dims")
|
|
261
422
|
for n, d in wind_resource.items():
|
|
262
423
|
read_wind_resource_field(n, d, coords, fields, dims, verbosity)
|
|
263
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
|
-
_print(
|
|
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:
|
foxes/input/yaml/yaml.py
CHANGED
foxes/models/__init__.py
CHANGED
|
@@ -2,18 +2,19 @@
|
|
|
2
2
|
Model collection.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from . import turbine_types
|
|
6
|
-
from . import rotor_models
|
|
7
|
-
from . import turbine_models
|
|
8
|
-
from . import farm_models
|
|
9
|
-
from . import partial_wakes
|
|
10
|
-
from . import wake_frames
|
|
11
|
-
from . import wake_models
|
|
12
|
-
from . import
|
|
13
|
-
from . import
|
|
14
|
-
from . import
|
|
15
|
-
from . import
|
|
16
|
-
from . import
|
|
17
|
-
from . import
|
|
5
|
+
from . import turbine_types as turbine_types
|
|
6
|
+
from . import rotor_models as rotor_models
|
|
7
|
+
from . import turbine_models as turbine_models
|
|
8
|
+
from . import farm_models as farm_models
|
|
9
|
+
from . import partial_wakes as partial_wakes
|
|
10
|
+
from . import wake_frames as wake_frames
|
|
11
|
+
from . import wake_models as wake_models
|
|
12
|
+
from . import wake_deflections as wake_deflections
|
|
13
|
+
from . import wake_superpositions as wake_superpositions
|
|
14
|
+
from . import farm_controllers as farm_controllers
|
|
15
|
+
from . import vertical_profiles as vertical_profiles
|
|
16
|
+
from . import point_models as point_models
|
|
17
|
+
from . import axial_induction as axial_induction
|
|
18
|
+
from . import ground_models as ground_models
|
|
18
19
|
|
|
19
|
-
from .model_book import ModelBook
|
|
20
|
+
from .model_book import ModelBook as ModelBook
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .betz import BetzAxialInduction
|
|
2
|
-
from .madsen import MadsenAxialInduction
|
|
1
|
+
from .betz import BetzAxialInduction as BetzAxialInduction
|
|
2
|
+
from .madsen import MadsenAxialInduction as MadsenAxialInduction
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
from .no_ground import NoGround
|
|
2
|
-
from .wake_mirror import WakeMirror
|
|
1
|
+
from .no_ground import NoGround as NoGround
|
|
2
|
+
from .wake_mirror import WakeMirror as WakeMirror
|
|
3
|
+
from .wake_mirror import GroundMirror as GroundMirror
|
|
@@ -75,13 +75,14 @@ class WakeMirror(GroundModel):
|
|
|
75
75
|
# assert(np.all(fdata[FV.H]==fdata[FV.TXYH[..., 2]]))
|
|
76
76
|
|
|
77
77
|
# contribution from main wake:
|
|
78
|
-
wcoos = algo.wake_frame.get_wake_coos(
|
|
78
|
+
wcoos = algo.wake_frame.get_wake_coos(
|
|
79
|
+
algo, mdata, fdata, tdata, downwind_index, wmodel
|
|
80
|
+
)
|
|
79
81
|
wmodel.contribute(algo, mdata, fdata, tdata, downwind_index, wcoos, wake_deltas)
|
|
80
82
|
|
|
81
83
|
# contribution from mirrors:
|
|
82
84
|
tdata[FC.TARGETS] = tdata[FC.TARGETS].copy() # making sure this is no ref
|
|
83
85
|
for h in self.heights:
|
|
84
|
-
|
|
85
86
|
fdata[FV.TXYH][:, downwind_index, 2] = hh + 2 * (h - hh)
|
|
86
87
|
|
|
87
88
|
pwake.contribute(
|
|
@@ -136,7 +137,6 @@ class WakeMirror(GroundModel):
|
|
|
136
137
|
# contribution from mirrors:
|
|
137
138
|
tdata[FC.TARGETS] = tdata[FC.TARGETS].copy() # making sure this is no ref
|
|
138
139
|
for h in self.heights:
|
|
139
|
-
|
|
140
140
|
fdata[FV.TXYH][:, downwind_index, 2] = hh + 2 * (h - hh)
|
|
141
141
|
|
|
142
142
|
wcoos = algo.wake_frame.get_wake_coos(
|