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
@@ -61,7 +61,7 @@ class MultiHeightStates(States):
61
61
  pd_read_pars={},
62
62
  states_sel=None,
63
63
  states_loc=None,
64
- ipars={},
64
+ **ipars,
65
65
  ):
66
66
  """
67
67
  Constructor.
@@ -91,7 +91,6 @@ class MultiHeightStates(States):
91
91
  """
92
92
  super().__init__()
93
93
 
94
- self.data_source = data_source
95
94
  self.ovars = output_vars
96
95
  self.heights = np.array(heights, dtype=FC.DTYPE)
97
96
  self.rpars = pd_read_pars
@@ -101,10 +100,34 @@ class MultiHeightStates(States):
101
100
  self.states_sel = states_sel
102
101
  self.states_loc = states_loc
103
102
 
103
+ self._data_source = data_source
104
104
  self._solo = None
105
105
  self._weights = None
106
+ self._inds = None
106
107
  self._N = None
107
108
 
109
+ def __repr__(self):
110
+ berr = self.ipars.get("bounds_error", False)
111
+ ssel = "" if self.states_sel is None else f"n_states={len(self.states_sel)}, "
112
+ return f"{type(self).__name__}({ssel}bounds_error={berr})"
113
+
114
+ @property
115
+ def data_source(self):
116
+ """
117
+ The data source
118
+
119
+ Returns
120
+ -------
121
+ s: object
122
+ The data source
123
+
124
+ """
125
+ if self.running:
126
+ raise ValueError(
127
+ f"States '{self.name}': Cannot acces data_source while running"
128
+ )
129
+ return self._data_source
130
+
108
131
  def reset(self, algo=None, states_sel=None, states_loc=None, verbosity=0):
109
132
  """
110
133
  Reset the states, optionally select states
@@ -180,7 +203,7 @@ class MultiHeightStates(States):
180
203
  print(
181
204
  f"States '{self.name}': Reading static data '{self.data_source}' from context '{STATES}'"
182
205
  )
183
- self.data_source = algo.dbook.get_file_path(
206
+ self._data_source = algo.dbook.get_file_path(
184
207
  STATES, self.data_source, check_raw=False
185
208
  )
186
209
  if verbosity:
@@ -251,6 +274,79 @@ class MultiHeightStates(States):
251
274
 
252
275
  return idata
253
276
 
277
+ def set_running(
278
+ self,
279
+ algo,
280
+ data_stash,
281
+ sel=None,
282
+ isel=None,
283
+ verbosity=0,
284
+ ):
285
+ """
286
+ Sets this model status to running, and moves
287
+ all large data to stash.
288
+
289
+ The stashed data will be returned by the
290
+ unset_running() function after running calculations.
291
+
292
+ Parameters
293
+ ----------
294
+ algo: foxes.core.Algorithm
295
+ The calculation algorithm
296
+ data_stash: dict
297
+ Large data stash, this function adds data here.
298
+ Key: model name. Value: dict, large model data
299
+ sel: dict, optional
300
+ The subset selection dictionary
301
+ isel: dict, optional
302
+ The index subset selection dictionary
303
+ verbosity: int
304
+ The verbosity level, 0 = silent
305
+
306
+ """
307
+ super().set_running(algo, data_stash, sel, isel, verbosity)
308
+
309
+ data_stash[self.name] = dict(
310
+ data_source=self._data_source,
311
+ weights=self._weights,
312
+ inds=self._inds,
313
+ )
314
+ del self._data_source, self._weights, self._inds
315
+
316
+ def unset_running(
317
+ self,
318
+ algo,
319
+ data_stash,
320
+ sel=None,
321
+ isel=None,
322
+ verbosity=0,
323
+ ):
324
+ """
325
+ Sets this model status to not running, recovering large data
326
+ from stash
327
+
328
+ Parameters
329
+ ----------
330
+ algo: foxes.core.Algorithm
331
+ The calculation algorithm
332
+ data_stash: dict
333
+ Large data stash, this function adds data here.
334
+ Key: model name. Value: dict, large model data
335
+ sel: dict, optional
336
+ The subset selection dictionary
337
+ isel: dict, optional
338
+ The index subset selection dictionary
339
+ verbosity: int
340
+ The verbosity level, 0 = silent
341
+
342
+ """
343
+ super().unset_running(algo, data_stash, sel, isel, verbosity)
344
+
345
+ data = data_stash[self.name]
346
+ self._data_source = data.pop("data_source")
347
+ self._weights = data.pop("weights")
348
+ self._inds = data.pop("inds")
349
+
254
350
  def size(self):
255
351
  """
