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.

Files changed (131) hide show
  1. docs/source/conf.py +3 -2
  2. examples/dyn_wakes/run.py +2 -2
  3. examples/timelines/run.py +1 -1
  4. foxes/__init__.py +13 -2
  5. foxes/algorithms/downwind/downwind.py +6 -1
  6. foxes/algorithms/downwind/models/init_farm_data.py +5 -2
  7. foxes/algorithms/downwind/models/point_wakes_calc.py +0 -1
  8. foxes/algorithms/iterative/iterative.py +1 -1
  9. foxes/algorithms/sequential/sequential.py +4 -3
  10. foxes/config/__init__.py +1 -0
  11. foxes/config/config.py +134 -0
  12. foxes/constants.py +15 -6
  13. foxes/core/algorithm.py +22 -10
  14. foxes/core/data.py +2 -1
  15. foxes/core/engine.py +40 -34
  16. foxes/core/farm_controller.py +4 -3
  17. foxes/core/farm_data_model.py +6 -2
  18. foxes/core/model.py +2 -1
  19. foxes/core/point_data_model.py +4 -2
  20. foxes/core/rotor_model.py +8 -4
  21. foxes/core/turbine_type.py +1 -1
  22. foxes/core/wake_frame.py +7 -5
  23. foxes/core/wake_model.py +6 -1
  24. foxes/data/__init__.py +1 -1
  25. foxes/data/static_data.py +0 -7
  26. foxes/engines/dask.py +4 -3
  27. foxes/engines/single.py +1 -1
  28. foxes/input/__init__.py +1 -1
  29. foxes/input/farm_layout/from_csv.py +3 -1
  30. foxes/input/farm_layout/from_file.py +10 -10
  31. foxes/input/farm_layout/from_json.py +4 -3
  32. foxes/input/farm_layout/grid.py +3 -3
  33. foxes/input/states/create/random_abl_states.py +5 -3
  34. foxes/input/states/field_data_nc.py +22 -14
  35. foxes/input/states/multi_height.py +26 -15
  36. foxes/input/states/one_point_flow.py +6 -5
  37. foxes/input/states/scan_ws.py +4 -1
  38. foxes/input/states/single.py +15 -6
  39. foxes/input/states/slice_data_nc.py +18 -12
  40. foxes/input/states/states_table.py +17 -10
  41. foxes/input/yaml/__init__.py +3 -0
  42. foxes/input/yaml/dict.py +210 -0
  43. foxes/input/yaml/windio/__init__.py +4 -0
  44. foxes/input/{windio → yaml/windio}/get_states.py +7 -7
  45. foxes/input/{windio → yaml/windio}/read_attributes.py +61 -40
  46. foxes/input/{windio → yaml/windio}/read_farm.py +34 -43
  47. foxes/input/{windio → yaml/windio}/read_fields.py +11 -10
  48. foxes/input/yaml/windio/read_outputs.py +147 -0
  49. foxes/input/yaml/windio/windio.py +269 -0
  50. foxes/input/yaml/yaml.py +103 -0
  51. foxes/models/partial_wakes/axiwake.py +7 -6
  52. foxes/models/partial_wakes/centre.py +3 -2
  53. foxes/models/partial_wakes/segregated.py +5 -2
  54. foxes/models/point_models/set_uniform_data.py +5 -3
  55. foxes/models/rotor_models/centre.py +2 -2
  56. foxes/models/rotor_models/grid.py +5 -5
  57. foxes/models/rotor_models/levels.py +6 -6
  58. foxes/models/turbine_models/kTI_model.py +3 -1
  59. foxes/models/turbine_models/lookup_table.py +7 -4
  60. foxes/models/turbine_models/power_mask.py +14 -8
  61. foxes/models/turbine_models/sector_management.py +4 -2
  62. foxes/models/turbine_models/set_farm_vars.py +53 -23
  63. foxes/models/turbine_models/table_factors.py +8 -7
  64. foxes/models/turbine_models/yaw2yawm.py +0 -1
  65. foxes/models/turbine_models/yawm2yaw.py +0 -1
  66. foxes/models/turbine_types/CpCt_file.py +6 -3
  67. foxes/models/turbine_types/CpCt_from_two.py +6 -3
  68. foxes/models/turbine_types/PCt_file.py +7 -6
  69. foxes/models/turbine_types/PCt_from_two.py +11 -2
  70. foxes/models/turbine_types/TBL_file.py +3 -4
  71. foxes/models/turbine_types/wsrho2PCt_from_two.py +19 -11
  72. foxes/models/turbine_types/wsti2PCt_from_two.py +19 -11
  73. foxes/models/vertical_profiles/abl_log_neutral_ws.py +1 -1
  74. foxes/models/vertical_profiles/abl_log_stable_ws.py +1 -1
  75. foxes/models/vertical_profiles/abl_log_unstable_ws.py +1 -1
  76. foxes/models/vertical_profiles/abl_log_ws.py +1 -1
  77. foxes/models/wake_frames/dynamic_wakes.py +17 -9
  78. foxes/models/wake_frames/farm_order.py +4 -3
  79. foxes/models/wake_frames/rotor_wd.py +3 -1
  80. foxes/models/wake_frames/seq_dynamic_wakes.py +14 -7
  81. foxes/models/wake_frames/streamlines.py +9 -6
  82. foxes/models/wake_frames/timelines.py +21 -14
  83. foxes/models/wake_frames/yawed_wakes.py +3 -1
  84. foxes/models/wake_models/induction/vortex_sheet.py +0 -1
  85. foxes/models/wake_models/ti/crespo_hernandez.py +2 -1
  86. foxes/models/wake_models/wind/bastankhah14.py +3 -2
  87. foxes/models/wake_models/wind/bastankhah16.py +2 -1
  88. foxes/models/wake_models/wind/turbopark.py +9 -7
  89. foxes/models/wake_superpositions/ws_product.py +0 -1
  90. foxes/output/calc_points.py +7 -4
  91. foxes/output/farm_layout.py +30 -18
  92. foxes/output/farm_results_eval.py +4 -3
  93. foxes/output/grids.py +8 -7
  94. foxes/output/output.py +7 -2
  95. foxes/output/results_writer.py +10 -11
  96. foxes/output/rose_plot.py +38 -20
  97. foxes/output/rotor_point_plots.py +7 -3
  98. foxes/output/slice_data.py +1 -1
  99. foxes/output/state_turbine_map.py +5 -1
  100. foxes/output/state_turbine_table.py +7 -3
  101. foxes/output/turbine_type_curves.py +7 -2
  102. foxes/utils/dict.py +107 -3
  103. foxes/utils/geopandas_utils.py +3 -2
  104. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/METADATA +20 -21
  105. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/RECORD +122 -122
  106. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/WHEEL +1 -1
  107. foxes-1.2.dist-info/entry_points.txt +3 -0
  108. tests/0_consistency/iterative/test_iterative.py +65 -67
  109. tests/0_consistency/partial_wakes/test_partial_wakes.py +58 -61
  110. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +56 -53
  111. tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +41 -41
  112. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +34 -34
  113. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +50 -50
  114. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +51 -52
  115. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +73 -74
  116. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +73 -74
  117. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +51 -49
  118. tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +101 -103
  119. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +61 -62
  120. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +51 -52
  121. examples/windio/run.py +0 -29
  122. foxes/data/states/windio_timeseries_5000.nc +0 -0
  123. foxes/data/windio/DTU_10MW_turbine.yaml +0 -10
  124. foxes/data/windio/__init__.py +0 -0
  125. foxes/data/windio/windio_5turbines_timeseries.yaml +0 -79
  126. foxes/input/windio/__init__.py +0 -11
  127. foxes/input/windio/read_outputs.py +0 -172
  128. foxes/input/windio/runner.py +0 -183
  129. foxes/input/windio/windio.py +0 -193
  130. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/LICENSE +0 -0
  131. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/top_level.txt +0 -0
