foxes 0.8.2__py3-none-any.whl → 1.1.0.2__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (215) hide show
  1. docs/source/conf.py +353 -0
  2. examples/abl_states/run.py +160 -0
  3. examples/compare_rotors_pwakes/run.py +217 -0
  4. examples/compare_wakes/run.py +241 -0
  5. examples/dyn_wakes/run.py +311 -0
  6. examples/field_data_nc/run.py +121 -0
  7. examples/induction/run.py +201 -0
  8. examples/multi_height/run.py +113 -0
  9. examples/power_mask/run.py +249 -0
  10. examples/random_timeseries/run.py +210 -0
  11. examples/scan_row/run.py +193 -0
  12. examples/sector_management/run.py +162 -0
  13. examples/sequential/run.py +209 -0
  14. examples/single_state/run.py +201 -0
  15. examples/states_lookup_table/run.py +137 -0
  16. examples/streamline_wakes/run.py +138 -0
  17. examples/tab_file/run.py +142 -0
  18. examples/timelines/run.py +267 -0
  19. examples/timeseries/run.py +190 -0
  20. examples/timeseries_slurm/run.py +185 -0
  21. examples/wind_rose/run.py +141 -0
  22. examples/windio/run.py +29 -0
  23. examples/yawed_wake/run.py +196 -0
  24. foxes/__init__.py +4 -8
  25. foxes/algorithms/__init__.py +1 -1
  26. foxes/algorithms/downwind/downwind.py +247 -111
  27. foxes/algorithms/downwind/models/farm_wakes_calc.py +12 -7
  28. foxes/algorithms/downwind/models/init_farm_data.py +2 -2
  29. foxes/algorithms/downwind/models/point_wakes_calc.py +6 -7
  30. foxes/algorithms/downwind/models/reorder_farm_output.py +1 -2
  31. foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
  32. foxes/algorithms/downwind/models/set_amb_point_results.py +5 -3
  33. foxes/algorithms/iterative/iterative.py +74 -34
  34. foxes/algorithms/iterative/models/farm_wakes_calc.py +12 -7
  35. foxes/algorithms/iterative/models/urelax.py +3 -3
  36. foxes/algorithms/sequential/models/plugin.py +5 -5
  37. foxes/algorithms/sequential/models/seq_state.py +1 -1
  38. foxes/algorithms/sequential/sequential.py +126 -255
  39. foxes/constants.py +22 -7
  40. foxes/core/__init__.py +1 -0
  41. foxes/core/algorithm.py +632 -147
  42. foxes/core/data.py +252 -20
  43. foxes/core/data_calc_model.py +15 -291
  44. foxes/core/engine.py +640 -0
  45. foxes/core/farm_controller.py +38 -10
  46. foxes/core/farm_data_model.py +16 -1
  47. foxes/core/ground_model.py +2 -2
  48. foxes/core/model.py +249 -182
  49. foxes/core/partial_wakes_model.py +1 -1
  50. foxes/core/point_data_model.py +17 -2
  51. foxes/core/rotor_model.py +27 -21
  52. foxes/core/states.py +17 -1
  53. foxes/core/turbine_type.py +28 -0
  54. foxes/core/wake_frame.py +30 -34
  55. foxes/core/wake_model.py +5 -5
  56. foxes/core/wake_superposition.py +1 -1
  57. foxes/data/windio/windio_5turbines_timeseries.yaml +31 -15
  58. foxes/engines/__init__.py +17 -0
  59. foxes/engines/dask.py +982 -0
  60. foxes/engines/default.py +75 -0
  61. foxes/engines/futures.py +72 -0
  62. foxes/engines/mpi.py +38 -0
  63. foxes/engines/multiprocess.py +71 -0
  64. foxes/engines/numpy.py +167 -0
  65. foxes/engines/pool.py +249 -0
  66. foxes/engines/ray.py +79 -0
  67. foxes/engines/single.py +141 -0
  68. foxes/input/farm_layout/__init__.py +1 -0
  69. foxes/input/farm_layout/from_csv.py +4 -0
  70. foxes/input/farm_layout/from_json.py +2 -2
  71. foxes/input/farm_layout/grid.py +2 -2
  72. foxes/input/farm_layout/ring.py +65 -0
  73. foxes/input/farm_layout/row.py +2 -2
  74. foxes/input/states/__init__.py +7 -0
  75. foxes/input/states/create/random_abl_states.py +1 -1
  76. foxes/input/states/field_data_nc.py +158 -33
  77. foxes/input/states/multi_height.py +128 -14
  78. foxes/input/states/one_point_flow.py +577 -0
  79. foxes/input/states/scan_ws.py +74 -3
  80. foxes/input/states/single.py +1 -1
  81. foxes/input/states/slice_data_nc.py +681 -0
  82. foxes/input/states/states_table.py +204 -35
  83. foxes/input/windio/__init__.py +2 -2
  84. foxes/input/windio/get_states.py +44 -23
  85. foxes/input/windio/read_attributes.py +48 -17
  86. foxes/input/windio/read_farm.py +116 -102
  87. foxes/input/windio/read_fields.py +16 -6
  88. foxes/input/windio/read_outputs.py +71 -24
  89. foxes/input/windio/runner.py +31 -17
  90. foxes/input/windio/windio.py +41 -23
  91. foxes/models/farm_models/turbine2farm.py +1 -1
  92. foxes/models/ground_models/wake_mirror.py +10 -6
  93. foxes/models/model_book.py +58 -20
  94. foxes/models/partial_wakes/axiwake.py +3 -3
  95. foxes/models/partial_wakes/rotor_points.py +3 -3
  96. foxes/models/partial_wakes/top_hat.py +2 -2
  97. foxes/models/point_models/set_uniform_data.py +1 -1
  98. foxes/models/point_models/tke2ti.py +1 -1
  99. foxes/models/point_models/wake_deltas.py +1 -1
  100. foxes/models/rotor_models/centre.py +4 -0
  101. foxes/models/rotor_models/grid.py +24 -25
  102. foxes/models/rotor_models/levels.py +4 -5
  103. foxes/models/turbine_models/calculator.py +4 -6
  104. foxes/models/turbine_models/kTI_model.py +22 -6
  105. foxes/models/turbine_models/lookup_table.py +30 -4
  106. foxes/models/turbine_models/rotor_centre_calc.py +4 -3
  107. foxes/models/turbine_models/set_farm_vars.py +103 -34
  108. foxes/models/turbine_types/PCt_file.py +27 -3
  109. foxes/models/turbine_types/PCt_from_two.py +27 -3
  110. foxes/models/turbine_types/TBL_file.py +80 -0
  111. foxes/models/turbine_types/__init__.py +2 -0
  112. foxes/models/turbine_types/lookup.py +316 -0
  113. foxes/models/turbine_types/null_type.py +51 -1
  114. foxes/models/turbine_types/wsrho2PCt_from_two.py +29 -5
  115. foxes/models/turbine_types/wsti2PCt_from_two.py +31 -7
  116. foxes/models/vertical_profiles/__init__.py +1 -1
  117. foxes/models/vertical_profiles/data_profile.py +1 -1
  118. foxes/models/wake_frames/__init__.py +1 -0
  119. foxes/models/wake_frames/dynamic_wakes.py +424 -0
  120. foxes/models/wake_frames/farm_order.py +25 -5
  121. foxes/models/wake_frames/rotor_wd.py +6 -4
  122. foxes/models/wake_frames/seq_dynamic_wakes.py +61 -74
  123. foxes/models/wake_frames/streamlines.py +21 -22
  124. foxes/models/wake_frames/timelines.py +330 -129
  125. foxes/models/wake_frames/yawed_wakes.py +7 -4
  126. foxes/models/wake_models/dist_sliced.py +2 -4
  127. foxes/models/wake_models/induction/rankine_half_body.py +5 -5
  128. foxes/models/wake_models/induction/rathmann.py +78 -24
  129. foxes/models/wake_models/induction/self_similar.py +78 -28
  130. foxes/models/wake_models/induction/vortex_sheet.py +86 -48
  131. foxes/models/wake_models/ti/crespo_hernandez.py +6 -4
  132. foxes/models/wake_models/ti/iec_ti.py +40 -21
  133. foxes/models/wake_models/top_hat.py +1 -1
  134. foxes/models/wake_models/wind/bastankhah14.py +8 -6
  135. foxes/models/wake_models/wind/bastankhah16.py +17 -16
  136. foxes/models/wake_models/wind/jensen.py +4 -3
  137. foxes/models/wake_models/wind/turbopark.py +16 -13
  138. foxes/models/wake_superpositions/ti_linear.py +1 -1
  139. foxes/models/wake_superpositions/ti_max.py +1 -1
  140. foxes/models/wake_superpositions/ti_pow.py +1 -1
  141. foxes/models/wake_superpositions/ti_quadratic.py +1 -1
  142. foxes/models/wake_superpositions/ws_linear.py +8 -7
  143. foxes/models/wake_superpositions/ws_max.py +8 -7
  144. foxes/models/wake_superpositions/ws_pow.py +8 -7
  145. foxes/models/wake_superpositions/ws_product.py +5 -5
  146. foxes/models/wake_superpositions/ws_quadratic.py +8 -7
  147. foxes/output/__init__.py +4 -1
  148. foxes/output/farm_layout.py +16 -12
  149. foxes/output/farm_results_eval.py +1 -1
  150. foxes/output/flow_plots_2d/__init__.py +0 -1
  151. foxes/output/flow_plots_2d/flow_plots.py +70 -30
  152. foxes/output/grids.py +92 -22
  153. foxes/output/results_writer.py +2 -2
  154. foxes/output/rose_plot.py +3 -3
  155. foxes/output/seq_plugins/__init__.py +2 -0
  156. foxes/output/{flow_plots_2d → seq_plugins}/seq_flow_ani_plugin.py +64 -22
  157. foxes/output/seq_plugins/seq_wake_debug_plugin.py +145 -0
  158. foxes/output/slice_data.py +131 -111
  159. foxes/output/state_turbine_map.py +19 -14
  160. foxes/output/state_turbine_table.py +19 -19
  161. foxes/utils/__init__.py +1 -1
  162. foxes/utils/abl/neutral.py +2 -2
  163. foxes/utils/abl/stable.py +2 -2
  164. foxes/utils/abl/unstable.py +2 -2
  165. foxes/utils/data_book.py +1 -1
  166. foxes/utils/dev_utils.py +42 -0
  167. foxes/utils/dict.py +24 -1
  168. foxes/utils/exec_python.py +1 -1
  169. foxes/utils/factory.py +176 -53
  170. foxes/utils/geom2d/circle.py +1 -1
  171. foxes/utils/geom2d/polygon.py +1 -1
  172. foxes/utils/geopandas_utils.py +2 -2
  173. foxes/utils/load.py +2 -2
  174. foxes/utils/pandas_helpers.py +3 -2
  175. foxes/utils/wind_dir.py +0 -2
  176. foxes/utils/xarray_utils.py +24 -14
  177. foxes/variables.py +39 -2
  178. {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/METADATA +75 -33
  179. foxes-1.1.0.2.dist-info/RECORD +309 -0
  180. {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/WHEEL +1 -1
  181. foxes-1.1.0.2.dist-info/top_level.txt +4 -0
  182. tests/0_consistency/iterative/test_iterative.py +92 -0
  183. tests/0_consistency/partial_wakes/test_partial_wakes.py +90 -0
  184. tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +85 -0
  185. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +103 -0
  186. tests/1_verification/flappy_0_6/abl_states/flappy/run.py +85 -0
  187. tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +87 -0
  188. tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +82 -0
  189. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +82 -0
  190. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/flappy/run.py +92 -0
  191. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +93 -0
  192. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/flappy/run.py +92 -0
  193. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +96 -0
  194. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/flappy/run.py +94 -0
  195. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +122 -0
  196. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/flappy/run.py +94 -0
  197. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +122 -0
  198. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/flappy/run.py +92 -0
  199. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +93 -0
  200. tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +85 -0
  201. tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +130 -0
  202. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/flappy/run.py +96 -0
  203. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +116 -0
  204. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +93 -0
  205. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +99 -0
  206. tests/3_examples/test_examples.py +34 -0
  207. foxes/VERSION +0 -1
  208. foxes/output/flow_plots_2d.py +0 -0
  209. foxes/utils/geopandas_helpers.py +0 -294
  210. foxes/utils/runners/__init__.py +0 -1
  211. foxes/utils/runners/runners.py +0 -280
  212. foxes-0.8.2.dist-info/RECORD +0 -247
  213. foxes-0.8.2.dist-info/top_level.txt +0 -1
  214. foxes-0.8.2.dist-info/zip-safe +0 -1
  215. {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/LICENSE +0 -0
foxes/core/rotor_model.py CHANGED
@@ -27,13 +27,13 @@ class RotorModel(FarmDataModel):
27
27
 
28
28
  """
29
29
 
30
- def __init__(self, calc_vars):
30
+ def __init__(self, calc_vars=None):
31
31
  """
32
32
  Constructor.
33
33
 
34
34
  Parameters
35
35
  ----------
36
- calc_vars: list of str
36
+ calc_vars: list of str, optional
37
37
  The variables that are calculated by the model
38
38
  (Their ambients are added automatically)
39
39
 
@@ -41,10 +41,6 @@ class RotorModel(FarmDataModel):
41
41
  super().__init__()
42
42
  self.calc_vars = calc_vars
43
43
 
44
- self.RPOINTS = self.var("rpoints")
45
- self.RWEIGHTS = self.var("rweights")
46
- self.AMBRES = self.var("amb_res")
47
-
48
44
  def output_farm_vars(self, algo):
49
45
  """
50
46
  The variables which are being modified by the model.
@@ -60,12 +56,21 @@ class RotorModel(FarmDataModel):
60
56
  The output variable names
61
57
 
62
58
  """
63
- return list(
64
- set(
65
- self.calc_vars
66
- + [FV.var2amb[v] for v in self.calc_vars if v in FV.var2amb]
67
- )
68
- )
59
+ if self.calc_vars is None:
60
+ vrs = algo.states.output_point_vars(algo)
61
+ if FV.WS in vrs:
62
+ self.calc_vars = [FV.REWS] + [v for v in vrs if v != FV.WS]
63
+ else:
64
+ self.calc_vars = vrs
65
+
66
+ if algo.farm_controller.needs_rews2() and FV.REWS2 not in self.calc_vars:
67
+ self.calc_vars.append(FV.REWS2)
68
+ if algo.farm_controller.needs_rews3() and FV.REWS3 not in self.calc_vars:
69
+ self.calc_vars.append(FV.REWS3)
70
+
71
+ self.calc_vars = sorted(self.calc_vars)
72
+
73
+ return self.calc_vars
69
74
 
70
75
  @abstractmethod
71
76
  def n_rotor_points(self):
@@ -207,6 +212,10 @@ class RotorModel(FarmDataModel):
207
212
  variables after calculation
208
213
 
209
214
  """
215
+ for v in [FV.REWS2, FV.REWS3]:
216
+ if v in fdata and v not in self.calc_vars:
217
+ self.calc_vars.append(v)
218
+
210
219
  uvp = None
211
220
  uv = None
212
221
  if (
@@ -348,11 +357,11 @@ class RotorModel(FarmDataModel):
348
357
  """
349
358
 
350
359
  if rpoints is None:
351
- rpoints = mdata.get(self.RPOINTS, self.get_rotor_points(algo, mdata, fdata))
360
+ rpoints = mdata.get(
361
+ FC.ROTOR_POINTS, self.get_rotor_points(algo, mdata, fdata)
362
+ )
352
363
  if store_rpoints:
353
- mdata[self.RPOINTS] = rpoints
354
- mdata.dims[self.RPOINTS] = (FC.STATE, FC.TURBINE, FC.TPOINT, FC.XYH)
355
- self.data_to_store(self.RPOINTS, algo, mdata)
364
+ algo.add_to_chunk_store(FC.ROTOR_POINTS, rpoints, mdata=mdata)
356
365
 
357
366
  if downwind_index is not None:
358
367
  rpoints = rpoints[:, downwind_index, None]
@@ -360,9 +369,7 @@ class RotorModel(FarmDataModel):
360
369
  if weights is None:
361
370
  weights = mdata.get(FC.TWEIGHTS, self.rotor_point_weights())
362
371
  if store_rweights:
363
- mdata[self.RWEIGHTS] = weights
364
- mdata.dims[self.RWEIGHTS] = (FC.TPOINT,)
365
- self.data_to_store(self.RWEIGHTS, algo, mdata)
372
+ algo.add_to_chunk_store(FC.ROTOR_WEIGHTS, weights, mdata=mdata)
366
373
 
367
374
  tdata = TData.from_tpoints(rpoints, weights)
368
375
  svars = algo.states.output_point_vars(algo)
@@ -377,8 +384,7 @@ class RotorModel(FarmDataModel):
377
384
  tdata.update(sres)
378
385
 
379
386
  if store_amb_res:
380
- mdata[self.AMBRES] = sres.copy()
381
- self.data_to_store(self.AMBRES, algo, mdata)
387
+ algo.add_to_chunk_store(FC.AMB_ROTOR_RES, sres.copy(), mdata=mdata)
382
388
 
383
389
  self.eval_rpoint_results(
384
390
  algo,
foxes/core/states.py CHANGED
@@ -61,6 +61,22 @@ class States(PointDataModel):
61
61
  """
62
62
  pass
63
63
 
64
+ def reset(self, algo=None, states_sel=None, states_loc=None, verbosity=0):
65
+ """
66
+ Reset the states, optionally select states
67
+
68
+ Parameters
69
+ ----------
70
+ states_sel: slice or range or list of int, optional
71
+ States subset selection
72
+ states_loc: list, optional
73
+ State index selection via pandas loc function
74
+ verbosity: int
75
+ The verbosity level, 0 = silent
76
+
77
+ """
78
+ raise NotImplementedError(f"States '{self.name}': Reset is not implemented")
79
+
64
80
  def load_data(self, algo, verbosity=0):
65
81
  """
66
82
  Load and/or create all model data that is subject to chunking.
@@ -279,7 +295,7 @@ class ExtendedStates(States):
279
295
  return self.states.output_point_vars(algo)
280
296
 
281
297
  def calculate(self, algo, mdata, fdata, tdata):
282
- """ "
298
+ """
283
299
  The main model calculation.
284
300
 
285
301
  This function is executed on a single chunk of data,
@@ -1,3 +1,5 @@
1
+ from abc import abstractmethod
2
+
1
3
  import foxes.constants as FC
2
4
  from foxes.utils import all_subclasses
3
5
 
@@ -64,6 +66,32 @@ class TurbineType(TurbineModel):
64
66
  a = f"D={self.D}, H={self.H}, P_nominal={self.P_nominal}, P_unit={self.P_unit}"
65
67
  return f"{type(self).__name__}({a})"
66
68
 
69
+ @abstractmethod
70
+ def needs_rews2(self):
71
+ """
72
+ Returns flag for requiring REWS2 variable
73
+
74
+ Returns
75
+ -------
76
+ flag: bool
77
+ True if REWS2 is required
78
+
79
+ """
80
+ pass
81
+
82
+ @abstractmethod
83
+ def needs_rews3(self):
84
+ """
85
+ Returns flag for requiring REWS3 variable
86
+
87
+ Returns
88
+ -------
89
+ flag: bool
90
+ True if REWS3 is required
91
+
92
+ """
93
+ pass
94
+
67
95
  def modify_cutin(self, modify_ct, modify_P):
68
96
  """
69
97
  Modify the data such that a discontinuity
foxes/core/wake_frame.py CHANGED
@@ -6,7 +6,7 @@ from foxes.utils import all_subclasses
6
6
  import foxes.constants as FC
7
7
  import foxes.variables as FV
8
8
 
9
- from .data import MData, FData, TData
9
+ from .data import TData
10
10
  from .model import Model
11
11
 
12
12
 
@@ -21,13 +21,31 @@ class WakeFrame(Model):
21
21
  They are also responsible for the calculation of
22
22
  the turbine evaluation order.
23
23
 
24
+ Attributes
25
+ ----------
26
+ max_length_km: float
27
+ The maximal wake length in km
28
+
24
29
  :group: core
25
30
 
26
31
  """
27
32
 
33
+ def __init__(self, max_length_km=3e4):
34
+ """
35
+ Constructor.
36
+
37
+ Parameters
38
+ ----------
39
+ max_length_km: float
40
+ The maximal wake length in km
41
+
42
+ """
43
+ super().__init__()
44
+ self.max_length_km = max_length_km
45
+
28
46
  @abstractmethod
29
47
  def calc_order(self, algo, mdata, fdata):
30
- """ "
48
+ """
31
49
  Calculates the order of turbine evaluation.
32
50
 
33
51
  This function is executed on a single chunk of data,
@@ -74,7 +92,7 @@ class WakeFrame(Model):
74
92
  The target point data
75
93
  downwind_index: int
76
94
  The index of the wake causing turbine
77
- in the downwnd order
95
+ in the downwind order
78
96
 
79
97
  Returns
80
98
  -------
@@ -94,7 +112,6 @@ class WakeFrame(Model):
94
112
  tdata,
95
113
  target,
96
114
  states0=None,
97
- upcast=False,
98
115
  ):
99
116
  """
100
117
  Return data that is required for computing the
@@ -118,47 +135,26 @@ class WakeFrame(Model):
118
135
  FC.STATE_TARGET_TPOINT
119
136
  states0: numpy.ndarray, optional
120
137
  The states of wake creation
121
- upcast: bool
122
- Flag for ensuring targets dimension,
123
- otherwise dimension 1 is entered
124
138
 
125
139
  Returns
126
140
  -------
127
141
  data: numpy.ndarray
128
142
  Data for wake modelling, shape:
129
143
  (n_states, n_turbines) or (n_states, n_target)
130
- dims: tuple
131
- The data dimensions
132
144
 
133
145
  """
134
- n_states = fdata.n_states
135
146
  s = np.s_[:] if states0 is None else states0
136
147
 
137
- if not upcast:
138
- if target == FC.STATE_TARGET_TPOINT:
139
- out = fdata[variable][s, downwind_index, None, None]
140
- dims = (FC.STATE, 1, 1)
141
- else:
142
- out = fdata[variable][s, downwind_index, None]
143
- dims = (FC.STATE, 1)
144
- elif target == FC.STATE_TURBINE:
145
- out = np.zeros((n_states, fdata.n_turbines), dtype=FC.DTYPE)
146
- out[:] = fdata[variable][s, downwind_index, None]
147
- dims = (FC.STATE, FC.TURBINE)
148
- elif target == FC.STATE_TARGET:
149
- out = np.zeros((n_states, tdata.n_targets), dtype=FC.DTYPE)
150
- out[:] = fdata[variable][s, downwind_index, None]
151
- dims = (FC.STATE, FC.TARGET)
152
- elif target == FC.STATE_TARGET_TPOINT:
153
- out = np.zeros((n_states, tdata.n_targets, tdata.n_tpoints), dtype=FC.DTYPE)
154
- out[:] = fdata[variable][s, downwind_index, None, None]
155
- dims = (FC.STATE, FC.TARGET, FC.TPOINT)
148
+ if target == FC.STATE_TARGET_TPOINT:
149
+ out = fdata[variable][s, downwind_index, None, None]
150
+ elif target in [FC.STATE_TURBINE, FC.STATE_TARGET]:
151
+ out = fdata[variable][s, downwind_index, None]
156
152
  else:
157
153
  raise ValueError(
158
- f"Unsupported target '{target}', expcting '{FC.STATE_TURBINE}', '{FC.STATE_TARGET}', {FC.STATE_TARGET_TPOINT}"
154
+ f"Unkown target '{target}', choices are {FC.STATE_TURBINE}, {FC.STATE_TARGET}, {FC.STATE_TARGET_TPOINT}"
159
155
  )
160
156
 
161
- return out, dims
157
+ return out
162
158
 
163
159
  def get_centreline_points(self, algo, mdata, fdata, downwind_index, x):
164
160
  """
@@ -241,7 +237,7 @@ class WakeFrame(Model):
241
237
 
242
238
  # calc evaluation points:
243
239
  xmin = 0.0
244
- xmax = np.nanmax(x)
240
+ xmax = min(np.nanmax(x), self.max_length_km * 1e3)
245
241
  n_steps = int((xmax - xmin) / dx)
246
242
  if xmin + n_steps * dx < xmax:
247
243
  n_steps += 1
@@ -262,7 +258,7 @@ class WakeFrame(Model):
262
258
  res = algo.states.calculate(algo, mdata, fdata, tdata)
263
259
  tdata.update(res)
264
260
  amb2var = algo.get_model("SetAmbPointResults")()
265
- amb2var.initialize(algo, verbosity=0)
261
+ amb2var.initialize(algo, verbosity=0, force=True)
266
262
  res = amb2var.calculate(algo, mdata, fdata, tdata)
267
263
  tdata.update(res)
268
264
  del res, amb2var
@@ -277,7 +273,7 @@ class WakeFrame(Model):
277
273
  # calc wakes:
278
274
  if not ambient:
279
275
  wcalc = algo.get_model("PointWakesCalculation")(wake_models=wake_models)
280
- wcalc.initialize(algo, verbosity=0)
276
+ wcalc.initialize(algo, verbosity=0, force=True)
281
277
  wsrc = downwind_index if self_wake else None
282
278
  res = wcalc.calculate(algo, mdata, fdata, tdata, downwind_index=wsrc)
283
279
  tdata.update(res)
foxes/core/wake_model.py CHANGED
@@ -81,7 +81,7 @@ class WakeModel(Model):
81
81
  The target point data
82
82
  downwind_index: int
83
83
  The index of the wake causing turbine
84
- in the downwnd order
84
+ in the downwind order
85
85
  wake_coos: numpy.ndarray
86
86
  The wake frame coordinates of the evaluation
87
87
  points, shape: (n_states, n_targets, n_tpoints, 3)
@@ -304,9 +304,9 @@ class WakeK(Model):
304
304
  The k array as returned by get_data
305
305
 
306
306
  """
307
- if self._k is not None:
308
- setattr(self, self.k_var, self._k)
309
- elif self._ka is not None or self._kb is not None:
307
+ sel = kwargs.pop("selection", None)
308
+ setattr(self, self.k_var, self._k)
309
+ if self._ka is not None or self._kb is not None:
310
310
  if self.ti_var == FV.TI and ti is not None:
311
311
  pass
312
312
  elif self.ti_var == FV.AMB_TI and amb_ti is not None:
@@ -316,6 +316,6 @@ class WakeK(Model):
316
316
  kb = 0 if self._kb is None else self._kb
317
317
  setattr(self, self.k_var, self._ka * ti + kb)
318
318
 
319
- k = self.get_data(self.k_var, *args, lookup=lookup_k, **kwargs)
319
+ k = self.get_data(self.k_var, *args, lookup=lookup_k, selection=sel, **kwargs)
320
320
  setattr(self, self.k_var, None)
321
321
  return k
@@ -45,7 +45,7 @@ class WakeSuperposition(Model):
45
45
  The target point data
46
46
  downwind_index: int
47
47
  The index of the wake causing turbine
48
- in the downwnd order
48
+ in the downwind order
49
49
  st_sel: numpy.ndarray of bool
50
50
  The selection of targets, shape: (n_states, n_targets)
51
51
  variable: str
@@ -14,10 +14,9 @@ site:
14
14
  wind_farm:
15
15
  name: One row with 5 turbines
16
16
  layouts:
17
- initial_layout:
18
- coordinates:
19
- x: [0, 0, 0, 0, 0]
20
- y: [0, 600, 1150, 1730, 2400]
17
+ - coordinates:
18
+ x: [0, 0, 0, 0, 0]
19
+ y: [0, 600, 1150, 1730, 2400]
21
20
  turbines: !include DTU_10MW_turbine.yaml
22
21
 
23
22
  attributes:
@@ -26,38 +25,55 @@ attributes:
26
25
 
27
26
  analysis:
28
27
 
28
+ #pywake and foxes
29
29
  wind_deficit_model:
30
30
  name: Bastankhah2014
31
31
  wake_expansion_coefficient: # k = ka*ti + kb
32
- k_a: 0.04
33
- k_b: 0.0
32
+ k_a: 0.0
33
+ k_b: 0.04
34
34
  free_stream_ti: false
35
35
  ceps: 0.2
36
36
  use_effective_ws: true
37
-
38
37
  axial_induction_model: Madsen
39
-
40
38
  deflection_model:
41
39
  name: None
42
-
43
40
  turbulence_model:
44
41
  name: CrespoHernandez
45
-
46
42
  superposition_model:
47
43
  ws_superposition: Linear
48
44
  ti_superposition: Quadratic
49
-
50
45
  rotor_averaging:
51
46
  grid: grid
52
47
  n_x_grid_points: 4
53
48
  n_y_grid_points: 4
54
- background_averaging: grid
55
- wake_averaging: axiwake9
49
+ background_averaging: center
50
+ wake_averaging: centre
56
51
  wind_speed_exponent_for_power: 3
57
52
  wind_speed_exponent_for_ct: 2
58
-
59
53
  blockage_model:
60
54
  name: None
61
55
 
62
-
56
+ outputs:
57
+ output_folder: "results"
58
+ turbine_outputs:
59
+ turbine_nc_filename: 'turbine_data.nc' # dimension = states, turbine
60
+ output_variables: ['power', 'rotor_effective_velocity'] #'frequency'
61
+ #
62
+ flow_field:
63
+ report: False
64
+ flow_nc_filename: flow_field.nc
65
+ cases_run:
66
+ all_occurences: True
67
+ output_variables: ['wind_speed', 'wind_direction']
68
+ z_planes:
69
+ z_sampling: "hub_height"
70
+ xy_sampling: "default"
71
+ #
72
+ statistics:
73
+ stats_filename: None
74
+ AEP: False
75
+ AEP_per_turbine: False
76
+ power_percentiles:
77
+ report: False
78
+ percentiles: None
63
79
 
@@ -0,0 +1,17 @@
1
+ from .pool import PoolEngine
2
+ from .multiprocess import MultiprocessEngine
3
+ from .numpy import NumpyEngine
4
+ from .single import SingleChunkEngine
5
+ from .futures import ThreadsEngine, ProcessEngine
6
+ from .mpi import MPIEngine
7
+ from .ray import RayEngine
8
+
9
+ from .dask import (
10
+ DaskBaseEngine,
11
+ XArrayEngine,
12
+ DaskEngine,
13
+ LocalClusterEngine,
14
+ SlurmClusterEngine,
15
+ )
16
+
17
+ from .default import DefaultEngine