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,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,30 +85,48 @@ 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
|
-
|
|
88
|
-
|
|
124
|
+
raise NotImplementedError(
|
|
125
|
+
f"xy_sampling '{xy_sampling}' is not supported (yet)"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def read_outputs(wio_outs, algo_dict, output_dir=None, verbosity=1):
|
|
89
130
|
"""
|
|
90
131
|
Reads the windio outputs
|
|
91
132
|
|
|
@@ -95,6 +136,8 @@ def read_outputs(wio_outs, algo_dict, verbosity):
|
|
|
95
136
|
The windio output data
|
|
96
137
|
algo_dict: dict
|
|
97
138
|
The algorithm dictionary
|
|
139
|
+
output_dir: pathlib.Path, optional
|
|
140
|
+
Path to the output folder
|
|
98
141
|
verbosity: int
|
|
99
142
|
The verbosity level, 0=silent
|
|
100
143
|
|
|
@@ -109,7 +152,11 @@ def read_outputs(wio_outs, algo_dict, verbosity):
|
|
|
109
152
|
|
|
110
153
|
"""
|
|
111
154
|
out_dicts = []
|
|
112
|
-
odir =
|
|
155
|
+
odir = (
|
|
156
|
+
Path(output_dir)
|
|
157
|
+
if output_dir is not None
|
|
158
|
+
else Path(wio_outs.pop("output_folder", "results"))
|
|
159
|
+
)
|
|
113
160
|
odir.mkdir(exist_ok=True, parents=True)
|
|
114
161
|
if verbosity > 2:
|
|
115
162
|
print(" Reading 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()
|
foxes/input/windio/windio.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import pandas as pd
|
|
3
1
|
from pathlib import Path
|
|
4
2
|
|
|
5
3
|
from foxes.core import WindFarm
|
|
@@ -9,7 +7,7 @@ from foxes.data import StaticData, WINDIO
|
|
|
9
7
|
|
|
10
8
|
from .read_fields import read_wind_resource_field
|
|
11
9
|
from .get_states import get_states
|
|
12
|
-
from .read_farm import read_layout,
|
|
10
|
+
from .read_farm import read_layout, read_turbine_types
|
|
13
11
|
from .read_attributes import read_attributes
|
|
14
12
|
from .runner import WindioRunner
|
|
15
13
|
|
|
@@ -78,19 +76,28 @@ def _read_farm(wio, algo_dict, verbosity):
|
|
|
78
76
|
ws_exp_ct = 1
|
|
79
77
|
|
|
80
78
|
# read turbine type:
|
|
81
|
-
|
|
82
|
-
ttype = read_turbine_type(turbines, algo_dict, ws_exp_P, ws_exp_ct, verbosity)
|
|
79
|
+
ttypes = read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity)
|
|
83
80
|
|
|
84
81
|
# read layouts:
|
|
85
|
-
|
|
82
|
+
wfarm = wio_farm["layouts"]
|
|
83
|
+
if isinstance(wfarm, dict):
|
|
84
|
+
layouts = Dict(wfarm, name="layouts")
|
|
85
|
+
else:
|
|
86
|
+
layouts = Dict({i: l for i, l in enumerate(wfarm)}, name="layouts")
|
|
86
87
|
if verbosity > 2:
|
|
87
88
|
print(" Reading layouts")
|
|
88
89
|
print(" Contents:", [k for k in layouts.keys()])
|
|
89
90
|
for lname, ldict in layouts.items():
|
|
90
|
-
read_layout(lname, ldict, algo_dict,
|
|
91
|
+
read_layout(lname, ldict, algo_dict, ttypes, verbosity)
|
|
91
92
|
|
|
92
93
|
|
|
93
|
-
def read_windio(
|
|
94
|
+
def read_windio(
|
|
95
|
+
windio_yaml,
|
|
96
|
+
verbosity=1,
|
|
97
|
+
algo_pars=None,
|
|
98
|
+
output_dir=None,
|
|
99
|
+
**runner_pars,
|
|
100
|
+
):
|
|
94
101
|
"""
|
|
95
102
|
Reads a complete WindIO case.
|
|
96
103
|
|
|
@@ -103,6 +110,12 @@ def read_windio(windio_yaml, verbosity=1):
|
|
|
103
110
|
Path to the windio yaml file
|
|
104
111
|
verbosity: int
|
|
105
112
|
The verbosity level, 0 = silent
|
|
113
|
+
algo_pars: dict, optional
|
|
114
|
+
Additional algorithm parameters
|
|
115
|
+
output_dir: str, optional
|
|
116
|
+
Path to the output folder
|
|
117
|
+
runner_pars: dict, optional
|
|
118
|
+
Additional parameters for the WindioRunner
|
|
106
119
|
|
|
107
120
|
Returns
|
|
108
121
|
-------
|
|
@@ -113,7 +126,6 @@ def read_windio(windio_yaml, verbosity=1):
|
|
|
113
126
|
:group: input.windio
|
|
114
127
|
|
|
115
128
|
"""
|
|
116
|
-
|
|
117
129
|
wio_file = Path(windio_yaml)
|
|
118
130
|
if not wio_file.is_file():
|
|
119
131
|
wio_file = StaticData().get_file_path(WINDIO, wio_file, check_raw=False)
|
|
@@ -128,32 +140,38 @@ def read_windio(windio_yaml, verbosity=1):
|
|
|
128
140
|
print(" Name:", wio.pop("name", None))
|
|
129
141
|
print(" Contents:", [k for k in wio.keys()])
|
|
130
142
|
|
|
131
|
-
algo_dict = Dict(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
algo_dict = Dict(algo_type="Downwind", name="algo_dict")
|
|
144
|
+
if algo_pars is not None:
|
|
145
|
+
algo_dict.update(algo_pars)
|
|
146
|
+
algo_dict.update(
|
|
147
|
+
dict(
|
|
148
|
+
mbook=ModelBook(),
|
|
149
|
+
farm=WindFarm(),
|
|
150
|
+
wake_models=[],
|
|
151
|
+
verbosity=verbosity - 3,
|
|
152
|
+
)
|
|
137
153
|
)
|
|
138
154
|
|
|
139
155
|
_read_site(wio, algo_dict, verbosity)
|
|
140
156
|
_read_farm(wio, algo_dict, verbosity)
|
|
141
|
-
|
|
157
|
+
|
|
142
158
|
out_dicts, odir = read_attributes(
|
|
143
159
|
wio,
|
|
144
160
|
algo_dict,
|
|
145
|
-
|
|
161
|
+
output_dir=output_dir,
|
|
162
|
+
verbosity=verbosity,
|
|
146
163
|
)
|
|
147
164
|
|
|
148
165
|
if verbosity > 1:
|
|
149
166
|
print("Creating windio runner")
|
|
150
167
|
runner = WindioRunner(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
168
|
+
algo_dict,
|
|
169
|
+
output_dir=odir,
|
|
170
|
+
output_dicts=out_dicts,
|
|
171
|
+
wio_input_data=wio,
|
|
172
|
+
verbosity=verbosity,
|
|
173
|
+
**runner_pars,
|
|
174
|
+
)
|
|
157
175
|
|
|
158
176
|
return runner
|
|
159
177
|
|
|
@@ -56,7 +56,7 @@ class WakeMirror(GroundModel):
|
|
|
56
56
|
The target point data
|
|
57
57
|
downwind_index: int
|
|
58
58
|
The index of the wake causing turbine
|
|
59
|
-
in the
|
|
59
|
+
in the downwind order
|
|
60
60
|
wake_deltas: dict
|
|
61
61
|
The wake deltas. Key: variable name,
|
|
62
62
|
value: numpy.ndarray with shape
|
|
@@ -70,6 +70,10 @@ class WakeMirror(GroundModel):
|
|
|
70
70
|
# prepare:
|
|
71
71
|
hh = fdata[FV.H][:, downwind_index].copy()
|
|
72
72
|
|
|
73
|
+
# DEBUG CHECK:
|
|
74
|
+
# import numpy as np
|
|
75
|
+
# assert(np.all(fdata[FV.H]==fdata[FV.TXYH[..., 2]]))
|
|
76
|
+
|
|
73
77
|
# contribution from main wake:
|
|
74
78
|
wcoos = algo.wake_frame.get_wake_coos(algo, mdata, fdata, tdata, downwind_index)
|
|
75
79
|
wmodel.contribute(algo, mdata, fdata, tdata, downwind_index, wcoos, wake_deltas)
|
|
@@ -78,14 +82,14 @@ class WakeMirror(GroundModel):
|
|
|
78
82
|
tdata[FC.TARGETS] = tdata[FC.TARGETS].copy() # making sure this is no ref
|
|
79
83
|
for h in self.heights:
|
|
80
84
|
|
|
81
|
-
fdata[FV.
|
|
85
|
+
fdata[FV.TXYH][:, downwind_index, 2] = hh + 2 * (h - hh)
|
|
82
86
|
|
|
83
87
|
pwake.contribute(
|
|
84
88
|
algo, mdata, fdata, tdata, downwind_index, wake_deltas, wmodel
|
|
85
89
|
)
|
|
86
90
|
|
|
87
91
|
# reset heights:
|
|
88
|
-
fdata[FV.
|
|
92
|
+
fdata[FV.TXYH][:, downwind_index, 2] = hh
|
|
89
93
|
|
|
90
94
|
def contribute_to_point_wakes(
|
|
91
95
|
self,
|
|
@@ -113,7 +117,7 @@ class WakeMirror(GroundModel):
|
|
|
113
117
|
The target point data
|
|
114
118
|
downwind_index: int
|
|
115
119
|
The index of the wake causing turbine
|
|
116
|
-
in the
|
|
120
|
+
in the downwind order
|
|
117
121
|
wake_deltas: dict
|
|
118
122
|
The wake deltas. Key: variable name,
|
|
119
123
|
value: numpy.ndarray with shape
|
|
@@ -133,7 +137,7 @@ class WakeMirror(GroundModel):
|
|
|
133
137
|
tdata[FC.TARGETS] = tdata[FC.TARGETS].copy() # making sure this is no ref
|
|
134
138
|
for h in self.heights:
|
|
135
139
|
|
|
136
|
-
fdata[FV.
|
|
140
|
+
fdata[FV.TXYH][:, downwind_index, 2] = hh + 2 * (h - hh)
|
|
137
141
|
|
|
138
142
|
wcoos = algo.wake_frame.get_wake_coos(
|
|
139
143
|
algo, mdata, fdata, tdata, downwind_index
|
|
@@ -143,7 +147,7 @@ class WakeMirror(GroundModel):
|
|
|
143
147
|
)
|
|
144
148
|
|
|
145
149
|
# reset heights:
|
|
146
|
-
fdata[FV.
|
|
150
|
+
fdata[FV.TXYH][:, downwind_index, 2] = hh
|
|
147
151
|
|
|
148
152
|
|
|
149
153
|
class GroundMirror(WakeMirror):
|
foxes/models/model_book.py
CHANGED
|
@@ -85,8 +85,7 @@ class ModelBook:
|
|
|
85
85
|
self.point_models["tke2ti"] = fm.point_models.TKE2TI()
|
|
86
86
|
|
|
87
87
|
self.rotor_models = FDict(name="rotor_models")
|
|
88
|
-
|
|
89
|
-
self.rotor_models["centre"] = fm.rotor_models.CentreRotor(calc_vars=rvars)
|
|
88
|
+
self.rotor_models["centre"] = fm.rotor_models.CentreRotor()
|
|
90
89
|
|
|
91
90
|
def _n2n(n2):
|
|
92
91
|
n2 = float(n2)
|
|
@@ -100,7 +99,7 @@ class ModelBook:
|
|
|
100
99
|
self.rotor_models.add_factory(
|
|
101
100
|
fm.rotor_models.GridRotor,
|
|
102
101
|
"grid<n2>",
|
|
103
|
-
kwargs=dict(
|
|
102
|
+
kwargs=dict(reduce=True),
|
|
104
103
|
var2arg={"n2": "n"},
|
|
105
104
|
n2=_n2n,
|
|
106
105
|
hints={"n2": "(Number of points in square grid)"},
|
|
@@ -108,7 +107,7 @@ class ModelBook:
|
|
|
108
107
|
self.rotor_models.add_factory(
|
|
109
108
|
fm.rotor_models.GridRotor,
|
|
110
109
|
"grid<n2>_raw",
|
|
111
|
-
kwargs=dict(
|
|
110
|
+
kwargs=dict(reduce=False),
|
|
112
111
|
var2arg={"n2": "n"},
|
|
113
112
|
n2=_n2n,
|
|
114
113
|
hints={"n2": "(Number of points in square grid)"},
|
|
@@ -116,14 +115,14 @@ class ModelBook:
|
|
|
116
115
|
self.rotor_models.add_factory(
|
|
117
116
|
fm.rotor_models.LevelRotor,
|
|
118
117
|
"level<n>",
|
|
119
|
-
kwargs=dict(
|
|
118
|
+
kwargs=dict(reduce=True),
|
|
120
119
|
n=lambda x: int(x),
|
|
121
120
|
hints={"n": "(Number of vertical levels)"},
|
|
122
121
|
)
|
|
123
122
|
self.rotor_models.add_factory(
|
|
124
123
|
fm.rotor_models.LevelRotor,
|
|
125
124
|
"level<n>_raw",
|
|
126
|
-
kwargs=dict(
|
|
125
|
+
kwargs=dict(reduce=False),
|
|
127
126
|
n=lambda x: int(x),
|
|
128
127
|
hints={"n": "(Number of vertical levels)"},
|
|
129
128
|
)
|
|
@@ -158,14 +157,14 @@ class ModelBook:
|
|
|
158
157
|
fm.turbine_models.kTI,
|
|
159
158
|
"kTI_<kTI>",
|
|
160
159
|
kTI=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
161
|
-
hints={"kTI": "(Value, e.g.
|
|
160
|
+
hints={"kTI": "(Value, e.g. 02 for 0.2)"},
|
|
162
161
|
)
|
|
163
162
|
self.turbine_models.add_factory(
|
|
164
163
|
fm.turbine_models.kTI,
|
|
165
164
|
"kTI_amb_<kTI>",
|
|
166
165
|
kwargs=dict(ti_var=FV.AMB_TI),
|
|
167
166
|
kTI=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
168
|
-
hints={"kTI": "(Value, e.g.
|
|
167
|
+
hints={"kTI": "(Value, e.g. 04 for 0.4)"},
|
|
169
168
|
)
|
|
170
169
|
self.turbine_models.add_factory(
|
|
171
170
|
fm.turbine_models.kTI,
|
|
@@ -173,7 +172,7 @@ class ModelBook:
|
|
|
173
172
|
kTI=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
174
173
|
kb=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
175
174
|
hints={
|
|
176
|
-
"kTI": "(Value, e.g.
|
|
175
|
+
"kTI": "(Value, e.g. 04 for 0.4)",
|
|
177
176
|
"kb": "(Value, e.g. 004 for 0.04)",
|
|
178
177
|
},
|
|
179
178
|
)
|
|
@@ -184,7 +183,7 @@ class ModelBook:
|
|
|
184
183
|
kTI=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
185
184
|
kb=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
186
185
|
hints={
|
|
187
|
-
"kTI": "(Value, e.g.
|
|
186
|
+
"kTI": "(Value, e.g. 04 for 0.4)",
|
|
188
187
|
"kb": "(Value, e.g. 004 for 0.04)",
|
|
189
188
|
},
|
|
190
189
|
)
|
|
@@ -254,12 +253,24 @@ class ModelBook:
|
|
|
254
253
|
)
|
|
255
254
|
|
|
256
255
|
self.wake_frames["timelines"] = fm.wake_frames.Timelines()
|
|
256
|
+
self.wake_frames["dyn_wakes"] = fm.wake_frames.DynamicWakes()
|
|
257
|
+
self.wake_frames["seq_dyn_wakes"] = fm.wake_frames.SeqDynamicWakes()
|
|
257
258
|
|
|
258
259
|
def _todt(x):
|
|
259
260
|
if x[-1] == "s":
|
|
260
261
|
return float(x[:-1]) / 60
|
|
261
262
|
elif x[-3:] == "min":
|
|
262
263
|
return float(x[:-3])
|
|
264
|
+
else:
|
|
265
|
+
raise NotImplementedError(f"Cannot translate '{x}' into minutes")
|
|
266
|
+
|
|
267
|
+
def _tokm(x):
|
|
268
|
+
if x[-2:] == "km":
|
|
269
|
+
return float(x[:-2])
|
|
270
|
+
elif x[-1] == "m":
|
|
271
|
+
return float(x[:-1]) / 1e3
|
|
272
|
+
else:
|
|
273
|
+
raise NotImplementedError(f"Cannot translate '{x}' into km")
|
|
263
274
|
|
|
264
275
|
self.wake_frames.add_factory(
|
|
265
276
|
fm.wake_frames.Timelines,
|
|
@@ -268,6 +279,13 @@ class ModelBook:
|
|
|
268
279
|
var2arg={"dt": "dt_min"},
|
|
269
280
|
hints={"dt": "(Time step, e.g '10s', '1min' etc.)"},
|
|
270
281
|
)
|
|
282
|
+
self.wake_frames.add_factory(
|
|
283
|
+
fm.wake_frames.DynamicWakes,
|
|
284
|
+
"dyn_wakes_<length>",
|
|
285
|
+
length=_tokm,
|
|
286
|
+
var2arg={"length": "max_length_km"},
|
|
287
|
+
hints={"length": "(Maximal wake length, e.g. '5km' or '5000m')"},
|
|
288
|
+
)
|
|
271
289
|
self.wake_frames.add_factory(
|
|
272
290
|
fm.wake_frames.SeqDynamicWakes,
|
|
273
291
|
"seq_dyn_wakes_<dt>",
|
|
@@ -411,14 +429,6 @@ class ModelBook:
|
|
|
411
429
|
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
412
430
|
)
|
|
413
431
|
|
|
414
|
-
self.wake_models.add_factory(
|
|
415
|
-
fm.wake_models.ti.IECTIWake,
|
|
416
|
-
"IECTI2005_<superposition>",
|
|
417
|
-
kwargs=dict(iec_type="2005"),
|
|
418
|
-
superposition=lambda s: f"ti_{s}",
|
|
419
|
-
hints={"superposition": "(Superposition, e.g. linear for ti_linear)"},
|
|
420
|
-
)
|
|
421
|
-
|
|
422
432
|
self.wake_models.add_factory(
|
|
423
433
|
fm.wake_models.ti.IECTIWake,
|
|
424
434
|
"IECTI2019_<superposition>",
|
|
@@ -450,12 +460,39 @@ class ModelBook:
|
|
|
450
460
|
)
|
|
451
461
|
|
|
452
462
|
self.wake_models[f"RHB"] = fm.wake_models.induction.RankineHalfBody()
|
|
463
|
+
|
|
464
|
+
self.wake_models[f"VortexSheet"] = fm.wake_models.induction.VortexSheet()
|
|
465
|
+
self.wake_models.add_factory(
|
|
466
|
+
fm.wake_models.induction.VortexSheet,
|
|
467
|
+
"VortexSheet_<superposition>",
|
|
468
|
+
superposition=lambda s: f"ws_{s}",
|
|
469
|
+
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
470
|
+
)
|
|
471
|
+
|
|
453
472
|
self.wake_models[f"Rathmann"] = fm.wake_models.induction.Rathmann()
|
|
473
|
+
self.wake_models.add_factory(
|
|
474
|
+
fm.wake_models.induction.Rathmann,
|
|
475
|
+
"Rathmann_<superposition>",
|
|
476
|
+
superposition=lambda s: f"ws_{s}",
|
|
477
|
+
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
478
|
+
)
|
|
479
|
+
|
|
454
480
|
self.wake_models[f"SelfSimilar"] = fm.wake_models.induction.SelfSimilar()
|
|
455
481
|
self.wake_models[f"SelfSimilar2020"] = (
|
|
456
482
|
fm.wake_models.induction.SelfSimilar2020()
|
|
457
483
|
)
|
|
458
|
-
self.wake_models
|
|
484
|
+
self.wake_models.add_factory(
|
|
485
|
+
fm.wake_models.induction.SelfSimilar,
|
|
486
|
+
"SelfSimilar_<superposition>",
|
|
487
|
+
superposition=lambda s: f"ws_{s}",
|
|
488
|
+
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
489
|
+
)
|
|
490
|
+
self.wake_models.add_factory(
|
|
491
|
+
fm.wake_models.induction.SelfSimilar2020,
|
|
492
|
+
"SelfSimilar2020_<superposition>",
|
|
493
|
+
superposition=lambda s: f"ws_{s}",
|
|
494
|
+
hints={"superposition": "(Superposition, e.g. linear for ws_linear)"},
|
|
495
|
+
)
|
|
459
496
|
|
|
460
497
|
self.ground_models = FDict(name="ground_models")
|
|
461
498
|
self.ground_models["no_ground"] = fm.ground_models.NoGround()
|
|
@@ -466,6 +503,7 @@ class ModelBook:
|
|
|
466
503
|
var2arg={"height": "heights"},
|
|
467
504
|
height=lambda h: [0.0, float(h)],
|
|
468
505
|
hints={"height": "(Boundary layer wake reflection height)"},
|
|
506
|
+
example_vars={"height": 500},
|
|
469
507
|
)
|
|
470
508
|
|
|
471
509
|
self.sources = FDict(
|
|
@@ -504,7 +542,7 @@ class ModelBook:
|
|
|
504
542
|
m.name = k
|
|
505
543
|
|
|
506
544
|
def __getitem__(self, key):
|
|
507
|
-
return self.sources.
|
|
545
|
+
return self.sources.get_item(key)
|
|
508
546
|
|
|
509
547
|
def print_toc(self, subset=None, search=None):
|
|
510
548
|
"""
|