@@ -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__(self, ws=None, wd=None, ti=None, rho=None, profiles={}, **profdata):
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=FC.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=FC.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=FC.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=FC.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=FC.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 = StaticData().get_file_path(
149
- STATES, self.data_source, check_raw=True
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
- if Path(self.data_source).is_file():
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
- with _read_ds() as ds:
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((n_sts, n_y, n_x, len(self.var2ncvar)), dtype=FC.DTYPE)
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=FC.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=FC.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(points, np.zeros((n_states, n_pts, 1), dtype=FC.DTYPE), axis=2)
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=FC.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
- if not Path(self.data_source).is_file():
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=FC.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), dtype=FC.DTYPE
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), f, dtype=FC.DTYPE
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
- if not Path(self.__tab_source).is_file():
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=FC.DTYPE), self.__tab_data["ws"].to_numpy()
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=FC.DTYPE)
578
- wd = np.zeros((n_ws, n_wd), dtype=FC.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
 
@@ -0,0 +1,3 @@
1
+ from .dict import run_dict
2
+ from .yaml import foxes_yaml
3
+ from .windio.windio import read_windio, foxes_windio
@@ -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
@@ -0,0 +1,4 @@
1
+ from .windio import foxes_windio, read_windio
2
+ from .read_fields import read_wind_resource_field
3
+ from .read_farm import read_layout, read_turbine_types
4
+ from .read_attributes import read_attributes
@@ -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(" Preparing states")
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}