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.
- docs/source/conf.py +0 -1
- examples/states_lookup_table/run.py +1 -1
- examples/timeseries/run.py +11 -4
- foxes/algorithms/downwind/downwind.py +18 -13
- foxes/algorithms/downwind/models/farm_wakes_calc.py +1 -1
- foxes/algorithms/downwind/models/init_farm_data.py +1 -1
- foxes/algorithms/downwind/models/point_wakes_calc.py +1 -1
- foxes/algorithms/downwind/models/reorder_farm_output.py +1 -1
- foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
- foxes/algorithms/downwind/models/set_amb_point_results.py +1 -1
- foxes/algorithms/iterative/iterative.py +1 -1
- foxes/algorithms/iterative/models/farm_wakes_calc.py +1 -1
- foxes/algorithms/iterative/models/urelax.py +3 -3
- foxes/algorithms/sequential/models/plugin.py +4 -4
- foxes/algorithms/sequential/models/seq_state.py +1 -1
- foxes/constants.py +5 -5
- foxes/core/algorithm.py +2 -2
- foxes/core/data_calc_model.py +2 -2
- foxes/core/engine.py +20 -10
- foxes/core/farm_controller.py +3 -3
- foxes/core/farm_data_model.py +1 -1
- foxes/core/ground_model.py +2 -2
- foxes/core/model.py +122 -108
- foxes/core/partial_wakes_model.py +1 -1
- foxes/core/point_data_model.py +2 -2
- foxes/core/states.py +1 -1
- foxes/core/turbine_type.py +2 -2
- foxes/core/wake_frame.py +8 -30
- foxes/core/wake_model.py +3 -2
- foxes/core/wake_superposition.py +1 -1
- foxes/data/windio/windio_5turbines_timeseries.yaml +9 -15
- foxes/engines/__init__.py +1 -0
- foxes/engines/dask.py +13 -6
- foxes/engines/multiprocess.py +5 -8
- foxes/engines/numpy.py +8 -26
- foxes/engines/pool.py +10 -24
- foxes/engines/ray.py +79 -0
- foxes/engines/single.py +3 -1
- foxes/input/farm_layout/from_json.py +1 -1
- foxes/input/states/__init__.py +1 -0
- foxes/input/states/field_data_nc.py +4 -4
- foxes/input/states/multi_height.py +4 -4
- foxes/input/states/scan_ws.py +1 -1
- foxes/input/states/single.py +1 -1
- foxes/input/states/slice_data_nc.py +681 -0
- foxes/input/states/states_table.py +3 -3
- foxes/input/windio/__init__.py +1 -1
- foxes/input/windio/read_attributes.py +8 -2
- foxes/input/windio/read_fields.py +3 -0
- foxes/input/windio/read_outputs.py +8 -2
- foxes/input/windio/windio.py +6 -2
- foxes/models/farm_models/turbine2farm.py +1 -1
- foxes/models/ground_models/wake_mirror.py +2 -2
- foxes/models/model_book.py +29 -2
- foxes/models/partial_wakes/axiwake.py +3 -3
- foxes/models/partial_wakes/top_hat.py +2 -2
- foxes/models/point_models/set_uniform_data.py +1 -1
- foxes/models/point_models/tke2ti.py +1 -1
- foxes/models/point_models/wake_deltas.py +1 -1
- foxes/models/rotor_models/grid.py +2 -2
- foxes/models/turbine_models/calculator.py +4 -4
- foxes/models/turbine_models/kTI_model.py +22 -6
- foxes/models/turbine_models/lookup_table.py +3 -2
- foxes/models/turbine_types/PCt_file.py +5 -5
- foxes/models/turbine_types/PCt_from_two.py +5 -5
- foxes/models/turbine_types/TBL_file.py +80 -0
- foxes/models/turbine_types/__init__.py +1 -0
- foxes/models/turbine_types/lookup.py +5 -5
- foxes/models/turbine_types/null_type.py +3 -3
- foxes/models/turbine_types/wsrho2PCt_from_two.py +7 -7
- foxes/models/turbine_types/wsti2PCt_from_two.py +9 -9
- foxes/models/vertical_profiles/__init__.py +1 -1
- foxes/models/wake_frames/dynamic_wakes.py +2 -2
- foxes/models/wake_frames/farm_order.py +2 -2
- foxes/models/wake_frames/rotor_wd.py +2 -2
- foxes/models/wake_frames/seq_dynamic_wakes.py +5 -11
- foxes/models/wake_frames/streamlines.py +2 -2
- foxes/models/wake_frames/timelines.py +2 -2
- foxes/models/wake_frames/yawed_wakes.py +3 -3
- foxes/models/wake_models/dist_sliced.py +1 -1
- foxes/models/wake_models/induction/rankine_half_body.py +1 -1
- foxes/models/wake_models/induction/rathmann.py +76 -22
- foxes/models/wake_models/induction/self_similar.py +76 -26
- foxes/models/wake_models/induction/vortex_sheet.py +84 -46
- foxes/models/wake_models/ti/crespo_hernandez.py +6 -4
- foxes/models/wake_models/ti/iec_ti.py +7 -5
- foxes/models/wake_models/wind/bastankhah14.py +6 -4
- foxes/models/wake_models/wind/bastankhah16.py +9 -9
- foxes/models/wake_models/wind/jensen.py +3 -2
- foxes/models/wake_models/wind/turbopark.py +14 -11
- foxes/models/wake_superpositions/ti_linear.py +1 -1
- foxes/models/wake_superpositions/ti_max.py +1 -1
- foxes/models/wake_superpositions/ti_pow.py +1 -1
- foxes/models/wake_superpositions/ti_quadratic.py +1 -1
- foxes/models/wake_superpositions/ws_linear.py +8 -7
- foxes/models/wake_superpositions/ws_max.py +8 -7
- foxes/models/wake_superpositions/ws_pow.py +8 -7
- foxes/models/wake_superpositions/ws_product.py +5 -5
- foxes/models/wake_superpositions/ws_quadratic.py +8 -7
- foxes/output/farm_layout.py +14 -10
- foxes/output/farm_results_eval.py +1 -1
- foxes/output/grids.py +1 -1
- foxes/output/results_writer.py +2 -2
- foxes/output/rose_plot.py +3 -3
- foxes/output/seq_plugins/seq_flow_ani_plugin.py +2 -2
- foxes/output/seq_plugins/seq_wake_debug_plugin.py +2 -2
- foxes/output/state_turbine_map.py +1 -1
- foxes/utils/abl/neutral.py +2 -2
- foxes/utils/abl/stable.py +2 -2
- foxes/utils/abl/unstable.py +2 -2
- foxes/utils/data_book.py +1 -1
- foxes/utils/dict.py +23 -0
- foxes/utils/exec_python.py +1 -1
- foxes/utils/factory.py +29 -1
- foxes/utils/geom2d/circle.py +1 -1
- foxes/utils/geom2d/polygon.py +1 -1
- foxes/utils/geopandas_utils.py +2 -2
- foxes/utils/load.py +2 -2
- foxes/utils/pandas_helpers.py +1 -1
- foxes/utils/xarray_utils.py +1 -1
- foxes/variables.py +3 -3
- {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/METADATA +8 -6
- {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/RECORD +127 -125
- {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/WHEEL +1 -1
- foxes/utils/geopandas_helpers.py +0 -294
- /examples/{induction_RHB → induction}/run.py +0 -0
- {foxes-1.0.dist-info → foxes-1.1.1.dist-info}/LICENSE +0 -0
- {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 =
|
|
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
|
|
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",
|
|
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(
|
|
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
|
|
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]
|
foxes/input/states/__init__.py
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
foxes/input/states/scan_ws.py
CHANGED
|
@@ -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,
|
foxes/input/states/single.py
CHANGED
|
@@ -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,
|