foxes 1.0__py3-none-any.whl → 1.1.1__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 (128) hide show
  1. docs/source/conf.py +0 -1
  2. examples/states_lookup_table/run.py +1 -1
  3. examples/timeseries/run.py +11 -4
  4. foxes/algorithms/downwind/downwind.py +18 -13
  5. foxes/algorithms/downwind/models/farm_wakes_calc.py +1 -1
  6. foxes/algorithms/downwind/models/init_farm_data.py +1 -1
  7. foxes/algorithms/downwind/models/point_wakes_calc.py +1 -1
  8. foxes/algorithms/downwind/models/reorder_farm_output.py +1 -1
  9. foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
  10. foxes/algorithms/downwind/models/set_amb_point_results.py +1 -1
  11. foxes/algorithms/iterative/iterative.py +1 -1
  12. foxes/algorithms/iterative/models/farm_wakes_calc.py +1 -1
  13. foxes/algorithms/iterative/models/urelax.py +3 -3
  14. foxes/algorithms/sequential/models/plugin.py +4 -4
  15. foxes/algorithms/sequential/models/seq_state.py +1 -1
  16. foxes/constants.py +5 -5
  17. foxes/core/algorithm.py +2 -2
  18. foxes/core/data_calc_model.py +2 -2
  19. foxes/core/engine.py +20 -10
  20. foxes/core/farm_controller.py +3 -3
  21. foxes/core/farm_data_model.py +1 -1
  22. foxes/core/ground_model.py +2 -2
  23. foxes/core/model.py +122 -108
  24. foxes/core/partial_wakes_model.py +1 -1
  25. foxes/core/point_data_model.py +2 -2
  26. foxes/core/states.py +1 -1
  27. foxes/core/turbine_type.py +2 -2
  28. foxes/core/wake_frame.py +8 -30
  29. foxes/core/wake_model.py +3 -2
  30. foxes/core/wake_superposition.py +1 -1
  31. foxes/data/windio/windio_5turbines_timeseries.yaml +9 -15
  32. foxes/engines/__init__.py +1 -0
  33. foxes/engines/dask.py +13 -6
  34. foxes/engines/multiprocess.py +5 -8
  35. foxes/engines/numpy.py +8 -26
  36. foxes/engines/pool.py +10 -24
  37. foxes/engines/ray.py +79 -0
  38. foxes/engines/single.py +3 -1
  39. foxes/input/farm_layout/from_json.py +1 -1
  40. foxes/input/states/__init__.py +1 -0
  41. foxes/input/states/field_data_nc.py +4 -4
  42. foxes/input/states/multi_height.py +4 -4
  43. foxes/input/states/scan_ws.py +1 -1
  44. foxes/input/states/single.py +1 -1
  45. foxes/input/states/slice_data_nc.py +681 -0
  46. foxes/input/states/states_table.py +3 -3
  47. foxes/input/windio/__init__.py +1 -1
  48. foxes/input/windio/read_attributes.py +8 -2
  49. foxes/input/windio/read_fields.py +3 -0
  50. foxes/input/windio/read_outputs.py +8 -2
  51. foxes/input/windio/windio.py +6 -2
  52. foxes/models/farm_models/turbine2farm.py +1 -1
  53. foxes/models/ground_models/wake_mirror.py +2 -2
  54. foxes/models/model_book.py +29 -2
  55. foxes/models/partial_wakes/axiwake.py +3 -3
  56. foxes/models/partial_wakes/top_hat.py +2 -2
  57. foxes/models/point_models/set_uniform_data.py +1 -1
  58. foxes/models/point_models/tke2ti.py +1 -1
  59. foxes/models/point_models/wake_deltas.py +1 -1
  60. foxes/models/rotor_models/grid.py +2 -2
  61. foxes/models/turbine_models/calculator.py +4 -4
  62. foxes/models/turbine_models/kTI_model.py +22 -6
  63. foxes/models/turbine_models/lookup_table.py +3 -2
  64. foxes/models/turbine_types/PCt_file.py +5 -5
  65. foxes/models/turbine_types/PCt_from_two.py +5 -5
  66. foxes/models/turbine_types/TBL_file.py +80 -0
  67. foxes/models/turbine_types/__init__.py +1 -0
  68. foxes/models/turbine_types/lookup.py +5 -5
  69. foxes/models/turbine_types/null_type.py +3 -3
  70. foxes/models/turbine_types/wsrho2PCt_from_two.py +7 -7
  71. foxes/models/turbine_types/wsti2PCt_from_two.py +9 -9
  72. foxes/models/vertical_profiles/__init__.py +1 -1
  73. foxes/models/wake_frames/dynamic_wakes.py +2 -2
  74. foxes/models/wake_frames/farm_order.py +2 -2
  75. foxes/models/wake_frames/rotor_wd.py +2 -2
  76. foxes/models/wake_frames/seq_dynamic_wakes.py +5 -11
  77. foxes/models/wake_frames/streamlines.py +2 -2
  78. foxes/models/wake_frames/timelines.py +2 -2
  79. foxes/models/wake_frames/yawed_wakes.py +3 -3
  80. foxes/models/wake_models/dist_sliced.py +1 -1
  81. foxes/models/wake_models/induction/rankine_half_body.py +1 -1
  82. foxes/models/wake_models/induction/rathmann.py +76 -22
  83. foxes/models/wake_models/induction/self_similar.py +76 -26
  84. foxes/models/wake_models/induction/vortex_sheet.py +84 -46
  85. foxes/models/wake_models/ti/crespo_hernandez.py +6 -4
  86. foxes/models/wake_models/ti/iec_ti.py +7 -5
  87. foxes/models/wake_models/wind/bastankhah14.py +6 -4
  88. foxes/models/wake_models/wind/bastankhah16.py +9 -9
  89. foxes/models/wake_models/wind/jensen.py +3 -2
  90. foxes/models/wake_models/wind/turbopark.py +14 -11
  91. foxes/models/wake_superpositions/ti_linear.py +1 -1
  92. foxes/models/wake_superpositions/ti_max.py +1 -1
  93. foxes/models/wake_superpositions/ti_pow.py +1 -1
  94. foxes/models/wake_superpositions/ti_quadratic.py +1 -1
  95. foxes/models/wake_superpositions/ws_linear.py +8 -7
  96. foxes/models/wake_superpositions/ws_max.py +8 -7
  97. foxes/models/wake_superpositions/ws_pow.py +8 -7
  98. foxes/models/wake_superpositions/ws_product.py +5 -5
  99. foxes/models/wake_superpositions/ws_quadratic.py +8 -7
  100. foxes/output/farm_layout.py +14 -10
  101. foxes/output/farm_results_eval.py +1 -1
  102. foxes/output/grids.py +1 -1
  103. foxes/output/results_writer.py +2 -2
  104. foxes/output/rose_plot.py +3 -3
  105. foxes/output/seq_plugins/seq_flow_ani_plugin.py +2 -2
  106. foxes/output/seq_plugins/seq_wake_debug_plugin.py +2 -2
  107. foxes/output/state_turbine_map.py +1 -1
  108. foxes/utils/abl/neutral.py +2 -2
  109. foxes/utils/abl/stable.py +2 -2
  110. foxes/utils/abl/unstable.py +2 -2
  111. foxes/utils/data_book.py +1 -1
  112. foxes/utils/dict.py +23 -0
  113. foxes/utils/exec_python.py +1 -1
  114. foxes/utils/factory.py +29 -1
  115. foxes/utils/geom2d/circle.py +1 -1
  116. foxes/utils/geom2d/polygon.py +1 -1
  117. foxes/utils/geopandas_utils.py +2 -2
  118. foxes/utils/load.py +2 -2
  119. foxes/utils/pandas_helpers.py +1 -1
  120. foxes/utils/xarray_utils.py +1 -1
  121. foxes/variables.py +3 -3
  122. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/METADATA +8 -6
  123. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/RECORD +127 -125
  124. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/WHEEL +1 -1
  125. foxes/utils/geopandas_helpers.py +0 -294
  126. /examples/{induction_RHB → induction}/run.py +0 -0
  127. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/LICENSE +0 -0
  128. {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/top_level.txt +0 -0
foxes/engines/numpy.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from tqdm import tqdm
2
2
  from xarray import Dataset
3
+ from tqdm import tqdm
3
4
 
4
5
  from foxes.core import Engine
5
6
  import foxes.constants as FC
@@ -15,28 +16,6 @@ class NumpyEngine(Engine):
15
16
 
16
17
  """
17
18
 
18
- def __init__(self, *args, **kwargs):
19
- """
20
- Constructor.
21
-
22
- Parameters
23
- ----------
24
- args: tuple, optional
25
- Additional parameters for the base class
26
- kwargs: dict, optional
27
- Additional parameters for the base class
28
-
29
- """
30
- ignr = ["n_procs"]
31
- for k in ignr:
32
- if kwargs.pop(k, None) is not None:
33
- print(f"{type(self).__name__}: Ignoring {k}")
34
- super().__init__(
35
- *args,
36
- n_procs=1,
37
- **kwargs,
38
- )
39
-
40
19
  def run_calculation(
41
20
  self,
42
21
  algo,
@@ -117,14 +96,18 @@ class NumpyEngine(Engine):
117
96
  n_chunks_states = len(chunk_sizes_states)
118
97
  n_chunks_targets = len(chunk_sizes_targets)
119
98
  self.print(
120
- f"Selecting n_chunks_states = {n_chunks_states}, n_chunks_targets = {n_chunks_targets}",
99
+ f"{type(self).__name__}: Selecting n_chunks_states = {n_chunks_states}, n_chunks_targets = {n_chunks_targets}",
121
100
  level=2,
122
101
  )
123
102
 
124
103
  # prepare and submit chunks:
125
104
  n_chunks_all = n_chunks_states * n_chunks_targets
126
- self.print(f"Looping over {n_chunks_all} chunks")
127
- pbar = tqdm(total=n_chunks_all) if self.verbosity > 1 else None
105
+ self.print(f"{type(self).__name__}: Looping over {n_chunks_all} chunks")
106
+ pbar = (
107
+ tqdm(total=n_chunks_all)
108
+ if self.verbosity > 0 and n_chunks_all > 1
109
+ else None
110
+ )
128
111
  results = {}
129
112
  i0_states = 0
130
113
  for chunki_states in range(n_chunks_states):
@@ -134,7 +117,6 @@ class NumpyEngine(Engine):
134
117
  i1_targets = i0_targets + chunk_sizes_targets[chunki_points]
135
118
 
136
119
  i = chunki_states * n_chunks_targets + chunki_points
137
- self.print(f"Computing chunk {i}/{n_chunks_all}")
138
120
 
139
121
  # get this chunk's data:
140
122
  data = self.get_chunk_input_data(
foxes/engines/pool.py CHANGED
@@ -74,12 +74,13 @@ class PoolEngine(Engine):
74
74
  """Shuts down the pool"""
75
75
  pass
76
76
 
77
- def initialize(self):
78
- """
79
- Initializes the engine.
80
- """
81
- super().initialize()
77
+ def __enter__(self):
82
78
  self._create_pool()
79
+ return super().__enter__()
80
+
81
+ def __exit__(self, *exit_args):
82
+ self._shutdown_pool()
83
+ super().__exit__(*exit_args)
83
84
 
84
85
  def run_calculation(
85
86
  self,
@@ -161,14 +162,15 @@ class PoolEngine(Engine):
161
162
  n_chunks_states = len(chunk_sizes_states)
162
163
  n_chunks_targets = len(chunk_sizes_targets)
163
164
  self.print(
164
- f"Selecting n_chunks_states = {n_chunks_states}, n_chunks_targets = {n_chunks_targets}",
165
+ f"{type(self).__name__}: Selecting n_chunks_states = {n_chunks_states}, n_chunks_targets = {n_chunks_targets}",
165
166
  level=2,
166
167
  )
167
168
 
168
169
  # prepare and submit chunks:
169
170
  n_chunks_all = n_chunks_states * n_chunks_targets
170
171
  self.print(
171
- f"Submitting {n_chunks_all} chunks to {self.n_procs} processes", level=2
172
+ f"{type(self).__name__}: Submitting {n_chunks_all} chunks to {self.n_procs} processes",
173
+ level=2,
172
174
  )
173
175
  pbar = tqdm(total=n_chunks_all) if self.verbosity > 1 else None
174
176
  jobs = {}
@@ -217,7 +219,7 @@ class PoolEngine(Engine):
217
219
  # wait for results:
218
220
  if n_chunks_all > 1 or self.verbosity > 1:
219
221
  self.print(
220
- f"Computing {n_chunks_all} chunks using {self.n_procs} processes"
222
+ f"{type(self).__name__}: Computing {n_chunks_all} chunks using {self.n_procs} processes"
221
223
  )
222
224
  pbar = (
223
225
  tqdm(total=n_chunks_all)
@@ -245,19 +247,3 @@ class PoolEngine(Engine):
245
247
  goal_data=goal_data,
246
248
  iterative=iterative,
247
249
  )
248
-
249
- def finalize(self, *exit_args, **exit_kwargs):
250
- """
251
- Finalizes the engine.
252
-
253
- Parameters
254
- ----------
255
- exit_args: tuple, optional
256
- Arguments from the exit function
257
- exit_kwargs: dict, optional
258
- Arguments from the exit function
259
-
260
- """
261
- if self.initialized:
262
- self._shutdown_pool()
263
- super().finalize(*exit_args, **exit_kwargs)
foxes/engines/ray.py ADDED
@@ -0,0 +1,79 @@
1
+ from copy import deepcopy
2
+
3
+ from foxes.utils import import_module
4
+
5
+ from .pool import PoolEngine
6
+
7
+
8
+ ray = None
9
+
10
+
11
+ def load_ray():
12
+ """On-demand loading of the ray package"""
13
+ global ray
14
+ if ray is None:
15
+ ray = import_module("ray", hint="pip install ray")
16
+
17
+
18
+ class RayEngine(PoolEngine):
19
+ """
20
+ The ray engine for foxes calculations.
21
+
22
+ :group: engines
23
+
24
+ """
25
+
26
+ def _create_pool(self):
27
+ """Creates the pool"""
28
+ self.print(f"Initializing pool of {self.n_procs} ray workers")
29
+ load_ray()
30
+ ray.init(num_cpus=self.n_procs)
31
+
32
+ def _submit(self, f, *args, **kwargs):
33
+ """
34
+ Submits to the pool
35
+
36
+ Parameters
37
+ ----------
38
+ f: Callable
39
+ The function f(*args, **kwargs) to be
40
+ submitted
41
+ args: tuple, optional
42
+ Arguments for the function
43
+ kwargs: dict, optional
44
+ Arguments for the function
45
+
46
+ Returns
47
+ -------
48
+ future: object
49
+ The future object
50
+
51
+ """
52
+
53
+ @ray.remote
54
+ def f_ray(*args, **kwargs):
55
+ return f(*deepcopy(args), **deepcopy(kwargs))
56
+
57
+ return f_ray.remote(*args, **kwargs)
58
+
59
+ def _result(self, future):
60
+ """
61
+ Waits for result from a future
62
+
63
+ Parameters
64
+ ----------
65
+ future: object
66
+ The future
67
+
68
+ Returns
69
+ -------
70
+ result: object
71
+ The calculation result
72
+
73
+ """
74
+ return ray.get(future)
75
+
76
+ def _shutdown_pool(self):
77
+ """Shuts down the pool"""
78
+ self.print(f"Shutting down pool of {self.n_procs} ray workers")
79
+ ray.shutdown()
foxes/engines/single.py CHANGED
@@ -111,7 +111,9 @@ class SingleChunkEngine(Engine):
111
111
  # calculate:
112
112
 
113
113
  if n_states > 1:
114
- self.print(f"Running single chunk calculation for {n_states} states")
114
+ self.print(
115
+ f"{type(self).__name__}: Running single chunk calculation for {n_states} states"
116
+ )
115
117
 
116
118
  data = self.get_chunk_input_data(
117
119
  algo=algo,
@@ -35,7 +35,7 @@ def add_from_json(
35
35
 
36
36
  keys = list(dict.keys())
37
37
  if len(keys) != 1:
38
- raise KeyError("Only one wind farm supported by flappy at the moment.")
38
+ raise KeyError("Only one wind farm supported by foxes at the moment.")
39
39
 
40
40
  farm_name = keys[0]
41
41
  fdict = dict[farm_name]
@@ -6,6 +6,7 @@ from .single import SingleStateStates
6
6
  from .scan_ws import ScanWS
7
7
  from .states_table import StatesTable, Timeseries, TabStates
8
8
  from .field_data_nc import FieldDataNC
9
+ from .slice_data_nc import SliceDataNC
9
10
  from .multi_height import MultiHeightStates, MultiHeightTimeseries
10
11
  from .multi_height import MultiHeightNCStates, MultiHeightNCTimeseries
11
12
  from .one_point_flow import (
@@ -207,7 +207,7 @@ class FieldDataNC(States):
207
207
  """
208
208
  if self.pre_load and self.running:
209
209
  raise ValueError(
210
- f"States '{self.name}': Cannot acces data_source while running"
210
+ f"States '{self.name}': Cannot access data_source while running"
211
211
  )
212
212
  return self.__data_source
213
213
 
@@ -496,7 +496,7 @@ class FieldDataNC(States):
496
496
 
497
497
  """
498
498
  if self.running:
499
- raise ValueError(f"States '{self.name}': Cannot acces index while running")
499
+ raise ValueError(f"States '{self.name}': Cannot access index while running")
500
500
  return self.__inds
501
501
 
502
502
  def output_point_vars(self, algo):
@@ -533,12 +533,12 @@ class FieldDataNC(States):
533
533
  """
534
534
  if self.running:
535
535
  raise ValueError(
536
- f"States '{self.name}': Cannot acces weights while running"
536
+ f"States '{self.name}': Cannot access weights while running"
537
537
  )
538
538
  return self.__weights
539
539
 
540
540
  def calculate(self, algo, mdata, fdata, tdata):
541
- """ "
541
+ """
542
542
  The main model calculation.
543
543
 
544
544
  This function is executed on a single chunk of data,
@@ -124,7 +124,7 @@ class MultiHeightStates(States):
124
124
  """
125
125
  if self.running:
126
126
  raise ValueError(
127
- f"States '{self.name}': Cannot acces data_source while running"
127
+ f"States '{self.name}': Cannot access data_source while running"
128
128
  )
129
129
  return self._data_source
130
130
 
@@ -370,7 +370,7 @@ class MultiHeightStates(States):
370
370
 
371
371
  """
372
372
  if self.running:
373
- raise ValueError(f"States '{self.name}': Cannot acces index while running")
373
+ raise ValueError(f"States '{self.name}': Cannot access index while running")
374
374
  return self._inds
375
375
 
376
376
  def output_point_vars(self, algo):
@@ -407,12 +407,12 @@ class MultiHeightStates(States):
407
407
  """
408
408
  if self.running:
409
409
  raise ValueError(
410
- f"States '{self.name}': Cannot acces weights while running"
410
+ f"States '{self.name}': Cannot access weights while running"
411
411
  )
412
412
  return self._weights
413
413
 
414
414
  def calculate(self, algo, mdata, fdata, tdata):
415
- """ "
415
+ """
416
416
  The main model calculation.
417
417
 
418
418
  This function is executed on a single chunk of data,
@@ -201,7 +201,7 @@ class ScanWS(States):
201
201
  return np.full((self.N, algo.n_turbines), 1.0 / self.N, dtype=FC.DTYPE)
202
202
 
203
203
  def calculate(self, algo, mdata, fdata, tdata):
204
- """ "
204
+ """
205
205
  The main model calculation.
206
206
 
207
207
  This function is executed on a single chunk of data,
@@ -166,7 +166,7 @@ class SingleStateStates(States):
166
166
  return np.ones((1, algo.n_turbines), dtype=FC.DTYPE)
167
167
 
168
168
  def calculate(self, algo, mdata, fdata, tdata):
169
- """ "
169
+ """
170
170
  The main model calculation.
171
171
 
172
172
  This function is executed on a single chunk of data,