foxes 1.1.0.2__py3-none-any.whl → 1.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 +3 -2
- examples/dyn_wakes/run.py +2 -2
- examples/timelines/run.py +1 -1
- foxes/__init__.py +13 -2
- foxes/algorithms/downwind/downwind.py +6 -1
- foxes/algorithms/downwind/models/init_farm_data.py +5 -2
- foxes/algorithms/downwind/models/point_wakes_calc.py +0 -1
- foxes/algorithms/iterative/iterative.py +1 -1
- foxes/algorithms/sequential/sequential.py +4 -3
- foxes/config/__init__.py +1 -0
- foxes/config/config.py +134 -0
- foxes/constants.py +15 -6
- foxes/core/algorithm.py +22 -10
- foxes/core/data.py +2 -1
- foxes/core/engine.py +40 -34
- foxes/core/farm_controller.py +4 -3
- foxes/core/farm_data_model.py +6 -2
- foxes/core/model.py +2 -1
- foxes/core/point_data_model.py +4 -2
- foxes/core/rotor_model.py +8 -4
- foxes/core/turbine_type.py +1 -1
- foxes/core/wake_frame.py +7 -5
- foxes/core/wake_model.py +6 -1
- foxes/data/__init__.py +1 -1
- foxes/data/static_data.py +0 -7
- foxes/engines/dask.py +4 -3
- foxes/engines/single.py +1 -1
- foxes/input/__init__.py +1 -1
- foxes/input/farm_layout/from_csv.py +3 -1
- foxes/input/farm_layout/from_file.py +10 -10
- foxes/input/farm_layout/from_json.py +4 -3
- foxes/input/farm_layout/grid.py +3 -3
- foxes/input/states/create/random_abl_states.py +5 -3
- foxes/input/states/field_data_nc.py +22 -14
- foxes/input/states/multi_height.py +26 -15
- foxes/input/states/one_point_flow.py +6 -5
- foxes/input/states/scan_ws.py +4 -1
- foxes/input/states/single.py +15 -6
- foxes/input/states/slice_data_nc.py +18 -12
- foxes/input/states/states_table.py +17 -10
- foxes/input/yaml/__init__.py +3 -0
- foxes/input/yaml/dict.py +210 -0
- foxes/input/yaml/windio/__init__.py +4 -0
- foxes/input/{windio → yaml/windio}/get_states.py +7 -7
- foxes/input/{windio → yaml/windio}/read_attributes.py +61 -40
- foxes/input/{windio → yaml/windio}/read_farm.py +34 -43
- foxes/input/{windio → yaml/windio}/read_fields.py +11 -10
- foxes/input/yaml/windio/read_outputs.py +147 -0
- foxes/input/yaml/windio/windio.py +269 -0
- foxes/input/yaml/yaml.py +103 -0
- foxes/models/partial_wakes/axiwake.py +7 -6
- foxes/models/partial_wakes/centre.py +3 -2
- foxes/models/partial_wakes/segregated.py +5 -2
- foxes/models/point_models/set_uniform_data.py +5 -3
- foxes/models/rotor_models/centre.py +2 -2
- foxes/models/rotor_models/grid.py +5 -5
- foxes/models/rotor_models/levels.py +6 -6
- foxes/models/turbine_models/kTI_model.py +3 -1
- foxes/models/turbine_models/lookup_table.py +7 -4
- foxes/models/turbine_models/power_mask.py +14 -8
- foxes/models/turbine_models/sector_management.py +4 -2
- foxes/models/turbine_models/set_farm_vars.py +53 -23
- foxes/models/turbine_models/table_factors.py +8 -7
- foxes/models/turbine_models/yaw2yawm.py +0 -1
- foxes/models/turbine_models/yawm2yaw.py +0 -1
- foxes/models/turbine_types/CpCt_file.py +6 -3
- foxes/models/turbine_types/CpCt_from_two.py +6 -3
- foxes/models/turbine_types/PCt_file.py +7 -6
- foxes/models/turbine_types/PCt_from_two.py +11 -2
- foxes/models/turbine_types/TBL_file.py +3 -4
- foxes/models/turbine_types/wsrho2PCt_from_two.py +19 -11
- foxes/models/turbine_types/wsti2PCt_from_two.py +19 -11
- foxes/models/vertical_profiles/abl_log_neutral_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_stable_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_unstable_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_ws.py +1 -1
- foxes/models/wake_frames/dynamic_wakes.py +17 -9
- foxes/models/wake_frames/farm_order.py +4 -3
- foxes/models/wake_frames/rotor_wd.py +3 -1
- foxes/models/wake_frames/seq_dynamic_wakes.py +14 -7
- foxes/models/wake_frames/streamlines.py +9 -6
- foxes/models/wake_frames/timelines.py +21 -14
- foxes/models/wake_frames/yawed_wakes.py +3 -1
- foxes/models/wake_models/induction/vortex_sheet.py +0 -1
- foxes/models/wake_models/ti/crespo_hernandez.py +2 -1
- foxes/models/wake_models/wind/bastankhah14.py +3 -2
- foxes/models/wake_models/wind/bastankhah16.py +2 -1
- foxes/models/wake_models/wind/turbopark.py +9 -7
- foxes/models/wake_superpositions/ws_product.py +0 -1
- foxes/output/calc_points.py +7 -4
- foxes/output/farm_layout.py +30 -18
- foxes/output/farm_results_eval.py +4 -3
- foxes/output/grids.py +8 -7
- foxes/output/output.py +7 -2
- foxes/output/results_writer.py +10 -11
- foxes/output/rose_plot.py +38 -20
- foxes/output/rotor_point_plots.py +7 -3
- foxes/output/slice_data.py +1 -1
- foxes/output/state_turbine_map.py +5 -1
- foxes/output/state_turbine_table.py +7 -3
- foxes/output/turbine_type_curves.py +7 -2
- foxes/utils/dict.py +107 -3
- foxes/utils/geopandas_utils.py +3 -2
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/METADATA +20 -21
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/RECORD +122 -122
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/WHEEL +1 -1
- foxes-1.2.dist-info/entry_points.txt +3 -0
- tests/0_consistency/iterative/test_iterative.py +65 -67
- tests/0_consistency/partial_wakes/test_partial_wakes.py +58 -61
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +56 -53
- tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +41 -41
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +34 -34
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +50 -50
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +51 -52
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +73 -74
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +73 -74
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +51 -49
- tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +101 -103
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +61 -62
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +51 -52
- examples/windio/run.py +0 -29
- foxes/data/states/windio_timeseries_5000.nc +0 -0
- foxes/data/windio/DTU_10MW_turbine.yaml +0 -10
- foxes/data/windio/__init__.py +0 -0
- foxes/data/windio/windio_5turbines_timeseries.yaml +0 -79
- foxes/input/windio/__init__.py +0 -11
- foxes/input/windio/read_outputs.py +0 -172
- foxes/input/windio/runner.py +0 -183
- foxes/input/windio/windio.py +0 -193
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/LICENSE +0 -0
- {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/top_level.txt +0 -0
foxes/input/states/single.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import States, VerticalProfile
|
|
4
|
+
from foxes.config import config
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
6
7
|
|
|
@@ -29,7 +30,15 @@ class SingleStateStates(States):
|
|
|
29
30
|
|
|
30
31
|
"""
|
|
31
32
|
|
|
32
|
-
def __init__(
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
ws=None,
|
|
36
|
+
wd=None,
|
|
37
|
+
ti=None,
|
|
38
|
+
rho=None,
|
|
39
|
+
profiles={},
|
|
40
|
+
**profdata,
|
|
41
|
+
):
|
|
33
42
|
"""
|
|
34
43
|
Constructor.
|
|
35
44
|
|
|
@@ -163,7 +172,7 @@ class SingleStateStates(States):
|
|
|
163
172
|
The weights, shape: (n_states, n_turbines)
|
|
164
173
|
|
|
165
174
|
"""
|
|
166
|
-
return np.ones((1, algo.n_turbines), dtype=
|
|
175
|
+
return np.ones((1, algo.n_turbines), dtype=config.dtype_double)
|
|
167
176
|
|
|
168
177
|
def calculate(self, algo, mdata, fdata, tdata):
|
|
169
178
|
"""
|
|
@@ -195,25 +204,25 @@ class SingleStateStates(States):
|
|
|
195
204
|
tdata[FV.WS] = np.full(
|
|
196
205
|
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
197
206
|
self.ws,
|
|
198
|
-
dtype=
|
|
207
|
+
dtype=config.dtype_double,
|
|
199
208
|
)
|
|
200
209
|
if self.wd is not None:
|
|
201
210
|
tdata[FV.WD] = np.full(
|
|
202
211
|
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
203
212
|
self.wd,
|
|
204
|
-
dtype=
|
|
213
|
+
dtype=config.dtype_double,
|
|
205
214
|
)
|
|
206
215
|
if self.ti is not None:
|
|
207
216
|
tdata[FV.TI] = np.full(
|
|
208
217
|
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
209
218
|
self.ti,
|
|
210
|
-
dtype=
|
|
219
|
+
dtype=config.dtype_double,
|
|
211
220
|
)
|
|
212
221
|
if self.rho is not None:
|
|
213
222
|
tdata[FV.RHO] = np.full(
|
|
214
223
|
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
215
224
|
self.rho,
|
|
216
|
-
dtype=
|
|
225
|
+
dtype=config.dtype_double,
|
|
217
226
|
)
|
|
218
227
|
|
|
219
228
|
if len(self._profiles):
|
|
@@ -2,11 +2,11 @@ import numpy as np
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
import xarray as xr
|
|
4
4
|
from scipy.interpolate import interpn
|
|
5
|
-
from pathlib import Path
|
|
6
5
|
|
|
7
6
|
from foxes.core import States
|
|
8
7
|
from foxes.utils import wd2uv, uv2wd, import_module
|
|
9
8
|
from foxes.data import STATES, StaticData
|
|
9
|
+
from foxes.config import config, get_path
|
|
10
10
|
import foxes.variables as FV
|
|
11
11
|
import foxes.constants as FC
|
|
12
12
|
|
|
@@ -145,9 +145,11 @@ class SliceDataNC(States):
|
|
|
145
145
|
if "*" in str(self.data_source):
|
|
146
146
|
pass
|
|
147
147
|
else:
|
|
148
|
-
self.__data_source =
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
self.__data_source = get_path(self.data_source)
|
|
149
|
+
if not self.data_source.is_file():
|
|
150
|
+
self.__data_source = StaticData().get_file_path(
|
|
151
|
+
STATES, self.data_source.name, check_raw=False
|
|
152
|
+
)
|
|
151
153
|
if verbosity:
|
|
152
154
|
if pre_load:
|
|
153
155
|
print(
|
|
@@ -159,7 +161,8 @@ class SliceDataNC(States):
|
|
|
159
161
|
)
|
|
160
162
|
|
|
161
163
|
def _read_ds():
|
|
162
|
-
|
|
164
|
+
self._data_source = get_path(self.data_source)
|
|
165
|
+
if self.data_source.is_file():
|
|
163
166
|
return xr.open_dataset(self.data_source)
|
|
164
167
|
else:
|
|
165
168
|
# try to read multiple files, needs dask:
|
|
@@ -177,8 +180,7 @@ class SliceDataNC(States):
|
|
|
177
180
|
import_module("dask", hint="pip install dask")
|
|
178
181
|
raise e
|
|
179
182
|
|
|
180
|
-
|
|
181
|
-
self.__data_source = ds
|
|
183
|
+
self.__data_source = _read_ds()
|
|
182
184
|
|
|
183
185
|
if sel is not None:
|
|
184
186
|
self.__data_source = self.data_source.sel(self.sel)
|
|
@@ -264,7 +266,9 @@ class SliceDataNC(States):
|
|
|
264
266
|
f"States '{self.name}': Wrong coordinate order for variable '{ncv}': Found {ds[ncv].dims}, expecting {cor_sxy}, {cor_syx}, or {cor_s}"
|
|
265
267
|
)
|
|
266
268
|
|
|
267
|
-
data = np.zeros(
|
|
269
|
+
data = np.zeros(
|
|
270
|
+
(n_sts, n_y, n_x, len(self.var2ncvar)), dtype=config.dtype_double
|
|
271
|
+
)
|
|
268
272
|
for v in vars_syx:
|
|
269
273
|
ncv = self.var2ncvar[v]
|
|
270
274
|
if ds[ncv].dims == cor_syx:
|
|
@@ -276,7 +280,7 @@ class SliceDataNC(States):
|
|
|
276
280
|
data[..., self._dkys[v]] = ds[ncv].to_numpy()[:, None, None]
|
|
277
281
|
if FV.WD in self.fixed_vars:
|
|
278
282
|
data[..., self._dkys[FV.WD]] = np.full(
|
|
279
|
-
(n_sts, n_y, n_x), self.fixed_vars[FV.WD], dtype=
|
|
283
|
+
(n_sts, n_y, n_x), self.fixed_vars[FV.WD], dtype=config.dtype_double
|
|
280
284
|
)
|
|
281
285
|
|
|
282
286
|
if verbosity > 1:
|
|
@@ -351,7 +355,7 @@ class SliceDataNC(States):
|
|
|
351
355
|
|
|
352
356
|
if self.__weights is None:
|
|
353
357
|
self.__weights = np.full(
|
|
354
|
-
(self._N, algo.n_turbines), 1.0 / self._N, dtype=
|
|
358
|
+
(self._N, algo.n_turbines), 1.0 / self._N, dtype=config.dtype_double
|
|
355
359
|
)
|
|
356
360
|
|
|
357
361
|
idata = super().load_data(algo, verbosity)
|
|
@@ -588,7 +592,9 @@ class SliceDataNC(States):
|
|
|
588
592
|
|
|
589
593
|
# prepare points:
|
|
590
594
|
sts = np.arange(n_states)
|
|
591
|
-
pts = np.append(
|
|
595
|
+
pts = np.append(
|
|
596
|
+
points, np.zeros((n_states, n_pts, 1), dtype=config.dtype_double), axis=2
|
|
597
|
+
)
|
|
592
598
|
pts[:, :, 3] = sts[:, None]
|
|
593
599
|
pts = pts.reshape(n_states * n_pts, 3)
|
|
594
600
|
pts = np.flip(pts, axis=1)
|
|
@@ -675,7 +681,7 @@ class SliceDataNC(States):
|
|
|
675
681
|
out[v] = data[..., self._dkys[v]]
|
|
676
682
|
else:
|
|
677
683
|
out[v] = np.full(
|
|
678
|
-
(n_states, n_pts), self.fixed_vars[v], dtype=
|
|
684
|
+
(n_states, n_pts), self.fixed_vars[v], dtype=config.dtype_double
|
|
679
685
|
)
|
|
680
686
|
|
|
681
687
|
return {v: d.reshape(n_states, n_targets, n_tpoints) for v, d in out.items()}
|
|
@@ -6,6 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
from foxes.core import States, VerticalProfile
|
|
7
7
|
from foxes.utils import PandasFileHelper, read_tab_file
|
|
8
8
|
from foxes.data import STATES
|
|
9
|
+
from foxes.config import config, get_path
|
|
9
10
|
import foxes.variables as FV
|
|
10
11
|
import foxes.constants as FC
|
|
11
12
|
|
|
@@ -214,13 +215,14 @@ class StatesTable(States):
|
|
|
214
215
|
data = self.data_source
|
|
215
216
|
isorg = True
|
|
216
217
|
else:
|
|
217
|
-
|
|
218
|
+
self._data_source = get_path(self.data_source)
|
|
219
|
+
if not self.data_source.is_file():
|
|
218
220
|
if verbosity:
|
|
219
221
|
print(
|
|
220
222
|
f"States '{self.name}': Reading static data '{self.data_source}' from context '{STATES}'"
|
|
221
223
|
)
|
|
222
224
|
self._data_source = algo.dbook.get_file_path(
|
|
223
|
-
STATES, self.data_source, check_raw=False
|
|
225
|
+
STATES, self.data_source.name, check_raw=False
|
|
224
226
|
)
|
|
225
227
|
if verbosity:
|
|
226
228
|
print(f"Path: {self.data_source}")
|
|
@@ -238,7 +240,7 @@ class StatesTable(States):
|
|
|
238
240
|
self.__inds = data.index.to_numpy()
|
|
239
241
|
|
|
240
242
|
col_w = self.var2col.get(FV.WEIGHT, FV.WEIGHT)
|
|
241
|
-
self.__weights = np.zeros((self._N, algo.n_turbines), dtype=
|
|
243
|
+
self.__weights = np.zeros((self._N, algo.n_turbines), dtype=config.dtype_double)
|
|
242
244
|
if col_w in data:
|
|
243
245
|
self.__weights[:] = data[col_w].to_numpy()[:, None]
|
|
244
246
|
elif FV.WEIGHT in self.var2col:
|
|
@@ -436,14 +438,17 @@ class StatesTable(States):
|
|
|
436
438
|
tdata[v][:] = mdata[self.DATA][:, i, None, None]
|
|
437
439
|
else:
|
|
438
440
|
tdata[v] = np.zeros(
|
|
439
|
-
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
441
|
+
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
442
|
+
dtype=config.dtype_double,
|
|
440
443
|
)
|
|
441
444
|
tdata[v][:] = mdata[self.DATA][:, i, None, None]
|
|
442
445
|
tdata.dims[v] = (FC.STATE, FC.TARGET, FC.TPOINT)
|
|
443
446
|
|
|
444
447
|
for v, f in self.fixed_vars.items():
|
|
445
448
|
tdata[v] = np.full(
|
|
446
|
-
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
449
|
+
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
450
|
+
f,
|
|
451
|
+
dtype=config.dtype_double,
|
|
447
452
|
)
|
|
448
453
|
|
|
449
454
|
z = tdata[FC.TARGETS][..., 2]
|
|
@@ -545,13 +550,14 @@ class TabStates(StatesTable):
|
|
|
545
550
|
"""
|
|
546
551
|
if self.data_source is None:
|
|
547
552
|
if self.__tab_data is None:
|
|
548
|
-
|
|
553
|
+
self.__tab_source = get_path(self.__tab_source)
|
|
554
|
+
if not self.__tab_source.is_file():
|
|
549
555
|
if verbosity:
|
|
550
556
|
print(
|
|
551
557
|
f"States '{self.name}': Reading static data '{self.__tab_source}' from context '{STATES}'"
|
|
552
558
|
)
|
|
553
559
|
self.__tab_source = algo.dbook.get_file_path(
|
|
554
|
-
STATES, self.__tab_source, check_raw=False
|
|
560
|
+
STATES, self.__tab_source.name, check_raw=False
|
|
555
561
|
)
|
|
556
562
|
if verbosity:
|
|
557
563
|
print(f"Path: {self.__tab_source}")
|
|
@@ -568,14 +574,15 @@ class TabStates(StatesTable):
|
|
|
568
574
|
|
|
569
575
|
wd0 = self.__tab_data["wd"].to_numpy()
|
|
570
576
|
ws0 = a * np.append(
|
|
571
|
-
np.array([0], dtype=
|
|
577
|
+
np.array([0], dtype=config.dtype_double),
|
|
578
|
+
self.__tab_data["ws"].to_numpy(),
|
|
572
579
|
)
|
|
573
580
|
ws0 = 0.5 * (ws0[:-1] + ws0[1:])
|
|
574
581
|
|
|
575
582
|
n_ws = self.__tab_data.sizes["ws"]
|
|
576
583
|
n_wd = self.__tab_data.sizes["wd"]
|
|
577
|
-
ws = np.zeros((n_ws, n_wd), dtype=
|
|
578
|
-
wd = np.zeros((n_ws, n_wd), dtype=
|
|
584
|
+
ws = np.zeros((n_ws, n_wd), dtype=config.dtype_double)
|
|
585
|
+
wd = np.zeros((n_ws, n_wd), dtype=config.dtype_double)
|
|
579
586
|
ws[:] = ws0[:, None]
|
|
580
587
|
wd[:] = wd0[None, :]
|
|
581
588
|
|
foxes/input/yaml/dict.py
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from inspect import signature
|
|
4
|
+
|
|
5
|
+
import foxes.input.farm_layout as farm_layout
|
|
6
|
+
from foxes.core import States, Engine, WindFarm, Algorithm
|
|
7
|
+
from foxes.models import ModelBook
|
|
8
|
+
from foxes import output
|
|
9
|
+
from foxes.utils import Dict
|
|
10
|
+
from foxes.config import config
|
|
11
|
+
import foxes.constants as FC
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def run_dict(
|
|
15
|
+
idict,
|
|
16
|
+
farm=None,
|
|
17
|
+
states=None,
|
|
18
|
+
mbook=None,
|
|
19
|
+
algo=None,
|
|
20
|
+
engine_pars=None,
|
|
21
|
+
iterative=None,
|
|
22
|
+
verbosity=None,
|
|
23
|
+
work_dir=".",
|
|
24
|
+
out_dir=".",
|
|
25
|
+
**algo_pars,
|
|
26
|
+
):
|
|
27
|
+
"""
|
|
28
|
+
Runs foxes from dictionary input
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
idict: foxes.utils.Dict
|
|
33
|
+
The input parameter dictionary
|
|
34
|
+
farm: foxes.core.WindFarm, optional
|
|
35
|
+
The wind farm, overrules settings from idict
|
|
36
|
+
states: foxes.core.States, optional
|
|
37
|
+
The ambient states, overrules settings from idict
|
|
38
|
+
mbook: foxes.models.ModelBook, optional
|
|
39
|
+
The model book, overrules settings from idict
|
|
40
|
+
algo: foxes.core.Algorithm, optional
|
|
41
|
+
The algorithm, overrules settings from idict
|
|
42
|
+
engine_pars: dict, optional
|
|
43
|
+
Parameters for engine creation, overrules
|
|
44
|
+
settings from idict
|
|
45
|
+
iterative: bool, optional
|
|
46
|
+
Force iterative calculations, overrules
|
|
47
|
+
settings from idict
|
|
48
|
+
verbosity: int, optional
|
|
49
|
+
Force a verbosity level, 0 = silent, overrules
|
|
50
|
+
settings from idict
|
|
51
|
+
work_dir: str or pathlib.Path
|
|
52
|
+
Path to the working directory
|
|
53
|
+
out_dir: str or pathlib.Path
|
|
54
|
+
The default output directory
|
|
55
|
+
algo_pars: dict, optional
|
|
56
|
+
Additional parameters for the algorithm, overrules
|
|
57
|
+
settings from idict
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
farm_results: xarray.Dataset, optional
|
|
62
|
+
The farm results
|
|
63
|
+
point_results: xarray.Dataset, optional
|
|
64
|
+
The point results
|
|
65
|
+
output_i: object
|
|
66
|
+
For each output either None or the output result
|
|
67
|
+
|
|
68
|
+
:group: input.yaml
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
def _print(*args, level=1, **kwargs):
|
|
73
|
+
if verbosity is None or verbosity >= level:
|
|
74
|
+
print(*args, **kwargs)
|
|
75
|
+
|
|
76
|
+
# set working directory:
|
|
77
|
+
config[FC.WORK_DIR] = work_dir
|
|
78
|
+
config[FC.OUT_DIR] = out_dir
|
|
79
|
+
_print("Working directory:", config.work_dir)
|
|
80
|
+
_print("Output directory :", config.out_dir)
|
|
81
|
+
|
|
82
|
+
# create states:
|
|
83
|
+
if states is None:
|
|
84
|
+
_print("Creating states")
|
|
85
|
+
states = States.new(**idict["states"])
|
|
86
|
+
|
|
87
|
+
# create model book:
|
|
88
|
+
if mbook is None:
|
|
89
|
+
mbook = ModelBook()
|
|
90
|
+
if "model_book" in idict:
|
|
91
|
+
_print("Creating model book")
|
|
92
|
+
mdict = idict.get_item("model_book")
|
|
93
|
+
for s, mlst in mdict.items():
|
|
94
|
+
t = mbook.sources.get_item(s)
|
|
95
|
+
c = mbook.base_classes.get_item(s)
|
|
96
|
+
ms = [Dict(m, name=f"{mdict.name}.s{i}") for i, m in enumerate(mlst)]
|
|
97
|
+
for m in ms:
|
|
98
|
+
mname = m.pop_item("name")
|
|
99
|
+
_print(f" Adding {s}.{mname}")
|
|
100
|
+
t[mname] = c.new(**m)
|
|
101
|
+
|
|
102
|
+
# create farm:
|
|
103
|
+
if farm is None:
|
|
104
|
+
_print("Creating wind farm")
|
|
105
|
+
fdict = idict.get_item("wind_farm")
|
|
106
|
+
lyts = [
|
|
107
|
+
Dict(l, name=f"{fdict.name}.layout{i}")
|
|
108
|
+
for i, l in enumerate(fdict.pop_item("layouts"))
|
|
109
|
+
]
|
|
110
|
+
farm = WindFarm(**fdict)
|
|
111
|
+
for lyt in lyts:
|
|
112
|
+
add_fun = getattr(farm_layout, lyt.pop_item("function"))
|
|
113
|
+
if verbosity is not None:
|
|
114
|
+
lyt["verbosity"] = verbosity - 1
|
|
115
|
+
add_fun(farm, **lyt)
|
|
116
|
+
|
|
117
|
+
# create engine:
|
|
118
|
+
engine = None
|
|
119
|
+
if engine_pars is not None:
|
|
120
|
+
engine = Engine.new(**engine_pars)
|
|
121
|
+
_print(f"Initializing engine: {engine}")
|
|
122
|
+
engine.initialize()
|
|
123
|
+
elif "engine" in idict:
|
|
124
|
+
if verbosity is not None:
|
|
125
|
+
idict["verbosity"] = verbosity - 1
|
|
126
|
+
engine = Engine.new(**idict["engine"])
|
|
127
|
+
engine.initialize()
|
|
128
|
+
_print(f"Initializing engine: {engine}")
|
|
129
|
+
|
|
130
|
+
# create algorithm:
|
|
131
|
+
if algo is None:
|
|
132
|
+
_print("Creating algorithm")
|
|
133
|
+
adict = idict.get_item("algorithm")
|
|
134
|
+
if iterative is not None and iterative:
|
|
135
|
+
adict["algo_type"] = "Iterative"
|
|
136
|
+
adict.update(dict(farm=farm, states=states, mbook=mbook))
|
|
137
|
+
if verbosity is not None:
|
|
138
|
+
adict["verbosity"] = verbosity - 1
|
|
139
|
+
if algo_pars is not None:
|
|
140
|
+
adict.update(algo_pars)
|
|
141
|
+
algo = Algorithm.new(**adict)
|
|
142
|
+
|
|
143
|
+
# run farm calculation:
|
|
144
|
+
rdict = idict.get_item("calc_farm")
|
|
145
|
+
if rdict.pop_item("run"):
|
|
146
|
+
_print("Running calc_farm")
|
|
147
|
+
farm_results = algo.calc_farm(**rdict)
|
|
148
|
+
else:
|
|
149
|
+
farm_results = None
|
|
150
|
+
out = (farm_results,)
|
|
151
|
+
|
|
152
|
+
# run points calculation:
|
|
153
|
+
if "calc_points" in idict:
|
|
154
|
+
rdict = idict.get_item("calc_points")
|
|
155
|
+
if rdict.pop_item("run"):
|
|
156
|
+
_print("Running calc_points")
|
|
157
|
+
points = rdict.pop_item("points")
|
|
158
|
+
if isinstance(points, str):
|
|
159
|
+
_print("Reading file", points)
|
|
160
|
+
points = pd.read_csv(points).to_numpy()
|
|
161
|
+
point_results = algo.calc_points(farm_results, points=points, **rdict)
|
|
162
|
+
else:
|
|
163
|
+
point_results = None
|
|
164
|
+
out += (point_results,)
|
|
165
|
+
|
|
166
|
+
# run outputs:
|
|
167
|
+
if "outputs" in idict:
|
|
168
|
+
_print("Running outputs")
|
|
169
|
+
odict = idict["outputs"]
|
|
170
|
+
for ocls, d in odict.items():
|
|
171
|
+
_print(f" Output {ocls}")
|
|
172
|
+
flist = [
|
|
173
|
+
Dict(f, name=f"{d.name}.function{i}")
|
|
174
|
+
for i, f in enumerate(d.pop_item("functions"))
|
|
175
|
+
]
|
|
176
|
+
try:
|
|
177
|
+
cls = getattr(output, ocls)
|
|
178
|
+
except AttributeError as e:
|
|
179
|
+
print(f"\nClass '{ocls}' not found in outputs. Found:")
|
|
180
|
+
prs = list(signature(cls.__init__).parameters.keys())
|
|
181
|
+
if "algo" in prs:
|
|
182
|
+
d["algo"] = algo
|
|
183
|
+
if "farm_results" in prs:
|
|
184
|
+
if farm_results is None:
|
|
185
|
+
print(f"No farm results; skipping output {ocls}")
|
|
186
|
+
for fdict in flist:
|
|
187
|
+
out += (None,)
|
|
188
|
+
continue
|
|
189
|
+
d["farm_results"] = farm_results
|
|
190
|
+
o = cls(**d)
|
|
191
|
+
for fdict in flist:
|
|
192
|
+
fname = fdict.pop_item("name")
|
|
193
|
+
_print(f" - {fname}")
|
|
194
|
+
plt_show = fdict.pop("plt_show", False)
|
|
195
|
+
f = getattr(o, fname)
|
|
196
|
+
prs = list(signature(f).parameters.keys())
|
|
197
|
+
if "algo" in prs:
|
|
198
|
+
fdict["algo"] = algo
|
|
199
|
+
res = f(**fdict)
|
|
200
|
+
out += (res,) if not isinstance(res, tuple) else res
|
|
201
|
+
if plt_show:
|
|
202
|
+
plt.show()
|
|
203
|
+
plt.close()
|
|
204
|
+
|
|
205
|
+
# shutdown engine, if created above:
|
|
206
|
+
if engine is not None:
|
|
207
|
+
_print(f"Finalizing engine: {engine}")
|
|
208
|
+
engine.finalize()
|
|
209
|
+
|
|
210
|
+
return out
|
|
@@ -4,13 +4,13 @@ from xarray import Dataset
|
|
|
4
4
|
from numbers import Number
|
|
5
5
|
|
|
6
6
|
from foxes.core import States
|
|
7
|
-
import foxes.constants as FC
|
|
8
7
|
import foxes.variables as FV
|
|
8
|
+
import foxes.constants as FC
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def _get_profiles(coords, fields, dims, ovars, fixval, verbosity):
|
|
12
12
|
"""Read ABL profiles information
|
|
13
|
-
:group: input.windio
|
|
13
|
+
:group: input.yaml.windio
|
|
14
14
|
"""
|
|
15
15
|
profiles = {}
|
|
16
16
|
if FV.Z0 in fields:
|
|
@@ -42,7 +42,7 @@ def _get_SingleStateStates(
|
|
|
42
42
|
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
43
43
|
):
|
|
44
44
|
"""Try to generate single state parameters
|
|
45
|
-
:group: input.windio
|
|
45
|
+
:group: input.yaml.windio
|
|
46
46
|
"""
|
|
47
47
|
for c in coords:
|
|
48
48
|
if not isinstance(c, Number):
|
|
@@ -81,7 +81,7 @@ def _get_Timeseries(
|
|
|
81
81
|
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
82
82
|
):
|
|
83
83
|
"""Try to generate time series parameters
|
|
84
|
-
:group: input.windio
|
|
84
|
+
:group: input.yaml.windio
|
|
85
85
|
"""
|
|
86
86
|
if len(coords) == 1 and FC.TIME in coords:
|
|
87
87
|
if verbosity > 2:
|
|
@@ -117,7 +117,7 @@ def _get_MultiHeightNCTimeseries(
|
|
|
117
117
|
coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
|
|
118
118
|
):
|
|
119
119
|
"""Try to generate time series parameters
|
|
120
|
-
:group: input.windio
|
|
120
|
+
:group: input.yaml.windio
|
|
121
121
|
"""
|
|
122
122
|
if len(coords) == 2 and FC.TIME in coords and FV.H in coords:
|
|
123
123
|
if verbosity > 2:
|
|
@@ -176,11 +176,11 @@ def get_states(coords, fields, dims, verbosity=1):
|
|
|
176
176
|
states: foxes.core.States
|
|
177
177
|
The states object
|
|
178
178
|
|
|
179
|
-
:group: input.windio
|
|
179
|
+
:group: input.yaml.windio
|
|
180
180
|
|
|
181
181
|
"""
|
|
182
182
|
if verbosity > 2:
|
|
183
|
-
print("
|
|
183
|
+
print(" Creating states")
|
|
184
184
|
|
|
185
185
|
ovars = [FV.WS, FV.WD, FV.TI, FV.RHO]
|
|
186
186
|
fixval = {FV.TI: 0.05, FV.RHO: 1.225}
|