foxes 1.3__py3-none-any.whl → 1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of foxes might be problematic. Click here for more details.

Files changed (228) hide show
  1. docs/source/conf.py +3 -3
  2. examples/abl_states/run.py +2 -2
  3. examples/compare_rotors_pwakes/run.py +1 -1
  4. examples/compare_wakes/run.py +1 -2
  5. examples/dyn_wakes/run.py +29 -6
  6. examples/field_data_nc/run.py +1 -1
  7. examples/induction/run.py +3 -3
  8. examples/multi_height/run.py +1 -1
  9. examples/power_mask/run.py +2 -2
  10. examples/quickstart/run.py +0 -1
  11. examples/random_timeseries/run.py +3 -4
  12. examples/scan_row/run.py +3 -3
  13. examples/sequential/run.py +33 -10
  14. examples/single_state/run.py +3 -4
  15. examples/states_lookup_table/run.py +3 -3
  16. examples/streamline_wakes/run.py +29 -6
  17. examples/tab_file/run.py +3 -3
  18. examples/timelines/run.py +29 -5
  19. examples/timeseries/run.py +3 -3
  20. examples/timeseries_slurm/run.py +3 -3
  21. examples/wind_rose/run.py +3 -3
  22. examples/yawed_wake/run.py +19 -9
  23. foxes/__init__.py +21 -17
  24. foxes/algorithms/__init__.py +6 -6
  25. foxes/algorithms/downwind/__init__.py +2 -2
  26. foxes/algorithms/downwind/downwind.py +49 -17
  27. foxes/algorithms/downwind/models/__init__.py +6 -6
  28. foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -9
  29. foxes/algorithms/downwind/models/init_farm_data.py +58 -29
  30. foxes/algorithms/downwind/models/point_wakes_calc.py +7 -13
  31. foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
  32. foxes/algorithms/downwind/models/set_amb_point_results.py +6 -6
  33. foxes/algorithms/iterative/__init__.py +7 -3
  34. foxes/algorithms/iterative/iterative.py +1 -2
  35. foxes/algorithms/iterative/models/__init__.py +7 -3
  36. foxes/algorithms/iterative/models/farm_wakes_calc.py +9 -5
  37. foxes/algorithms/sequential/__init__.py +3 -3
  38. foxes/algorithms/sequential/models/__init__.py +2 -2
  39. foxes/algorithms/sequential/sequential.py +3 -4
  40. foxes/config/__init__.py +5 -1
  41. foxes/constants.py +16 -0
  42. foxes/core/__init__.py +45 -22
  43. foxes/core/algorithm.py +5 -6
  44. foxes/core/data.py +94 -22
  45. foxes/core/data_calc_model.py +4 -2
  46. foxes/core/engine.py +42 -53
  47. foxes/core/farm_controller.py +2 -2
  48. foxes/core/farm_data_model.py +16 -13
  49. foxes/core/ground_model.py +4 -13
  50. foxes/core/model.py +24 -6
  51. foxes/core/partial_wakes_model.py +147 -10
  52. foxes/core/point_data_model.py +21 -17
  53. foxes/core/rotor_model.py +4 -3
  54. foxes/core/states.py +2 -3
  55. foxes/core/turbine.py +2 -1
  56. foxes/core/wake_deflection.py +130 -0
  57. foxes/core/wake_model.py +222 -9
  58. foxes/core/wake_superposition.py +122 -4
  59. foxes/core/wind_farm.py +6 -6
  60. foxes/data/__init__.py +7 -2
  61. foxes/data/states/point_cloud_100.nc +0 -0
  62. foxes/data/states/weibull_cloud_4.nc +0 -0
  63. foxes/data/states/weibull_grid.nc +0 -0
  64. foxes/data/states/weibull_sectors_12.csv +13 -0
  65. foxes/data/states/weibull_sectors_12.nc +0 -0
  66. foxes/engines/__init__.py +14 -15
  67. foxes/engines/dask.py +42 -20
  68. foxes/engines/default.py +2 -2
  69. foxes/engines/numpy.py +11 -13
  70. foxes/engines/pool.py +20 -11
  71. foxes/engines/single.py +8 -6
  72. foxes/input/__init__.py +3 -3
  73. foxes/input/farm_layout/__init__.py +9 -8
  74. foxes/input/farm_layout/from_arrays.py +68 -0
  75. foxes/input/farm_layout/from_csv.py +1 -1
  76. foxes/input/farm_layout/ring.py +0 -1
  77. foxes/input/states/__init__.py +28 -12
  78. foxes/input/states/create/__init__.py +3 -2
  79. foxes/input/states/dataset_states.py +710 -0
  80. foxes/input/states/field_data.py +531 -0
  81. foxes/input/states/multi_height.py +11 -6
  82. foxes/input/states/one_point_flow.py +1 -4
  83. foxes/input/states/point_cloud_data.py +618 -0
  84. foxes/input/states/scan.py +2 -0
  85. foxes/input/states/single.py +3 -1
  86. foxes/input/states/states_table.py +23 -30
  87. foxes/input/states/weibull_sectors.py +330 -0
  88. foxes/input/states/wrg_states.py +8 -6
  89. foxes/input/yaml/__init__.py +9 -3
  90. foxes/input/yaml/dict.py +42 -41
  91. foxes/input/yaml/windio/__init__.py +10 -5
  92. foxes/input/yaml/windio/read_attributes.py +42 -29
  93. foxes/input/yaml/windio/read_farm.py +17 -15
  94. foxes/input/yaml/windio/read_fields.py +4 -2
  95. foxes/input/yaml/windio/read_outputs.py +25 -15
  96. foxes/input/yaml/windio/read_site.py +172 -11
  97. foxes/input/yaml/windio/windio.py +23 -11
  98. foxes/input/yaml/yaml.py +1 -0
  99. foxes/models/__init__.py +15 -14
  100. foxes/models/axial_induction/__init__.py +2 -2
  101. foxes/models/farm_controllers/__init__.py +1 -1
  102. foxes/models/farm_models/__init__.py +1 -1
  103. foxes/models/ground_models/__init__.py +3 -2
  104. foxes/models/ground_models/wake_mirror.py +3 -3
  105. foxes/models/model_book.py +190 -63
  106. foxes/models/partial_wakes/__init__.py +6 -6
  107. foxes/models/partial_wakes/axiwake.py +30 -5
  108. foxes/models/partial_wakes/centre.py +47 -0
  109. foxes/models/partial_wakes/rotor_points.py +41 -11
  110. foxes/models/partial_wakes/segregated.py +2 -25
  111. foxes/models/partial_wakes/top_hat.py +27 -2
  112. foxes/models/point_models/__init__.py +4 -4
  113. foxes/models/rotor_models/__init__.py +4 -3
  114. foxes/models/rotor_models/centre.py +1 -1
  115. foxes/models/rotor_models/direct_infusion.py +241 -0
  116. foxes/models/turbine_models/__init__.py +11 -11
  117. foxes/models/turbine_models/calculator.py +16 -3
  118. foxes/models/turbine_models/kTI_model.py +1 -0
  119. foxes/models/turbine_models/lookup_table.py +2 -0
  120. foxes/models/turbine_models/power_mask.py +1 -0
  121. foxes/models/turbine_models/rotor_centre_calc.py +2 -0
  122. foxes/models/turbine_models/sector_management.py +1 -0
  123. foxes/models/turbine_models/set_farm_vars.py +3 -9
  124. foxes/models/turbine_models/table_factors.py +2 -0
  125. foxes/models/turbine_models/thrust2ct.py +1 -0
  126. foxes/models/turbine_models/yaw2yawm.py +2 -0
  127. foxes/models/turbine_models/yawm2yaw.py +2 -0
  128. foxes/models/turbine_types/PCt_file.py +2 -6
  129. foxes/models/turbine_types/PCt_from_two.py +1 -2
  130. foxes/models/turbine_types/__init__.py +10 -9
  131. foxes/models/turbine_types/calculator_type.py +123 -0
  132. foxes/models/turbine_types/null_type.py +1 -0
  133. foxes/models/turbine_types/wsrho2PCt_from_two.py +2 -0
  134. foxes/models/turbine_types/wsti2PCt_from_two.py +3 -1
  135. foxes/models/vertical_profiles/__init__.py +7 -7
  136. foxes/models/wake_deflections/__init__.py +3 -0
  137. foxes/models/{wake_frames/yawed_wakes.py → wake_deflections/bastankhah2016.py} +32 -111
  138. foxes/models/wake_deflections/jimenez.py +277 -0
  139. foxes/models/wake_deflections/no_deflection.py +94 -0
  140. foxes/models/wake_frames/__init__.py +6 -7
  141. foxes/models/wake_frames/dynamic_wakes.py +12 -3
  142. foxes/models/wake_frames/rotor_wd.py +3 -1
  143. foxes/models/wake_frames/seq_dynamic_wakes.py +41 -7
  144. foxes/models/wake_frames/streamlines.py +8 -6
  145. foxes/models/wake_frames/timelines.py +9 -3
  146. foxes/models/wake_models/__init__.py +7 -7
  147. foxes/models/wake_models/dist_sliced.py +50 -84
  148. foxes/models/wake_models/gaussian.py +20 -0
  149. foxes/models/wake_models/induction/__init__.py +5 -5
  150. foxes/models/wake_models/induction/rankine_half_body.py +30 -71
  151. foxes/models/wake_models/induction/rathmann.py +65 -64
  152. foxes/models/wake_models/induction/self_similar.py +65 -68
  153. foxes/models/wake_models/induction/self_similar2020.py +0 -3
  154. foxes/models/wake_models/induction/vortex_sheet.py +71 -75
  155. foxes/models/wake_models/ti/__init__.py +2 -2
  156. foxes/models/wake_models/ti/crespo_hernandez.py +5 -3
  157. foxes/models/wake_models/ti/iec_ti.py +6 -4
  158. foxes/models/wake_models/top_hat.py +58 -7
  159. foxes/models/wake_models/wind/__init__.py +6 -4
  160. foxes/models/wake_models/wind/bastankhah14.py +25 -7
  161. foxes/models/wake_models/wind/bastankhah16.py +35 -3
  162. foxes/models/wake_models/wind/jensen.py +15 -2
  163. foxes/models/wake_models/wind/turbopark.py +28 -2
  164. foxes/models/wake_superpositions/__init__.py +18 -9
  165. foxes/models/wake_superpositions/ti_linear.py +4 -4
  166. foxes/models/wake_superpositions/ti_max.py +4 -4
  167. foxes/models/wake_superpositions/ti_pow.py +4 -4
  168. foxes/models/wake_superpositions/ti_quadratic.py +4 -4
  169. foxes/models/wake_superpositions/wind_vector.py +257 -0
  170. foxes/models/wake_superpositions/ws_linear.py +9 -10
  171. foxes/models/wake_superpositions/ws_max.py +8 -8
  172. foxes/models/wake_superpositions/ws_pow.py +8 -8
  173. foxes/models/wake_superpositions/ws_product.py +4 -4
  174. foxes/models/wake_superpositions/ws_quadratic.py +8 -8
  175. foxes/output/__init__.py +21 -19
  176. foxes/output/farm_layout.py +4 -2
  177. foxes/output/farm_results_eval.py +19 -16
  178. foxes/output/flow_plots_2d/__init__.py +2 -2
  179. foxes/output/flow_plots_2d/flow_plots.py +18 -0
  180. foxes/output/flow_plots_2d/get_fig.py +5 -2
  181. foxes/output/output.py +6 -1
  182. foxes/output/results_writer.py +1 -1
  183. foxes/output/rose_plot.py +13 -3
  184. foxes/output/rotor_point_plots.py +3 -0
  185. foxes/output/seq_plugins/__init__.py +2 -2
  186. foxes/output/seq_plugins/seq_flow_ani_plugin.py +0 -3
  187. foxes/output/seq_plugins/seq_wake_debug_plugin.py +0 -1
  188. foxes/output/state_turbine_map.py +3 -0
  189. foxes/output/turbine_type_curves.py +10 -8
  190. foxes/utils/__init__.py +37 -19
  191. foxes/utils/abl/__init__.py +4 -4
  192. foxes/utils/cubic_roots.py +1 -1
  193. foxes/utils/data_book.py +4 -3
  194. foxes/utils/dict.py +49 -37
  195. foxes/utils/exec_python.py +5 -5
  196. foxes/utils/factory.py +3 -5
  197. foxes/utils/geom2d/__init__.py +7 -5
  198. foxes/utils/geopandas_utils.py +2 -2
  199. foxes/utils/pandas_utils.py +4 -3
  200. foxes/utils/tab_files.py +0 -1
  201. foxes/utils/weibull.py +28 -0
  202. foxes/utils/wrg_utils.py +3 -1
  203. foxes/utils/xarray_utils.py +9 -2
  204. foxes/variables.py +67 -9
  205. {foxes-1.3.dist-info → foxes-1.5.dist-info}/METADATA +34 -63
  206. foxes-1.5.dist-info/RECORD +328 -0
  207. {foxes-1.3.dist-info → foxes-1.5.dist-info}/WHEEL +1 -1
  208. tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +2 -3
  209. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +1 -1
  210. tests/1_verification/flappy_0_6/abl_states/flappy/run.py +0 -1
  211. tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +0 -1
  212. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +0 -2
  213. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +0 -1
  214. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +0 -1
  215. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +0 -1
  216. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +0 -1
  217. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +0 -1
  218. tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +0 -2
  219. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +0 -1
  220. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +0 -1
  221. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +0 -1
  222. foxes/input/states/field_data_nc.py +0 -847
  223. foxes/output/round.py +0 -10
  224. foxes/utils/pandas_helpers.py +0 -178
  225. foxes-1.3.dist-info/RECORD +0 -313
  226. {foxes-1.3.dist-info → foxes-1.5.dist-info}/entry_points.txt +0 -0
  227. {foxes-1.3.dist-info → foxes-1.5.dist-info/licenses}/LICENSE +0 -0
  228. {foxes-1.3.dist-info → foxes-1.5.dist-info}/top_level.txt +0 -0
