foxes 0.8.1__py3-none-any.whl → 1.0__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 (175) 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_RHB/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 +183 -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 +232 -101
  27. foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -6
  28. foxes/algorithms/downwind/models/init_farm_data.py +1 -1
  29. foxes/algorithms/downwind/models/point_wakes_calc.py +5 -6
  30. foxes/algorithms/downwind/models/reorder_farm_output.py +0 -1
  31. foxes/algorithms/downwind/models/set_amb_point_results.py +4 -2
  32. foxes/algorithms/iterative/iterative.py +73 -33
  33. foxes/algorithms/iterative/models/farm_wakes_calc.py +11 -6
  34. foxes/algorithms/sequential/models/plugin.py +1 -1
  35. foxes/algorithms/sequential/sequential.py +126 -255
  36. foxes/constants.py +17 -2
  37. foxes/core/__init__.py +1 -0
  38. foxes/core/algorithm.py +631 -146
  39. foxes/core/data.py +252 -20
  40. foxes/core/data_calc_model.py +13 -289
  41. foxes/core/engine.py +630 -0
  42. foxes/core/farm_controller.py +37 -9
  43. foxes/core/farm_data_model.py +15 -0
  44. foxes/core/model.py +133 -80
  45. foxes/core/point_data_model.py +15 -0
  46. foxes/core/rotor_model.py +27 -21
  47. foxes/core/states.py +16 -0
  48. foxes/core/turbine_type.py +28 -0
  49. foxes/core/wake_frame.py +22 -4
  50. foxes/core/wake_model.py +2 -3
  51. foxes/data/windio/windio_5turbines_timeseries.yaml +23 -1
  52. foxes/engines/__init__.py +16 -0
  53. foxes/engines/dask.py +975 -0
  54. foxes/engines/default.py +75 -0
  55. foxes/engines/futures.py +72 -0
  56. foxes/engines/mpi.py +38 -0
  57. foxes/engines/multiprocess.py +74 -0
  58. foxes/engines/numpy.py +185 -0
  59. foxes/engines/pool.py +263 -0
  60. foxes/engines/single.py +139 -0
  61. foxes/input/farm_layout/__init__.py +1 -0
  62. foxes/input/farm_layout/from_csv.py +4 -0
  63. foxes/input/farm_layout/from_json.py +1 -1
  64. foxes/input/farm_layout/grid.py +2 -2
  65. foxes/input/farm_layout/ring.py +65 -0
  66. foxes/input/farm_layout/row.py +2 -2
  67. foxes/input/states/__init__.py +6 -0
  68. foxes/input/states/create/random_abl_states.py +1 -1
  69. foxes/input/states/field_data_nc.py +157 -32
  70. foxes/input/states/multi_height.py +127 -13
  71. foxes/input/states/one_point_flow.py +577 -0
  72. foxes/input/states/scan_ws.py +73 -2
  73. foxes/input/states/states_table.py +204 -35
  74. foxes/input/windio/__init__.py +1 -1
  75. foxes/input/windio/get_states.py +44 -23
  76. foxes/input/windio/read_attributes.py +41 -16
  77. foxes/input/windio/read_farm.py +116 -102
  78. foxes/input/windio/read_fields.py +13 -6
  79. foxes/input/windio/read_outputs.py +63 -22
  80. foxes/input/windio/runner.py +31 -17
  81. foxes/input/windio/windio.py +36 -22
  82. foxes/models/ground_models/wake_mirror.py +8 -4
  83. foxes/models/model_book.py +29 -18
  84. foxes/models/partial_wakes/rotor_points.py +3 -3
  85. foxes/models/rotor_models/centre.py +4 -0
  86. foxes/models/rotor_models/grid.py +22 -23
  87. foxes/models/rotor_models/levels.py +4 -5
  88. foxes/models/turbine_models/calculator.py +0 -2
  89. foxes/models/turbine_models/lookup_table.py +27 -2
  90. foxes/models/turbine_models/rotor_centre_calc.py +4 -3
  91. foxes/models/turbine_models/set_farm_vars.py +103 -34
  92. foxes/models/turbine_types/PCt_file.py +24 -0
  93. foxes/models/turbine_types/PCt_from_two.py +24 -0
  94. foxes/models/turbine_types/__init__.py +1 -0
  95. foxes/models/turbine_types/lookup.py +316 -0
  96. foxes/models/turbine_types/null_type.py +50 -0
  97. foxes/models/turbine_types/wsrho2PCt_from_two.py +24 -0
  98. foxes/models/turbine_types/wsti2PCt_from_two.py +24 -0
  99. foxes/models/vertical_profiles/data_profile.py +1 -1
  100. foxes/models/wake_frames/__init__.py +1 -0
  101. foxes/models/wake_frames/dynamic_wakes.py +424 -0
  102. foxes/models/wake_frames/farm_order.py +23 -3
  103. foxes/models/wake_frames/rotor_wd.py +4 -2
  104. foxes/models/wake_frames/seq_dynamic_wakes.py +56 -63
  105. foxes/models/wake_frames/streamlines.py +19 -20
  106. foxes/models/wake_frames/timelines.py +328 -127
  107. foxes/models/wake_frames/yawed_wakes.py +4 -1
  108. foxes/models/wake_models/dist_sliced.py +1 -3
  109. foxes/models/wake_models/induction/rankine_half_body.py +4 -4
  110. foxes/models/wake_models/induction/rathmann.py +2 -2
  111. foxes/models/wake_models/induction/self_similar.py +2 -2
  112. foxes/models/wake_models/induction/vortex_sheet.py +2 -2
  113. foxes/models/wake_models/ti/iec_ti.py +34 -17
  114. foxes/models/wake_models/top_hat.py +1 -1
  115. foxes/models/wake_models/wind/bastankhah14.py +2 -2
  116. foxes/models/wake_models/wind/bastankhah16.py +8 -7
  117. foxes/models/wake_models/wind/jensen.py +1 -1
  118. foxes/models/wake_models/wind/turbopark.py +2 -2
  119. foxes/output/__init__.py +4 -1
  120. foxes/output/farm_layout.py +2 -2
  121. foxes/output/flow_plots_2d/__init__.py +0 -1
  122. foxes/output/flow_plots_2d/flow_plots.py +70 -30
  123. foxes/output/grids.py +91 -21
  124. foxes/output/seq_plugins/__init__.py +2 -0
  125. foxes/output/{flow_plots_2d → seq_plugins}/seq_flow_ani_plugin.py +62 -20
  126. foxes/output/seq_plugins/seq_wake_debug_plugin.py +145 -0
  127. foxes/output/slice_data.py +131 -111
  128. foxes/output/state_turbine_map.py +18 -13
  129. foxes/output/state_turbine_table.py +19 -19
  130. foxes/utils/__init__.py +1 -1
  131. foxes/utils/dev_utils.py +42 -0
  132. foxes/utils/dict.py +1 -1
  133. foxes/utils/factory.py +147 -52
  134. foxes/utils/pandas_helpers.py +4 -3
  135. foxes/utils/wind_dir.py +0 -2
  136. foxes/utils/xarray_utils.py +25 -13
  137. foxes/variables.py +37 -0
  138. {foxes-0.8.1.dist-info → foxes-1.0.dist-info}/METADATA +72 -34
  139. foxes-1.0.dist-info/RECORD +307 -0
  140. {foxes-0.8.1.dist-info → foxes-1.0.dist-info}/WHEEL +1 -1
  141. foxes-1.0.dist-info/top_level.txt +4 -0
  142. tests/0_consistency/iterative/test_iterative.py +92 -0
  143. tests/0_consistency/partial_wakes/test_partial_wakes.py +90 -0
  144. tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +85 -0
  145. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +103 -0
  146. tests/1_verification/flappy_0_6/abl_states/flappy/run.py +85 -0
  147. tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +87 -0
  148. tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +82 -0
  149. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +82 -0
  150. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/flappy/run.py +92 -0
  151. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +93 -0
  152. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/flappy/run.py +92 -0
  153. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +96 -0
  154. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/flappy/run.py +94 -0
  155. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +122 -0
  156. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/flappy/run.py +94 -0
  157. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +122 -0
  158. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/flappy/run.py +92 -0
  159. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +93 -0
  160. tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +85 -0
  161. tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +130 -0
  162. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/flappy/run.py +96 -0
  163. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +116 -0
  164. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +93 -0
  165. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +99 -0
  166. tests/3_examples/test_examples.py +34 -0
  167. foxes/VERSION +0 -1
  168. foxes/output/flow_plots_2d.py +0 -0
  169. foxes/utils/plotly_helpers.py +0 -19
  170. foxes/utils/runners/__init__.py +0 -1
  171. foxes/utils/runners/runners.py +0 -280
  172. foxes-0.8.1.dist-info/RECORD +0 -248
  173. foxes-0.8.1.dist-info/top_level.txt +0 -1
  174. foxes-0.8.1.dist-info/zip-safe +0 -1
  175. {foxes-0.8.1.dist-info → foxes-1.0.dist-info}/LICENSE +0 -0
