foxes 1.1.1__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 -1
  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.1.dist-info → foxes-1.2.dist-info}/METADATA +18 -17
  105. {foxes-1.1.1.dist-info → foxes-1.2.dist-info}/RECORD +122 -122
  106. {foxes-1.1.1.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.1.dist-info → foxes-1.2.dist-info}/LICENSE +0 -0
  131. {foxes-1.1.1.dist-info → foxes-1.2.dist-info}/top_level.txt +0 -0
@@ -6,7 +6,13 @@ from .read_outputs import read_outputs
6
6
 
7
7
 
8
8
  def _read_wind_deficit(
9
- wake_model_key, wind_deficit, superposition, induction, algo_dict, verbosity
9
+ wake_model_key,
10
+ wind_deficit,
11
+ superposition,
12
+ induction,
13
+ algo_dict,
14
+ mbook,
15
+ verbosity,
10
16
  ):
11
17
  """Reads the wind deficit wake model"""
12
18
 
@@ -69,17 +75,25 @@ def _read_wind_deficit(
69
75
  supd = ws_sup_dict if eff_ws else ws_sup_amb_dict
70
76
  wind_def_dict["superposition"] = supd[superposition["ws_superposition"]]
71
77
 
72
- algo_dict["mbook"].wake_models[wname] = WakeModel.new(**wind_def_dict)
78
+ mbook.wake_models[wname] = WakeModel.new(**wind_def_dict)
73
79
  if verbosity > 2:
74
80
  print(f" Created wake model '{wname}':")
75
- print(" ", algo_dict["mbook"].wake_models[wname])
81
+ print(" ", mbook.wake_models[wname])
76
82
  algo_dict["wake_models"].append(wname)
77
83
 
78
84
  return ka, kb, amb_ti
79
85
 
80
86
 
81
87
  def _read_turbulence(
82
- turbulence_model, superposition, induction, algo_dict, ka, kb, amb_ti, verbosity
88
+ turbulence_model,
89
+ superposition,
90
+ induction,
91
+ algo_dict,
92
+ mbook,
93
+ ka,
94
+ kb,
95
+ amb_ti,
96
+ verbosity,
83
97
  ):
84
98
  """Reads the ti wake model"""
85
99
 
@@ -128,14 +142,14 @@ def _read_turbulence(
128
142
  tiwake_dict["ti_var"] = ti_var
129
143
  tiwake_dict["superposition"] = ti_sup_dict[superposition["ti_superposition"]]
130
144
 
131
- algo_dict["mbook"].wake_models[wname] = WakeModel.new(**tiwake_dict)
145
+ mbook.wake_models[wname] = WakeModel.new(**tiwake_dict)
132
146
  if verbosity > 2:
133
147
  print(f" Created wake model '{wname}':")
134
- print(" ", algo_dict["mbook"].wake_models[wname])
148
+ print(" ", mbook.wake_models[wname])
135
149
  algo_dict["wake_models"].append(wname)
136
150
 
137
151
 
138
- def _read_blockage(blockage_model, induction, algo_dict, verbosity):
152
+ def _read_blockage(blockage_model, induction, algo_dict, mbook, verbosity):
139
153
  """Reads the blockage model"""
140
154
  indc_def_map = Dict(
141
155
  {
@@ -154,10 +168,10 @@ def _read_blockage(blockage_model, induction, algo_dict, verbosity):
154
168
  print(" Contents:", [k for k in blockage_model.keys()])
155
169
  if wname not in ["None", "none"]:
156
170
  indc_dict = Dict(wmodel_type=indc_def_map[wname], induction=induction)
157
- algo_dict["mbook"].wake_models[wname] = WakeModel.new(**indc_dict)
171
+ mbook.wake_models[wname] = WakeModel.new(**indc_dict)
158
172
  if verbosity > 2:
159
173
  print(f" Created wake model '{wname}':")
160
- print(" ", algo_dict["mbook"].wake_models[wname])
174
+ print(" ", mbook.wake_models[wname])
161
175
  algo_dict["wake_models"].append(wname)
162
176
  algo_dict["algo_type"] = "Iterative"
163
177
 
@@ -214,7 +228,7 @@ def _read_rotor_averaging(rotor_averaging, algo_dict, verbosity):
214
228
  print(" --> partial_wakes :", algo_dict["partial_wakes"])
215
229
 
216
230
 
217
- def _read_deflection(deflection, induction, algo_dict, verbosity):
231
+ def _read_deflection(deflection, induction, algo_dict, mbook, verbosity):
218
232
  """Reads deflection model"""
219
233
  defl_def_map = Dict(
220
234
  {
@@ -231,25 +245,25 @@ def _read_deflection(deflection, induction, algo_dict, verbosity):
231
245
  print(" Contents:", [k for k in deflection.keys()])
232
246
  indc_dict = Dict(wframe_type=defl_def_map[wname])
233
247
  try:
234
- algo_dict["mbook"].wake_frames[wname] = WakeFrame.new(
235
- **indc_dict, induction=induction
236
- )
248
+ mbook.wake_frames[wname] = WakeFrame.new(**indc_dict, induction=induction)
237
249
  except TypeError:
238
- algo_dict["mbook"].wake_frames[wname] = WakeFrame.new(**indc_dict)
250
+ mbook.wake_frames[wname] = WakeFrame.new(**indc_dict)
239
251
  if verbosity > 2:
240
252
  print(f" Created wake frame '{wname}':")
241
- print(" ", algo_dict["mbook"].wake_frames[wname])
253
+ print(" ", mbook.wake_frames[wname])
242
254
  algo_dict["wake_frame"] = wname
243
255
 
244
256
 
245
- def _read_analysis(wio_ana, algo_dict, verbosity):
257
+ def _read_analysis(wio_ana, idict, mbook, verbosity):
246
258
  """Reads the windio analyses"""
247
259
  if verbosity > 2:
248
260
  print(" Reading analysis")
249
261
  print(" Contents:", [k for k in wio_ana.keys()])
250
262
 
251
263
  # superposition:
252
- superposition = Dict(wio_ana["superposition_model"], name="superposition_model")
264
+ superposition = Dict(
265
+ wio_ana["superposition_model"], name=wio_ana.name + ".superposition_model"
266
+ )
253
267
  if verbosity > 2:
254
268
  print(" Reading superposition_model")
255
269
  print(" Contents:", [k for k in superposition.keys()])
@@ -270,9 +284,18 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
270
284
  wake_model_key = (
271
285
  "wind_deficit_model" if "wind_deficit_model" in wio_ana else "wake_model"
272
286
  )
273
- wind_deficit = Dict(wio_ana[wake_model_key], name=wake_model_key)
287
+ algo_dict = idict["algorithm"]
288
+ wind_deficit = Dict(
289
+ wio_ana[wake_model_key], name=wio_ana.name + "." + wake_model_key
290
+ )
274
291
  ka, kb, amb_ti = _read_wind_deficit(
275
- wake_model_key, wind_deficit, superposition, induction, algo_dict, verbosity
292
+ wake_model_key,
293
+ wind_deficit,
294
+ superposition,
295
+ induction,
296
+ algo_dict,
297
+ mbook,
298
+ verbosity,
276
299
  )
277
300
 
278
301
  # turbulence model:
@@ -283,6 +306,7 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
283
306
  superposition,
284
307
  induction,
285
308
  algo_dict,
309
+ mbook,
286
310
  ka,
287
311
  kb,
288
312
  amb_ti,
@@ -294,7 +318,7 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
294
318
  # blockage model:
295
319
  if "blockage_model" in wio_ana:
296
320
  blockage_model = Dict(wio_ana["blockage_model"], name="blockage_model")
297
- _read_blockage(blockage_model, induction, algo_dict, verbosity)
321
+ _read_blockage(blockage_model, induction, algo_dict, mbook, verbosity)
298
322
  elif verbosity > 0:
299
323
  print("blockage_model not found, not using a turbine induction model")
300
324
 
@@ -308,37 +332,35 @@ def _read_analysis(wio_ana, algo_dict, verbosity):
308
332
  # deflection:
309
333
  if "deflection_model" in wio_ana:
310
334
  deflection = Dict(wio_ana["deflection_model"], name="deflection_model")
311
- _read_deflection(deflection, induction, algo_dict, verbosity)
335
+ _read_deflection(deflection, induction, algo_dict, mbook, verbosity)
312
336
  elif verbosity > 0:
313
337
  print("deflection_model not found, using default settings")
314
338
 
315
339
 
316
- def read_attributes(wio, algo_dict, verbosity=1, **output_pars):
340
+ def read_attributes(wio, idict, mbook, verbosity=1):
317
341
  """
318
342
  Reads the attributes part of windio
319
343
 
320
344
  Parameters
321
345
  ----------
322
- wio: dict
346
+ wio: foxes.utils.Dict
323
347
  The windio data
324
- algo_dict: dict
325
- The algorithm dictionary
348
+ idict: foxes.utils.Dict
349
+ The foxes input data dictionary
350
+ mbook: foxes.models.ModelBook
351
+ The model book
326
352
  verbosity: int
327
353
  The verbosity level, 0=silent
328
- **output_pars: dict, optional
329
- Additional parameters for output reading
330
354
 
331
355
  Returns
332
356
  -------
333
- out_dicts: list of dict
334
- The output dictionaries
335
357
  odir: pathlib.Path
336
- Path to the output folder
358
+ The output directory
337
359
 
338
- :group: input.windio
360
+ :group: input.yaml.windio
339
361
 
340
362
  """
341
- wio_attrs = Dict(wio["attributes"], name="attributes")
363
+ wio_attrs = Dict(wio["attributes"], name=wio.name + ".attributes")
342
364
  if verbosity > 1:
343
365
  print("Reading attributes")
344
366
  print(" Contents:", [k for k in wio_attrs.keys()])
@@ -355,15 +377,14 @@ def read_attributes(wio, algo_dict, verbosity=1, **output_pars):
355
377
  print(f"Running flow model 'foxes', overruling original choice '{fmname}'")
356
378
 
357
379
  # read analysis:
358
- wio_ana = Dict(wio_attrs["analysis"], name="analyses")
359
- _read_analysis(wio_ana, algo_dict, verbosity)
380
+ wio_ana = Dict(wio_attrs["analysis"], name=wio_attrs.name + ".analysis")
381
+ _read_analysis(wio_ana, idict, mbook, verbosity)
360
382
 
361
383
  # outputs:
362
- out_dicts = []
384
+ odict = idict["outputs"]
385
+ odir = "."
363
386
  if "outputs" in wio_attrs:
364
- outputs = Dict(wio_attrs["outputs"], name="outputs")
365
- out_dicts, odir = read_outputs(
366
- outputs, algo_dict, verbosity=verbosity, **output_pars
367
- )
387
+ outputs = Dict(wio_attrs["outputs"], name=wio_attrs.name + ".outputs")
388
+ odir = read_outputs(outputs, odict, verbosity=verbosity)
368
389
 
369
- return out_dicts, odir
390
+ return odir
@@ -6,7 +6,7 @@ from foxes.core import Turbine, TurbineType
6
6
  import foxes.variables as FV
7
7
 
8
8
 
9
- def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
9
+ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
10
10
  """
11
11
  Reads the turbine type from windio
12
12
 
@@ -14,8 +14,8 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
14
14
  ----------
15
15
  wio_farm: dict
16
16
  The windio farm data
17
- algo_dict: dict
18
- The algorithm dictionary
17
+ mbook: foxes.models.ModelBook
18
+ The model book
19
19
  ws_exp_P: int
20
20
  The REWS exponent for power
21
21
  ws_exp_ct: int
@@ -29,9 +29,14 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
29
29
  Mapping from turbine type key to turbine
30
30
  type name in the model book
31
31
 
32
- :group: input.windio
32
+ :group: input.yaml.windio
33
33
 
34
34
  """
35
+
36
+ def _print(*args, level=1, **kwargs):
37
+ if verbosity >= level:
38
+ print(*args, **kwargs)
39
+
35
40
  if "turbine_types" not in wio_farm:
36
41
  wio_farm["turbine_types"] = {0: wio_farm["turbines"]}
37
42
 
@@ -39,29 +44,25 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
39
44
  for k, wio_trbns in wio_farm["turbine_types"].items():
40
45
  tname = wio_trbns.pop("name")
41
46
  ttypes[k] = tname
42
- if verbosity > 2:
43
- print(" Reading turbine type", k)
44
- print(" Name:", tname)
45
- print(" Contents:", [k for k in wio_trbns.keys()])
47
+ _print(" Reading turbine type", k, level=3)
48
+ _print(" Name:", tname, level=3)
49
+ _print(" Contents:", [k for k in wio_trbns.keys()], level=3)
46
50
 
47
51
  # read performance:
48
52
  performance = Dict(wio_trbns["performance"], name="performance")
49
- if verbosity > 2:
50
- print(" Reading performance")
51
- print(" Contents:", [k for k in performance.keys()])
53
+ _print(" Reading performance", level=3)
54
+ _print(" Contents:", [k for k in performance.keys()], level=3)
52
55
 
53
56
  # P, ct data:
54
57
  if "power_curve" in performance:
55
58
  power_curve = Dict(performance["power_curve"], name="power_curve")
56
- if verbosity > 2:
57
- print(" Reading power_curve")
58
- print(" Contents:", [k for k in power_curve.keys()])
59
+ _print(" Reading power_curve", level=3)
60
+ _print(" Contents:", [k for k in power_curve.keys()], level=3)
59
61
  P = power_curve["power_values"]
60
62
  ws_P = power_curve["power_wind_speeds"]
61
63
  ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
62
- if verbosity > 2:
63
- print(" Reading Ct_curve")
64
- print(" Contents:", [k for k in ct_curve.keys()])
64
+ _print(" Reading Ct_curve", level=3)
65
+ _print(" Contents:", [k for k in ct_curve.keys()], level=3)
65
66
  ct = ct_curve["Ct_values"]
66
67
  ws_ct = ct_curve["Ct_wind_speeds"]
67
68
 
@@ -75,10 +76,9 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
75
76
  )
76
77
  return FV.REWS if wse == 1 else (FV.REWS2 if wse == 2 else FV.REWS3)
77
78
 
78
- if verbosity > 2:
79
- print(f" Creating model '{tname}'")
80
- print(f" Turbine type class: PCtFromTwo")
81
- algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
79
+ _print(f" Creating model '{tname}'", level=3)
80
+ _print(f" Turbine type class: PCtFomTwo", level=3)
81
+ mbook.turbine_types[tname] = TurbineType.new(
82
82
  ttype_type="PCtFromTwo",
83
83
  data_source_P=data_P,
84
84
  data_source_ct=data_ct,
@@ -92,31 +92,27 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
92
92
  var_ws_P=_get_wse_var(ws_exp_P),
93
93
  rho=1.225,
94
94
  )
95
- if verbosity > 2:
96
- print(" ", algo_dict["mbook"].turbine_types[tname])
95
+ _print(" ", mbook.turbine_types[tname], level=3)
97
96
 
98
97
  # P, ct data:
99
98
  elif "Cp_curve" in performance:
100
99
  cp_curve = Dict(performance["Cp_curve"], name="Cp_curve")
101
- if verbosity > 2:
102
- print(" Reading Cp_curve")
103
- print(" Contents:", [k for k in cp_curve.keys()])
100
+ _print(" Reading Cp_curve", level=3)
101
+ _print(" Contents:", [k for k in cp_curve.keys()], level=3)
104
102
  cp = cp_curve["Cp_values"]
105
103
  ws_cp = cp_curve["Cp_wind_speeds"]
106
104
  ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
107
- if verbosity > 2:
108
- print(" Reading Ct_curve")
109
- print(" Contents:", [k for k in ct_curve.keys()])
105
+ _print(" Reading Ct_curve", level=3)
106
+ _print(" Contents:", [k for k in ct_curve.keys()], level=3)
110
107
  ct = ct_curve["Ct_values"]
111
108
  ws_ct = ct_curve["Ct_wind_speeds"]
112
109
 
113
110
  data_cp = pd.DataFrame(data={"ws": ws_cp, "cp": cp})
114
111
  data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
115
112
 
116
- if verbosity > 2:
117
- print(f" Creating model '{tname}'")
118
- print(f" Turbine type class: CpCtFromTwo")
119
- algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
113
+ _print(f" Creating model '{tname}'", level=3)
114
+ _print(f" Turbine type class: CpCtFromTwo", level=3)
115
+ mbook.turbine_types[tname] = TurbineType.new(
120
116
  ttype_type="CpCtFromTwo",
121
117
  data_source_cp=data_cp,
122
118
  data_source_ct=data_ct,
@@ -127,6 +123,7 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
127
123
  H=wio_trbns["hub_height"],
128
124
  D=wio_trbns["rotor_diameter"],
129
125
  )
126
+ _print(" ", mbook.turbine_types[tname], level=3)
130
127
 
131
128
  else:
132
129
  raise KeyError(f"Expecting either 'power_curve' or 'Cp_curve'")
@@ -134,7 +131,7 @@ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
134
131
  return ttypes
135
132
 
136
133
 
137
- def read_layout(lname, ldict, algo_dict, ttypes, verbosity=1):
134
+ def read_layout(lname, ldict, farm, ttypes, verbosity=1):
138
135
  """
139
136
  Read wind farm layout from windio input
140
137
 
@@ -144,26 +141,20 @@ def read_layout(lname, ldict, algo_dict, ttypes, verbosity=1):
144
141
  The layout name
145
142
  ldict: dict
146
143
  The layout data
147
- algo_dict: dict
148
- The algorithm dictionary
144
+ farm: foxes.core.WindFarm
145
+ The wind farm
149
146
  ttypes: dict
150
147
  Mapping from turbine type key to turbine
151
148
  type name in the model book
152
149
  verbosity: int
153
150
  The verbosity level, 0=silent
154
151
 
155
- Returns
156
- -------
157
- states: foxes.core.States
158
- The states object
159
-
160
- :group: input.windio
152
+ :group: input.yaml.windio
161
153
 
162
154
  """
163
155
  if verbosity > 2:
164
156
  print(f" Reading '{lname}'")
165
157
  cdict = Dict(ldict["coordinates"], name="coordinates")
166
- farm = algo_dict["farm"]
167
158
  tmap = ldict.get("turbine_types", None)
168
159
  if verbosity > 2:
169
160
  print(f" Turbine type map:", tmap)
@@ -1,11 +1,12 @@
1
1
  import numpy as np
2
2
  from numbers import Number
3
3
 
4
- import foxes.constants as FC
5
4
  import foxes.variables as FV
5
+ import foxes.constants as FC
6
+
6
7
 
7
8
  """ Mapping from windio to foxes variables
8
- :group: input.windio
9
+ :group: input.yaml.windio
9
10
  """
10
11
  wio2foxes = {
11
12
  "time": FC.TIME,
@@ -24,14 +25,14 @@ wio2foxes = {
24
25
  }
25
26
 
26
27
  """ Mapping from foxes to windio variables
27
- :group: input.windio
28
+ :group: input.yaml.windio
28
29
  """
29
30
  foxes2wio = {d: k for k, d in wio2foxes.items()}
30
31
 
31
32
 
32
33
  def _read_nondimensional_coordinate(name, wio_data, coords):
33
34
  """read nondimensional coordinate
34
- :group: input.windio
35
+ :group: input.yaml.windio
35
36
  """
36
37
  if isinstance(wio_data, Number):
37
38
  coords[wio2foxes[name]] = wio_data
@@ -41,7 +42,7 @@ def _read_nondimensional_coordinate(name, wio_data, coords):
41
42
 
42
43
  def _read_dimensional_coordinate(name, wio_data, coords):
43
44
  """read dimensional coordinate
44
- :group: input.windio
45
+ :group: input.yaml.windio
45
46
  """
46
47
  if isinstance(wio_data, list):
47
48
  wio_data = np.array(wio_data)
@@ -53,7 +54,7 @@ def _read_dimensional_coordinate(name, wio_data, coords):
53
54
 
54
55
  def _read_multi_dimensional_coordinate(name, wio_data, coords):
55
56
  """Read multi dimensional coordinate
56
- :group: input.windio
57
+ :group: input.yaml.windio
57
58
  """
58
59
  return _read_nondimensional_coordinate(
59
60
  name, wio_data, coords
@@ -62,7 +63,7 @@ def _read_multi_dimensional_coordinate(name, wio_data, coords):
62
63
 
63
64
  def _read_nondimensional_data(name, wio_data, fields, dims):
64
65
  """read nondimensional data
65
- :group: input.windio
66
+ :group: input.yaml.windio
66
67
  """
67
68
  if isinstance(wio_data, Number):
68
69
  v = wio2foxes[name]
@@ -74,7 +75,7 @@ def _read_nondimensional_data(name, wio_data, fields, dims):
74
75
 
75
76
  def _read_dimensional_data(name, wio_data, fields, dims):
76
77
  """read dimensional data
77
- :group: input.windio
78
+ :group: input.yaml.windio
78
79
  """
79
80
  if isinstance(wio_data, dict) and "data" in wio_data and "dims" in wio_data:
80
81
  d = wio_data["data"]
@@ -91,7 +92,7 @@ def _read_dimensional_data(name, wio_data, fields, dims):
91
92
 
92
93
  def _read_multi_dimensional_data(name, wio_data, fields, dims):
93
94
  """Read multi dimensional data
94
- :group: input.windio
95
+ :group: input.yaml.windio
95
96
  """
96
97
  return _read_nondimensional_data(
97
98
  name, wio_data, fields, dims
@@ -129,7 +130,7 @@ def read_wind_resource_field(
129
130
  success: bool
130
131
  Flag for successful data extraction
131
132
 
132
- :group: input.windio
133
+ :group: input.yaml.windio
133
134
 
134
135
  """
135
136
  if name in [
@@ -0,0 +1,147 @@
1
+ from pathlib import Path
2
+
3
+ from foxes.utils import Dict
4
+ import foxes.variables as FV
5
+ import foxes.constants as FC
6
+
7
+ from .read_fields import foxes2wio
8
+
9
+
10
+ def _read_turbine_outputs(wio_outs, odict, verbosity):
11
+ """Reads the turbine outputs request"""
12
+ if "turbine_outputs" in wio_outs and wio_outs["turbine_outputs"].get(
13
+ "report", True
14
+ ):
15
+ turbine_outputs = Dict(
16
+ wio_outs["turbine_outputs"], name=wio_outs.name + ".turbine_outputs"
17
+ )
18
+ turbine_nc_filename = turbine_outputs.pop(
19
+ "turbine_nc_filename", "turbine_outputs.nc"
20
+ )
21
+ output_variables = turbine_outputs["output_variables"]
22
+ if verbosity > 2:
23
+ print(" Reading turbine_outputs")
24
+ print(" File name:", turbine_nc_filename)
25
+ print(" output_variables:", output_variables)
26
+
27
+ vmap = Dict(
28
+ power=FV.P,
29
+ rotor_effective_velocity=FV.REWS,
30
+ )
31
+ ivmap = {d: k for k, d in vmap.items()}
32
+ ivmap.update(
33
+ {
34
+ FC.STATE: "time",
35
+ FC.TURBINE: "turbine",
36
+ }
37
+ )
38
+
39
+ odict["StateTurbineTable"] = Dict(
40
+ functions=[
41
+ dict(
42
+ name="get_dataset",
43
+ variables=[vmap[v] for v in output_variables],
44
+ name_map=ivmap,
45
+ to_file=turbine_nc_filename,
46
+ round={vw: FV.get_default_digits(vf) for vw, vf in vmap.items()},
47
+ verbosity=verbosity,
48
+ )
49
+ ],
50
+ name=odict.name + ".StateTurbineTable",
51
+ )
52
+
53
+
54
+ def _read_flow_field(wio_outs, odict, verbosity):
55
+ """Reads the flow field request"""
56
+ if "flow_field" in wio_outs and wio_outs["flow_field"].get("report", True):
57
+ flow_field = Dict(wio_outs["flow_field"], name=wio_outs.name + ".flow_field")
58
+ flow_nc_filename = flow_field.pop("flow_nc_filename", "flow_field.nc")
59
+ output_variables = flow_field.pop("output_variables")
60
+ z_planes = Dict(flow_field.pop("z_planes"), name=flow_field.name + ".z_planes")
61
+ z_sampling = z_planes["z_sampling"]
62
+ xy_sampling = z_planes["xy_sampling"]
63
+ cases_run = Dict(
64
+ flow_field.pop("cases_run", {}), name=flow_field.name + ".cases_run"
65
+ )
66
+ states_isel = cases_run.get("subset", None)
67
+ if "all_occurences" in cases_run and cases_run.pop("all_occurences"):
68
+ states_isel = None
69
+ if verbosity > 2:
70
+ print(" Reading flow_field")
71
+ print(" File name :", flow_nc_filename)
72
+ print(" output_variables:", output_variables)
73
+ print(" states subset :", states_isel)
74
+ print(" z_sampling :", z_sampling)
75
+ print(" xy_sampling :", xy_sampling)
76
+
77
+ vmap = Dict(
78
+ wind_speed=FV.WS,
79
+ wind_direction=FV.WD,
80
+ )
81
+
82
+ if z_sampling in ["hub_height", "default"]:
83
+ z = None
84
+ elif isinstance(z_sampling, (int, float)):
85
+ z = z_sampling
86
+ else:
87
+ raise NotImplementedError(
88
+ f"z_sampling '{z_sampling}' of type '{type(z_sampling).__name__}' is not supported (yet). Please give 'hub_height', 'default' or a float."
89
+ )
90
+
91
+ if xy_sampling == "default":
92
+ odict["SliceData"] = Dict(
93
+ verbosity_delta=3,
94
+ functions=[
95
+ dict(
96
+ name="get_states_data_xy",
97
+ states_isel=states_isel,
98
+ n_img_points=(100, 100),
99
+ variables=[vmap[v] for v in output_variables],
100
+ z=z,
101
+ to_file=flow_nc_filename,
102
+ label_map=foxes2wio,
103
+ verbosity=verbosity,
104
+ )
105
+ ],
106
+ name=odict.name + ".SliceData",
107
+ )
108
+ else:
109
+ raise NotImplementedError(
110
+ f"xy_sampling '{xy_sampling}' is not supported (yet)"
111
+ )
112
+
113
+
114
+ def read_outputs(wio_outs, odict, verbosity=1):
115
+ """
116
+ Reads the windio outputs
117
+
118
+ Parameters
119
+ ----------
120
+ wio_outs: foxes.utils.Dict
121
+ The windio output data dict
122
+ odict: foxes.utils.Dict
123
+ The foxes output dictionary
124
+ verbosity: int
125
+ The verbosity level, 0=silent
126
+
127
+ Returns
128
+ -------
129
+ odir: pathlib.Path
130
+ The output directory
131
+
132
+ :group: input.yaml.windio
133
+
134
+ """
135
+ odir = wio_outs.pop("output_folder", ".")
136
+ if verbosity > 2:
137
+ print(" Reading outputs")
138
+ print(" Output dir:", odir)
139
+ print(" Contents :", [k for k in wio_outs.keys()])
140
+
141
+ # read turbine_outputs:
142
+ _read_turbine_outputs(wio_outs, odict, verbosity)
143
+
144
+ # read flow field:
145
+ _read_flow_field(wio_outs, odict, verbosity)
146
+
147
+ return odir