foxes/input/yaml/dict.py CHANGED
@@ -75,13 +75,13 @@ def read_dict(
75
75
  print(*args, **kwargs)
76
76
 
77
77
  # set working directory:
78
- l = 0
78
+ ld = 0
79
79
  for c, d in zip(
80
80
  [FC.WORK_DIR, FC.INPUT_DIR, FC.OUTPUT_DIR], [work_dir, input_dir, output_dir]
81
81
  ):
82
82
  if d is not None:
83
83
  config[c] = d
84
- l = max(l, len(str(d)))
84
+ ld = max(ld, len(str(d)))
85
85
  _print("\n--------------------- Reading foxes parameter dict ---------------------")
86
86
  _print("Working directory :", config.work_dir)
87
87
  _print("Input directory :", config.input_dir)
@@ -95,9 +95,9 @@ def read_dict(
95
95
  else:
96
96
  states = algo.states
97
97
  else:
98
- assert (
99
- algo is None
100
- ), f"Cannot handle both the algo and the states argument, please drop one"
98
+ assert algo is None, (
99
+ "Cannot handle both the algo and the states argument, please drop one"
100
+ )
101
101
 
102
102
  # create model book:
103
103
  if mbook is None:
@@ -110,7 +110,7 @@ def read_dict(
110
110
  t = mbook.sources.get_item(s)
111
111
  c = mbook.base_classes.get_item(s)
112
112
  ms = [
113
- Dict(m, name=f"{mdict.name}.s{i}") for i, m in enumerate(mlst)
113
+ Dict(m, _name=f"{mdict.name}.s.{i}") for i, m in enumerate(mlst)
114
114
  ]
115
115
  for m in ms:
116
116
  mname = m.pop_item("name")
@@ -119,19 +119,16 @@ def read_dict(
119
119
  else:
120
120
  mbook = algo.mbook
121
121
  else:
122
- assert (
123
- algo is None
124
- ), f"Cannot handle both the algo and the mbook argument, please drop one"
122
+ assert algo is None, (
123
+ "Cannot handle both the algo and the mbook argument, please drop one"
124
+ )
125
125
 
126
126
  # create farm:
127
127
  if farm is None:
128
128
  if algo is None:
129
129
  _print("Creating wind farm")
130
130
  fdict = idict.get_item("wind_farm")
131
- lyts = [
132
- Dict(l, name=f"{fdict.name}.layout{i}")
133
- for i, l in enumerate(fdict.pop_item("layouts"))
134
- ]
131
+ lyts = fdict.pop_item("layouts")
135
132
  farm = WindFarm(**fdict)
136
133
  for lyt in lyts:
137
134
  add_fun = getattr(farm_layout, lyt.pop_item("function"))
@@ -141,9 +138,9 @@ def read_dict(
141
138
  else:
142
139
  farm = algo.farm
143
140
  else:
144
- assert (
145
- algo is None
146
- ), f"Cannot handle both the algo and the farm argument, please drop one"
141
+ assert algo is None, (
142
+ "Cannot handle both the algo and the farm argument, please drop one"
143
+ )
147
144
 
148
145
  # create engine:
149
146
  engine = None
@@ -251,6 +248,7 @@ def run_obj_function(
251
248
  fdict,
252
249
  algo,
253
250
  rlabels,
251
+ nofig=False,
254
252
  verbosity=None,
255
253
  ):
256
254
  """
@@ -266,6 +264,8 @@ def run_obj_function(
266
264
  The algorithm
267
265
  rlabels: dict
268
266
  Storage for result variables
267
+ nofig: bool
268
+ Do not show figures, overrules settings from fdict
269
269
  verbosity: int, optional
270
270
  The verbosity level, 0 = silent
271
271
 
@@ -310,9 +310,9 @@ def run_obj_function(
310
310
  results = f(*args, **fdict)
311
311
 
312
312
  # pyplot shortcuts:
313
- if plt_show:
313
+ if not nofig and plt_show:
314
314
  plt.show()
315
- if plt_close:
315
+ if not nofig and plt_close:
316
316
  results = None
317
317
  plt.close()
318
318
 
@@ -321,12 +321,12 @@ def run_obj_function(
321
321
 
322
322
  def _set_label(rlabels, k, r):
323
323
  if k not in ["", "none", "None", "_", "__"]:
324
- assert (
325
- k[0] == "$"
326
- ), f"Output {i} of type '{ocls}', function '{fname}': result labels must start with '$', got '{k}'"
327
- assert (
328
- "[" not in k and "]" not in k and "," not in k
329
- ), f"Output {i} of type '{ocls}', function '{fname}': result labels cannot contain '[' or ']' or comma, got '{k}'"
324
+ assert k[0] == "$", (
325
+ f"Output {i} of type '{ocls}', function '{fname}': result labels must start with '$', got '{k}'"
326
+ )
327
+ assert "[" not in k and "]" not in k and "," not in k, (
328
+ f"Output {i} of type '{ocls}', function '{fname}': result labels cannot contain '[' or ']' or comma, got '{k}'"
329
+ )
330
330
  _print(f" result label {k}: {type(r).__name__}")
331
331
  rlabels[k] = r
332
332
 
@@ -346,6 +346,7 @@ def run_outputs(
346
346
  point_results=None,
347
347
  extra_sig={},
348
348
  ret_rlabels=False,
349
+ nofig=False,
349
350
  verbosity=None,
350
351
  ):
351
352
  """
@@ -366,6 +367,8 @@ def run_outputs(
366
367
  arguments (key) with data (value)
367
368
  ret_rlabels: bool
368
369
  Flag for returning results variables
370
+ nofig: bool
371
+ Do not show figures, overrules settings from idict
369
372
  verbosity: int, optional
370
373
  The verbosity level, 0 = silent
371
374
 
@@ -387,24 +390,19 @@ def run_outputs(
387
390
  print(*args, **kwargs)
388
391
 
389
392
  out = []
390
- rlabels = Dict(name="result_labels")
393
+ rlabels = Dict(_name="result_labels")
391
394
  if "outputs" in idict:
392
- odicts = [
393
- Dict(odict, name=f"{idict.name}.output{i}")
394
- for i, odict in enumerate(idict["outputs"])
395
- ]
395
+ odicts = idict["outputs"]
396
396
 
397
397
  for i, d in enumerate(odicts):
398
398
  if "output_type" in d:
399
+ d["nofig"] = nofig
399
400
  ocls = d.pop_item("output_type")
400
401
  _print(f"\nRunning output {i}: {ocls}")
401
402
  d0 = dict(output_type=ocls)
402
403
  d0.update(d)
403
404
 
404
- flist = [
405
- Dict(f, name=f"{d.name}.function{j}")
406
- for j, f in enumerate(d.pop_item("functions"))
407
- ]
405
+ flist = d.pop_item("functions")
408
406
 
409
407
  o = get_output_obj(
410
408
  ocls, d, algo, farm_results, point_results, extra_sig=extra_sig
@@ -419,10 +417,7 @@ def run_outputs(
419
417
  o = _get_object(rlabels, ocls)
420
418
  d0 = dict(object=ocls)
421
419
  d0.update(d)
422
- flist = [
423
- Dict(f, name=f"{d.name}.function{j}")
424
- for j, f in enumerate(d.pop_item("functions"))
425
- ]
420
+ flist = d.pop_item("functions")
426
421
 
427
422
  else:
428
423
  raise KeyError(
@@ -431,7 +426,7 @@ def run_outputs(
431
426
 
432
427
  fres = []
433
428
  for fdict in flist:
434
- results = run_obj_function(o, fdict, algo, rlabels, verbosity)
429
+ results = run_obj_function(o, fdict, algo, rlabels, nofig, verbosity)
435
430
  fres.append(results)
436
431
  out.append((d0, fres))
437
432
 
@@ -441,7 +436,7 @@ def run_outputs(
441
436
  return out if not ret_rlabels else out, rlabels
442
437
 
443
438
 
444
- def run_dict(idict, *args, verbosity=None, **kwargs):
439
+ def run_dict(idict, *args, nofig=False, verbosity=None, **kwargs):
445
440
  """
446
441
  Runs foxes from dictionary input
447
442
 
@@ -451,6 +446,8 @@ def run_dict(idict, *args, verbosity=None, **kwargs):
451
446
  The input parameter dictionary
452
447
  args: tuple, optional
453
448
  Additional parameters for read_dict
449
+ nofig: bool
450
+ Do not show figures, overrules settings from idict
454
451
  verbosity: int, optional
455
452
  Force a verbosity level, 0 = silent, overrules
456
453
  settings from idict
@@ -480,7 +477,7 @@ def run_dict(idict, *args, verbosity=None, **kwargs):
480
477
  algo, engine = read_dict(idict, *args, verbosity=verbosity, **kwargs)
481
478
 
482
479
  # run farm calculation:
483
- rdict = idict.get_item("calc_farm", Dict(name=idict.name + ".calc_farm"))
480
+ rdict = idict.get_item("calc_farm", Dict(_name=idict.name + ".calc_farm"))
484
481
  if rdict.pop_item("run", True):
485
482
  _print("Running calc_farm")
486
483
  farm_results = algo.calc_farm(**rdict)
@@ -504,7 +501,11 @@ def run_dict(idict, *args, verbosity=None, **kwargs):
504
501
  out += (point_results,)
505
502
 
506
503
  # run outputs:
507
- out += (run_outputs(idict, algo, farm_results, point_results, verbosity=verbosity),)
504
+ out += (
505
+ run_outputs(
506
+ idict, algo, farm_results, point_results, nofig=nofig, verbosity=verbosity
507
+ ),
508
+ )
508
509
 
509
510
  # shutdown engine, if created above:
510
511
  if engine is not None:
@@ -1,5 +1,10 @@
1
- from .windio import foxes_windio, read_windio
2
- from .read_site import read_site
3
- from .read_fields import read_wind_resource_field
4
- from .read_farm import read_layout, read_turbine_types, read_farm
5
- from .read_attributes import read_attributes
1
+ from .windio import foxes_windio as foxes_windio
2
+ from .windio import read_windio as read_windio
3
+
4
+ from .read_farm import read_layout as read_layout
5
+ from .read_farm import read_turbine_types as read_turbine_types
6
+ from .read_farm import read_farm as read_farm
7
+
8
+ from .read_site import read_site as read_site
9
+ from .read_fields import read_wind_resource_field as read_wind_resource_field
10
+ from .read_attributes import read_attributes as read_attributes
@@ -1,5 +1,5 @@
1
1
  from foxes.utils import Dict
2
- from foxes.core import WakeModel, WakeFrame
2
+ from foxes.core import WakeModel, WakeDeflection
3
3
  import foxes.variables as FV
4
4
 
5
5
 
@@ -21,7 +21,7 @@ def _read_wind_deficit(
21
21
  "Bastankhah2016": "Bastankhah2016",
22
22
  "TurbOPark": "TurbOPark",
23
23
  },
24
- name="wind_def_map",
24
+ _name="wind_def_map",
25
25
  )
26
26
 
27
27
  ws_sup_dict = Dict(
@@ -29,16 +29,18 @@ def _read_wind_deficit(
29
29
  "Linear": "ws_linear",
30
30
  "Squared": "ws_quadratic",
31
31
  "Product": "ws_product",
32
+ "Vector": "vector",
32
33
  },
33
- name="ws_sup_dict",
34
+ _name="ws_sup_dict",
34
35
  )
35
36
  ws_sup_amb_dict = Dict(
36
37
  {
37
38
  "Linear": "ws_linear_amb",
38
39
  "Squared": "ws_quadratic_amb",
39
40
  "Product": "ws_product",
41
+ "Vector": "vector",
40
42
  },
41
- name="ws_sup_dict",
43
+ _name="ws_sup_dict",
42
44
  )
43
45
 
44
46
  wname = wind_deficit.pop_item("name")
@@ -49,7 +51,7 @@ def _read_wind_deficit(
49
51
  print(" Eff ws :", eff_ws)
50
52
  print(" Contents:", [k for k in wind_deficit.keys()])
51
53
  wind_def_dict = Dict(wmodel_type=wind_def_map[wname], induction=induction)
52
- kcoef = Dict(wind_deficit["wake_expansion_coefficient"], name="kcoef")
54
+ kcoef = Dict(wind_deficit["wake_expansion_coefficient"], _name="kcoef")
53
55
  ka = kcoef["k_a"]
54
56
  kb = kcoef.get_item("k_b", 0.0)
55
57
  amb_ti = kcoef.get_item("free_stream_ti", False)
@@ -100,7 +102,7 @@ def _read_turbulence(
100
102
  "CrespoHernandez": "CrespoHernandezTIWake",
101
103
  "IEC-TI-2019": "IECTIWake",
102
104
  },
103
- name="twake_def_map",
105
+ _name="twake_def_map",
104
106
  )
105
107
 
106
108
  ti_sup_dict = Dict(
@@ -108,7 +110,7 @@ def _read_turbulence(
108
110
  "Linear": "ti_linear",
109
111
  "Squared": "ti_quadratic",
110
112
  },
111
- name="ti_sup_dict",
113
+ _name="ti_sup_dict",
112
114
  )
113
115
 
114
116
  wname = turbulence_model.pop_item("name")
@@ -122,7 +124,7 @@ def _read_turbulence(
122
124
  tiwake_dict["opening_angle"] = None
123
125
  tiwake_dict["iec_type"] = "2019"
124
126
  if "wake_expansion_coefficient" in turbulence_model:
125
- kcoef = Dict(turbulence_model["wake_expansion_coefficient"], name="kcoef")
127
+ kcoef = Dict(turbulence_model["wake_expansion_coefficient"], _name="kcoef")
126
128
  ka = kcoef["k_a"]
127
129
  kb = kcoef.get_item("k_b", 0.0)
128
130
  amb_ti = kcoef.get_item("free_stream_ti", False)
@@ -156,7 +158,7 @@ def _read_blockage(blockage_model, induction, algo_dict, mbook, verbosity):
156
158
  "SelfSimilarityDeficit": "SelfSimilar",
157
159
  "SelfSimilarityDeficit2020": "SelfSimilar2020",
158
160
  },
159
- name="twake_def_map",
161
+ _name="twake_def_map",
160
162
  )
161
163
 
162
164
  wname = blockage_model.pop_item("name")
@@ -202,7 +204,7 @@ def _read_rotor_averaging(rotor_averaging, algo_dict, verbosity):
202
204
  elif background_averaging in ["none", "None", None]:
203
205
  algo_dict["rotor_model"] = None
204
206
  elif background_averaging == "grid":
205
- algo_dict["rotor_model"] = f"grid{nx*ny}"
207
+ algo_dict["rotor_model"] = f"grid{nx * ny}"
206
208
  else:
207
209
  algo_dict["rotor_model"] = background_averaging
208
210
 
@@ -215,7 +217,7 @@ def _read_rotor_averaging(rotor_averaging, algo_dict, verbosity):
215
217
  algo_dict["partial_wakes"] = "rotor_points"
216
218
  else:
217
219
  if grid == "grid":
218
- algo_dict["partial_wakes"] = f"grid{nx*ny}"
220
+ algo_dict["partial_wakes"] = f"grid{nx * ny}"
219
221
  else:
220
222
  algo_dict["partial_wakes"] = grid
221
223
  else:
@@ -230,10 +232,12 @@ def _read_deflection(deflection, induction, algo_dict, mbook, verbosity):
230
232
  """Reads deflection model"""
231
233
  defl_def_map = Dict(
232
234
  {
233
- "None": "RotorWD",
234
- "Batankhah2016": "YawedWakes",
235
+ "None": "NoDeflection",
236
+ "Batankhah2016": "Bastankhah2016Deflection",
237
+ "Jimenez": "JimenezDeflection",
238
+ "JimenezVector": "JimenezDeflection",
235
239
  },
236
- name="defl_def_map",
240
+ _name="defl_def_map",
237
241
  )
238
242
 
239
243
  wname = deflection.pop_item("name")
@@ -241,15 +245,24 @@ def _read_deflection(deflection, induction, algo_dict, mbook, verbosity):
241
245
  print(" Reading deflection_model")
242
246
  print(" Name:", wname)
243
247
  print(" Contents:", [k for k in deflection.keys()])
244
- indc_dict = Dict(wframe_type=defl_def_map[wname])
248
+ defl_dict = Dict(wdefl_type=defl_def_map[wname])
249
+ if wname == "Jimenez" and "rotate" not in defl_dict:
250
+ defl_dict["rotate"] = False
251
+ elif wname == "JimenezVector":
252
+ assert "rotate" not in defl_dict, (
253
+ f"Deflection model '{wname}' does not support 'rotate' parameter"
254
+ )
255
+ defl_dict["rotate"] = True
245
256
  try:
246
- mbook.wake_frames[wname] = WakeFrame.new(**indc_dict, induction=induction)
257
+ mbook.wake_deflections[wname] = WakeDeflection.new(
258
+ **defl_dict, induction=induction
259
+ )
247
260
  except TypeError:
248
- mbook.wake_frames[wname] = WakeFrame.new(**indc_dict)
261
+ mbook.wake_deflections[wname] = WakeDeflection.new(**defl_dict)
249
262
  if verbosity > 2:
250
- print(f" Created wake frame '{wname}':")
251
- print(" ", mbook.wake_frames[wname])
252
- algo_dict["wake_frame"] = wname
263
+ print(f" Created wake deflection '{wname}':")
264
+ print(" ", mbook.wake_deflections[wname])
265
+ algo_dict["wake_deflection"] = wname
253
266
 
254
267
 
255
268
  def _read_analysis(wio_ana, idict, mbook, verbosity):
@@ -260,7 +273,7 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
260
273
 
261
274
  # superposition:
262
275
  superposition = Dict(
263
- wio_ana["superposition_model"], name=wio_ana.name + ".superposition_model"
276
+ wio_ana["superposition_model"], _name=wio_ana.name + ".superposition_model"
264
277
  )
265
278
  if verbosity > 2:
266
279
  print(" Reading superposition_model")
@@ -272,7 +285,7 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
272
285
  "1D": "Betz",
273
286
  "Madsen": "Madsen",
274
287
  },
275
- name="induction mapping",
288
+ _name="induction mapping",
276
289
  )
277
290
  induction = imap[wio_ana.get_item("axial_induction_model", "1D")]
278
291
  if verbosity > 2:
@@ -284,7 +297,7 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
284
297
  )
285
298
  algo_dict = idict["algorithm"]
286
299
  wind_deficit = Dict(
287
- wio_ana[wake_model_key], name=wio_ana.name + "." + wake_model_key
300
+ wio_ana[wake_model_key], _name=wio_ana.name + "." + wake_model_key
288
301
  )
289
302
  ka, kb, amb_ti = _read_wind_deficit(
290
303
  wake_model_key,
@@ -298,7 +311,7 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
298
311
 
299
312
  # turbulence model:
300
313
  if "turbulence_model" in wio_ana:
301
- turbulence_model = Dict(wio_ana["turbulence_model"], name="turbulence_model")
314
+ turbulence_model = Dict(wio_ana["turbulence_model"], _name="turbulence_model")
302
315
  _read_turbulence(
303
316
  turbulence_model,
304
317
  superposition,
@@ -315,21 +328,21 @@ def _read_analysis(wio_ana, idict, mbook, verbosity):
315
328
 
316
329
  # blockage model:
317
330
  if "blockage_model" in wio_ana:
318
- blockage_model = Dict(wio_ana["blockage_model"], name="blockage_model")
331
+ blockage_model = Dict(wio_ana["blockage_model"], _name="blockage_model")
319
332
  _read_blockage(blockage_model, induction, algo_dict, mbook, verbosity)
320
333
  elif verbosity > 0:
321
334
  print("blockage_model not found, not using a turbine induction model")
322
335
 
323
336
  # rotor_averaging:
324
337
  if "rotor_averaging" in wio_ana:
325
- rotor_averaging = Dict(wio_ana["rotor_averaging"], name="rotor_averaging")
338
+ rotor_averaging = Dict(wio_ana["rotor_averaging"], _name="rotor_averaging")
326
339
  _read_rotor_averaging(rotor_averaging, algo_dict, verbosity)
327
340
  elif verbosity > 0:
328
341
  print("rotor_averaging not found, using default settings")
329
342
 
330
343
  # deflection:
331
344
  if "deflection_model" in wio_ana:
332
- deflection = Dict(wio_ana["deflection_model"], name="deflection_model")
345
+ deflection = Dict(wio_ana["deflection_model"], _name="deflection_model")
333
346
  _read_deflection(deflection, induction, algo_dict, mbook, verbosity)
334
347
  elif verbosity > 0:
335
348
  print("deflection_model not found, using default settings")
@@ -359,7 +372,7 @@ def read_attributes(wio_attrs, idict, mbook, verbosity=1):
359
372
 
360
373
  # read flow model:
361
374
  if "flow_model" in wio_attrs:
362
- flow_model = Dict(wio_attrs["flow_model"], name="flow_model")
375
+ flow_model = Dict(wio_attrs["flow_model"], _name="flow_model")
363
376
  fmname = flow_model.pop_item("name")
364
377
  if verbosity > 2:
365
378
  print(" Reading flow_model")
@@ -369,5 +382,5 @@ def read_attributes(wio_attrs, idict, mbook, verbosity=1):
369
382
  print(f"Running flow model 'foxes', overruling original choice '{fmname}'")
370
383
 
371
384
  # read analysis:
372
- wio_ana = Dict(wio_attrs["analysis"], name=wio_attrs.name + ".analysis")
385
+ wio_ana = Dict(wio_attrs["analysis"], _name=wio_attrs.name + ".analysis")
373
386
  _read_analysis(wio_ana, idict, mbook, verbosity)
@@ -38,7 +38,9 @@ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
38
38
  print(*args, **kwargs)
39
39
 
40
40
  if "turbine_types" not in wio_farm:
41
- wio_farm["turbine_types"] = {0: wio_farm["turbines"]}
41
+ wio_farm["turbine_types"] = Dict(
42
+ {0: wio_farm["turbines"]}, _name="turbine_types"
43
+ )
42
44
 
43
45
  ttypes = {}
44
46
  for k, wio_trbns in wio_farm["turbine_types"].items():
@@ -49,18 +51,18 @@ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
49
51
  _print(" Contents:", [k for k in wio_trbns.keys()], level=3)
50
52
 
51
53
  # read performance:
52
- performance = Dict(wio_trbns["performance"], name="performance")
54
+ performance = wio_trbns["performance"]
53
55
  _print(" Reading performance", level=3)
54
56
  _print(" Contents:", [k for k in performance.keys()], level=3)
55
57
 
56
58
  # P, ct data:
57
59
  if "power_curve" in performance:
58
- power_curve = Dict(performance["power_curve"], name="power_curve")
60
+ power_curve = performance["power_curve"]
59
61
  _print(" Reading power_curve", level=3)
60
62
  _print(" Contents:", [k for k in power_curve.keys()], level=3)
61
63
  P = power_curve["power_values"]
62
64
  ws_P = power_curve["power_wind_speeds"]
63
- ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
65
+ ct_curve = performance["Ct_curve"]
64
66
  _print(" Reading Ct_curve", level=3)
65
67
  _print(" Contents:", [k for k in ct_curve.keys()], level=3)
66
68
  ct = ct_curve["Ct_values"]
@@ -77,7 +79,7 @@ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
77
79
  return FV.REWS if wse == 1 else (FV.REWS2 if wse == 2 else FV.REWS3)
78
80
 
79
81
  _print(f" Creating model '{tname}'", level=3)
80
- _print(f" Turbine type class: PCtFomTwo", level=3)
82
+ _print(" Turbine type class: PCtFomTwo", level=3)
81
83
  mbook.turbine_types[tname] = TurbineType.new(
82
84
  ttype_type="PCtFromTwo",
83
85
  data_source_P=data_P,
@@ -96,12 +98,12 @@ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
96
98
 
97
99
  # P, ct data:
98
100
  elif "Cp_curve" in performance:
99
- cp_curve = Dict(performance["Cp_curve"], name="Cp_curve")
101
+ cp_curve = performance["Cp_curve"]
100
102
  _print(" Reading Cp_curve", level=3)
101
103
  _print(" Contents:", [k for k in cp_curve.keys()], level=3)
102
104
  cp = cp_curve["Cp_values"]
103
105
  ws_cp = cp_curve["Cp_wind_speeds"]
104
- ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
106
+ ct_curve = performance["Ct_curve"]
105
107
  _print(" Reading Ct_curve", level=3)
106
108
  _print(" Contents:", [k for k in ct_curve.keys()], level=3)
107
109
  ct = ct_curve["Ct_values"]
@@ -111,7 +113,7 @@ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
111
113
  data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
112
114
 
113
115
  _print(f" Creating model '{tname}'", level=3)
114
- _print(f" Turbine type class: CpCtFromTwo", level=3)
116
+ _print(" Turbine type class: CpCtFromTwo", level=3)
115
117
  mbook.turbine_types[tname] = TurbineType.new(
116
118
  ttype_type="CpCtFromTwo",
117
119
  data_source_cp=data_cp,
@@ -126,7 +128,7 @@ def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
126
128
  _print(" ", mbook.turbine_types[tname], level=3)
127
129
 
128
130
  else:
129
- raise KeyError(f"Expecting either 'power_curve' or 'Cp_curve'")
131
+ raise KeyError("Expecting either 'power_curve' or 'Cp_curve'")
130
132
 
131
133
  return ttypes
132
134
 
@@ -154,10 +156,10 @@ def read_layout(lname, ldict, farm, ttypes, verbosity=1):
154
156
  """
155
157
  if verbosity > 2:
156
158
  print(f" Reading '{lname}'")
157
- cdict = Dict(ldict["coordinates"], name="coordinates")
159
+ cdict = ldict["coordinates"]
158
160
  tmap = ldict.get_item("turbine_types", None)
159
161
  if verbosity > 2:
160
- print(f" Turbine type map:", tmap)
162
+ print(" Turbine type map:", tmap)
161
163
  for i, xy in enumerate(zip(cdict["x"], cdict["y"])):
162
164
  tt = ttypes[tmap[i] if tmap is not None else 0]
163
165
  farm.add_turbine(
@@ -187,7 +189,7 @@ def read_farm(wio_dict, mbook, verbosity):
187
189
  :group: input.yaml.windio
188
190
 
189
191
  """
190
- wio_farm = Dict(wio_dict["wind_farm"], name=wio_dict.name + ".wind_farm")
192
+ wio_farm = wio_dict["wind_farm"]
191
193
  if verbosity > 1:
192
194
  print("Reading wind farm")
193
195
  print(" Name:", wio_farm.pop_item("name", None))
@@ -209,10 +211,10 @@ def read_farm(wio_dict, mbook, verbosity):
209
211
  farm = WindFarm()
210
212
  wfarm = wio_farm["layouts"]
211
213
  if isinstance(wfarm, dict):
212
- layouts = Dict(wfarm, name=wio_farm.name + ".layouts")
214
+ layouts = Dict(wfarm, _name=wio_farm.name + ".layouts")
213
215
  else:
214
- layouts = {str(i): l for i, l in enumerate(wfarm)}
215
- layouts = Dict(layouts, name=wio_farm.name + ".layouts")
216
+ layouts = {str(i): lf for i, lf in enumerate(wfarm)}
217
+ layouts = Dict(layouts, _name=wio_farm.name + ".layouts")
216
218
  if verbosity > 2:
217
219
  print(" Reading layouts")
218
220
  print(" Contents:", [k for k in layouts.keys()])
@@ -22,6 +22,8 @@ wio2foxes = {
22
22
  "LMO": FV.MOL,
23
23
  "z0": FV.Z0,
24
24
  "reference_height": FV.H,
25
+ "weibull_a": FV.WEIBULL_A,
26
+ "weibull_k": FV.WEIBULL_k,
25
27
  }
26
28
 
27
29
  """ Mapping from foxes to windio variables
@@ -134,8 +136,6 @@ def read_wind_resource_field(
134
136
 
135
137
  """
136
138
  if name in [
137
- "weibull_a",
138
- "weibull_k",
139
139
  "potential_temperature",
140
140
  "friction_velocity",
141
141
  "k",
@@ -178,6 +178,8 @@ def read_wind_resource_field(
178
178
  "LMO",
179
179
  "z0",
180
180
  "reference_height",
181
+ "weibull_a",
182
+ "weibull_k",
181
183
  ] and _read_multi_dimensional_data(name, wio_data, fields, dims):
182
184
  return True
183
185