@@ -44,7 +44,14 @@ class Iterative(Downwind):
44
44
  except AttributeError:
45
45
  return super().get_model(name)
46
46
 
47
- def __init__(self, *args, max_it=None, conv_crit="default", mod_cutin={}, **kwargs):
47
+ def __init__(
48
+ self,
49
+ *args,
50
+ max_it=None,
51
+ conv_crit="default",
52
+ mod_cutin={},
53
+ **kwargs,
54
+ ):
48
55
  """
49
56
  Constructor.
50
57
 
@@ -68,7 +75,7 @@ class Iterative(Downwind):
68
75
  self.conv_crit = (
69
76
  self.get_model("DefaultConv")() if conv_crit == "default" else conv_crit
70
77
  )
71
- self.prev_farm_results = None
78
+ self.__prev_farm_results = None
72
79
  self._it = None
73
80
  self._mlist = None
74
81
  self._reamb = False
@@ -77,6 +84,22 @@ class Iterative(Downwind):
77
84
  self._mod_cutin = dict(modify_ct=True, modify_P=False)
78
85
  self._mod_cutin.update(mod_cutin)
79
86
 
87
+ self.verbosity = self.verbosity - 1
88
+
89
+ @property
90
+ def farm_results_downwind(self):
91
+ """
92
+ Gets the all-chunks farm results in downwind order
93
+ from the previous iteration
94
+
95
+ Returns
96
+ -------
97
+ fres: xarray.Datatset
98
+ The all-chunks farm results during calculations
99
+
100
+ """
101
+ return self.__prev_farm_results
102
+
80
103
  def set_urelax(self, entry_point, **urel):
81
104
  """