256
352
  The total number of states.
@@ -273,6 +369,8 @@ class MultiHeightStates(States):
273
369
  The index labels of states, or None for default integers
274
370
 
275
371
  """
372
+ if self.running:
373
+ raise ValueError(f"States '{self.name}': Cannot acces index while running")
276
374
  return self._inds
277
375
 
278
376
  def output_point_vars(self, algo):
@@ -307,6 +405,10 @@ class MultiHeightStates(States):
307
405
  The weights, shape: (n_states, n_turbines)
308
406
 
309
407
  """
408
+ if self.running:
409
+ raise ValueError(
410
+ f"States '{self.name}': Cannot acces weights while running"
411
+ )
310
412
  return self._weights
311
413
 
312
414
  def calculate(self, algo, mdata, fdata, tdata):
@@ -346,10 +448,21 @@ class MultiHeightStates(States):
346
448
 
347
449
  coeffs = np.zeros((n_h, n_h), dtype=FC.DTYPE)
348
450
  np.fill_diagonal(coeffs, 1.0)
349
- ipars = dict(assume_sorted=True, bounds_error=True)
451
+ ipars = dict(
452
+ assume_sorted=True,
453
+ bounds_error=True,
454
+ fill_value=(coeffs[0], coeffs[-1]),
455
+ )
350
456
  ipars.update(self.ipars)
351
457
  intp = interp1d(h, coeffs, axis=0, **ipars)
352
- ires = intp(z)
458
+ try:
459
+ ires = intp(z)
460
+ except ValueError as e:
461
+ if ipars["bounds_error"]:
462
+ print(
463
+ f"{self.name}: Interpolation height out of bounds. Select 'bounds_error=False' for replacement by lowest or largest height"
464
+ )
465
+ raise e
353
466
  del coeffs, intp
354
467
 
355
468
  has_wd = FV.WD in vrs
@@ -481,11 +594,7 @@ class MultiHeightNCStates(MultiHeightStates):
481
594
  self.heights = heights
482
595
  self.h_coord = h_coord
483
596
  self.xr_read_pars = xr_read_pars
484
-
485
- if format_times_func == "default":
486
- self.format_times_func = lambda t: t.astype("datetime64[ns]")
487
- else:
488
- self.format_times_func = format_times_func
597
+ self._format_times_func = format_times_func
489
598
 
490
599
  def load_data(self, algo, verbosity=0):
491
600
  """
@@ -516,7 +625,7 @@ class MultiHeightNCStates(MultiHeightStates):
516
625
  print(
517
626
  f"States '{self.name}': Reading static data '{self.data_source}' from context '{STATES}'"
518
627
  )
519
- self.data_source = algo.dbook.get_file_path(
628
+ self._data_source = algo.dbook.get_file_path(
520
629
  STATES, self.data_source, check_raw=False
521
630
  )
522
631
  if verbosity:
@@ -534,8 +643,13 @@ class MultiHeightNCStates(MultiHeightStates):
534
643
 
535
644
  self._N = data.sizes[self.state_coord]
536
645
  self._inds = data.coords[self.state_coord].to_numpy()
537
- if self.format_times_func is not None:
538
- self._inds = self.format_times_func(self._inds)
646
+
647
+ if self._format_times_func == "default":
648
+ format_times_func = lambda t: t.astype("datetime64[ns]")
649
+ else:
650
+ format_times_func = self._format_times_func
651
+ if format_times_func is not None:
652
+ self._inds = format_times_func(self._inds)
539
653
 
540
654
  w_name = self.var2col.get(FV.WEIGHT, FV.WEIGHT)
541
655
  self._weights = np.zeros((self._N, algo.n_turbines), dtype=FC.DTYPE)