82
105
  Sets under-relaxation parameters.
@@ -215,11 +238,6 @@ class Iterative(Downwind):
215
238
 
216
239
  # rotate back from downwind order:
217
240
  else:
218
-
219
- # add model that calculates wake effects:
220
- # mlist.models.append(self.get_model("FarmWakesCalculation")(urelax=None))
221
- # calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
222
-
223
241
  mlist.models.append(self.get_model("ReorderFarmOutput")(outputs))
224
242
  calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
225
243
 
@@ -230,16 +248,26 @@ class Iterative(Downwind):
230
248
  if self._it == 0:
231
249
  super()._calc_farm_vars(mlist)
232
250
 
233
- def _run_farm_calc(self, mlist, *data, **kwargs):
251
+ def _launch_parallel_farm_calc(self, mlist, *data, **kwargs):
234
252
  """Helper function for running the main farm calculation"""
235
- ir = (
236
- None
237
- if self.prev_farm_results is None
238
- else self.chunked(self.prev_farm_results)
253
+ return super()._launch_parallel_farm_calc(
254
+ mlist, *data, farm_data=self.__prev_farm_results, iterative=True, **kwargs
239
255
  )
240
- return super()._run_farm_calc(mlist, *data, initial_results=ir, **kwargs)
241
256
 
242
- def calc_farm(self, finalize=True, **kwargs):
257
+ @property
258
+ def final_iteration(self):
259
+ """
260
+ Flag for the final iteration
261
+
262
+ Returns
263
+ -------
264
+ flag: bool
265
+ Flag for the final iteration
266
+
267
+ """
268
+ return self._final_run
269
+
270
+ def calc_farm(self, finalize=True, ret_dwnd_order=False, **kwargs):
243
271
  """
244
272
  Calculate farm data.
245
273
 
@@ -247,6 +275,8 @@ class Iterative(Downwind):
247
275
  ----------
248
276
  finalize: bool
249
277
  Flag for finalization after calculation
278
+ ret_dwnd_order: bool
279
+ Also return the results in downwind order
250
280
  kwargs: dict, optional
251
281
  Arguments for calc_farm in the base class.
252
282
 
@@ -257,44 +287,54 @@ class Iterative(Downwind):
257
287
  dimensions (state, turbine)
258
288
 
259
289
  """
260
- outputs = kwargs.pop("outputs", self.DEFAULT_FARM_OUTPUTS)
261
- outputs = list(set(outputs + [FV.ORDER_SSEL, FV.ORDER_INV, FV.WEIGHT]))
290
+ outputs = kwargs.pop("outputs", None)
291
+ if outputs == "default":
292
+ outputs = self.DEFAULT_FARM_OUTPUTS
262
293
 
263
294
  fres = None
264
295
  self._it = -1
265
296
  self._final_run = False
297
+ fres_dwnd = None
266
298
  while self._it < self.max_it:
267
299
  self._it += 1
268
300
 
269
301
  self.print(f"\nAlgorithm {self.name}: Iteration {self._it}\n", vlim=0)
270
302
 
271
- self.prev_farm_results = fres
303
+ self.__prev_farm_results = fres
272
304
  fres = super().calc_farm(outputs=None, finalize=False, **kwargs)
273
305
 
306
+ fres_dwnd = fres
274
307
  if self.conv_crit is not None:
275
- conv = self.conv_crit.check_converged(
276
- self, self.prev_farm_results, fres, verbosity=self.verbosity + 1
277
- )
278
-
279
- if conv:
280
- self.print(
281
- f"\nAlgorithm {self.name}: Convergence reached.\n", vlim=0
308
+ if self.eval_conv_block():
309
+ self.print(f"{self.name}: Convergence blocked", vlim=0)
310
+ else:
311
+ conv = self.conv_crit.check_converged(
312
+ self,
313
+ self.__prev_farm_results,
314
+ fres,
315
+ verbosity=self.verbosity + 1,
282
316
  )
283
- self.print("Starting final run")
284
- self._final_run = True
285
- fres = super().calc_farm(outputs=outputs, finalize=False, **kwargs)
286
- break
317
+ if conv:
318
+ self.print(
319
+ f"\nAlgorithm {self.name}: Convergence reached.\n", vlim=0
320
+ )
321
+ break
287
322
 
288
- if self._it == 0:
289
- self.verbosity -= 1
323
+ # final run, recovers farm order of results:
324
+ self.print("Starting final run", vlim=0)
325
+ self._final_run = True
326
+ fres = super().calc_farm(outputs=outputs, finalize=False, **kwargs)
290
327
 
291
328
  # finalize models:
292
329
  if finalize:
293
- self.print("\n")
330
+ self.print("\n", vlim=0)
294
331
  self.finalize()
295
332
  for m in self._mlist0.models:
296
- if m not in self.all_models():
333
+ if m not in self.sub_models():
297
334
  m.finalize(self, self.verbosity)
298
335
  del self._mlist0, self._calc_pars0
299
336
 
300
- return fres
337
+ if ret_dwnd_order:
338
+ return fres, fres_dwnd
339
+ else:
340
+ return fres
@@ -2,6 +2,7 @@ import numpy as np
2
2
  from copy import deepcopy
3
3
 
4
4
  from foxes.core import FarmDataModel, TData
5
+ import foxes.constants as FC
5
6
 
6
7
 
7
8
  class FarmWakesCalculation(FarmDataModel):
@@ -87,8 +88,8 @@ class FarmWakesCalculation(FarmDataModel):
87
88
  """
88
89
  # collect ambient rotor results and weights:
89
90
  rotor = algo.rotor_model
90
- weights = rotor.from_data_or_store(rotor.RWEIGHTS, algo, mdata)
91
- amb_res = rotor.from_data_or_store(rotor.AMBRES, algo, mdata)
91
+ weights = algo.get_from_chunk_store(FC.ROTOR_WEIGHTS, mdata=mdata)
92
+ amb_res = algo.get_from_chunk_store(FC.AMB_ROTOR_RES, mdata=mdata)
92
93
 
93
94
  # generate all wake evaluation points
94
95
  # (n_states, n_order, n_rpoints)
@@ -99,9 +100,9 @@ class FarmWakesCalculation(FarmDataModel):
99
100
  tpoints, tweights = pwake.get_wake_points(algo, mdata, fdata)
100
101
  pwake2tdata[pwake.name] = TData.from_tpoints(tpoints, tweights)
101
102
 
102
- def _get_wdata(tdatap, wdeltas, s):
103
+ def _get_wdata(tdatap, wdeltas, variables, s):
103
104
  """Helper function for wake data extraction"""
104
- tdata = tdatap.get_slice(s, keep=True)
105
+ tdata = tdatap.get_slice(variables, s)
105
106
  wdelta = {v: d[s] for v, d in wdeltas.items()}
106
107
  return tdata, wdelta
107
108
 
@@ -116,13 +117,17 @@ class FarmWakesCalculation(FarmDataModel):
116
117
  for oi in range(n_turbines):
117
118
 
118
119
  if oi > 0:
119
- tdata, wdelta = _get_wdata(tdatap, wdeltas, np.s_[:, :oi])
120
+ tdata, wdelta = _get_wdata(
121
+ tdatap, wdeltas, [FC.STATE, FC.TARGET], np.s_[:, :oi]
122
+ )
120
123
  gmodel.contribute_to_farm_wakes(
121
124
  algo, mdata, fdata, tdata, oi, wdelta, wmodel, pwake
122
125
  )
123
126
 
124
127
  if oi < n_turbines - 1:
125
- tdata, wdelta = _get_wdata(tdatap, wdeltas, np.s_[:, oi + 1 :])
128
+ tdata, wdelta = _get_wdata(
129
+ tdatap, wdeltas, [FC.STATE, FC.TARGET], np.s_[:, oi + 1 :]
130
+ )
126
131
  gmodel.contribute_to_farm_wakes(
127
132
  algo, mdata, fdata, tdata, oi, wdelta, wmodel, pwake
128
133
  )
@@ -56,4 +56,4 @@ class SequentialPlugin:
56
56
  The final sequetial algorithm
57
57
 
58
58
  """
59
- self.algo = None
59
+ self.algo = algo