foxes 1.1.1__py3-none-any.whl → 1.2.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 +3 -1
- examples/abl_states/run.py +5 -5
- examples/dyn_wakes/run.py +2 -2
- examples/induction/run.py +5 -5
- examples/random_timeseries/run.py +13 -13
- examples/scan_row/run.py +12 -7
- examples/sector_management/run.py +11 -7
- examples/single_state/run.py +5 -5
- examples/tab_file/run.py +1 -1
- examples/timelines/run.py +1 -1
- examples/timeseries/run.py +5 -5
- examples/timeseries_slurm/run.py +5 -5
- examples/wind_rose/run.py +1 -1
- examples/yawed_wake/run.py +5 -5
- foxes/__init__.py +13 -2
- foxes/algorithms/downwind/downwind.py +21 -6
- foxes/algorithms/downwind/models/init_farm_data.py +5 -2
- foxes/algorithms/downwind/models/point_wakes_calc.py +0 -1
- foxes/algorithms/iterative/iterative.py +1 -1
- foxes/algorithms/sequential/sequential.py +5 -4
- foxes/config/__init__.py +1 -0
- foxes/config/config.py +134 -0
- foxes/constants.py +15 -6
- foxes/core/algorithm.py +46 -30
- foxes/core/axial_induction_model.py +18 -0
- foxes/core/data.py +2 -1
- foxes/core/engine.py +43 -49
- foxes/core/farm_controller.py +22 -3
- foxes/core/farm_data_model.py +6 -2
- foxes/core/ground_model.py +19 -0
- foxes/core/model.py +2 -1
- foxes/core/partial_wakes_model.py +9 -21
- foxes/core/point_data_model.py +22 -2
- foxes/core/rotor_model.py +9 -21
- foxes/core/states.py +2 -17
- foxes/core/turbine_model.py +2 -18
- foxes/core/turbine_type.py +2 -18
- foxes/core/vertical_profile.py +8 -20
- foxes/core/wake_frame.py +9 -25
- foxes/core/wake_model.py +24 -20
- foxes/core/wake_superposition.py +19 -0
- foxes/data/__init__.py +1 -1
- foxes/data/static_data.py +0 -7
- foxes/engines/dask.py +4 -3
- foxes/engines/single.py +1 -1
- foxes/input/__init__.py +1 -1
- foxes/input/farm_layout/from_csv.py +3 -1
- foxes/input/farm_layout/from_file.py +10 -10
- foxes/input/farm_layout/from_json.py +4 -3
- foxes/input/farm_layout/grid.py +3 -3
- foxes/input/states/__init__.py +1 -1
- foxes/input/states/create/random_abl_states.py +5 -3
- foxes/input/states/field_data_nc.py +36 -15
- foxes/input/states/multi_height.py +26 -15
- foxes/input/states/one_point_flow.py +6 -5
- foxes/input/states/{scan_ws.py → scan.py} +42 -52
- foxes/input/states/single.py +15 -6
- foxes/input/states/slice_data_nc.py +18 -12
- foxes/input/states/states_table.py +17 -10
- foxes/input/yaml/__init__.py +3 -0
- foxes/input/yaml/dict.py +381 -0
- foxes/input/yaml/windio/__init__.py +4 -0
- foxes/input/{windio → yaml/windio}/get_states.py +7 -7
- foxes/input/{windio → yaml/windio}/read_attributes.py +61 -40
- foxes/input/{windio → yaml/windio}/read_farm.py +34 -43
- foxes/input/{windio → yaml/windio}/read_fields.py +11 -10
- foxes/input/yaml/windio/read_outputs.py +147 -0
- foxes/input/yaml/windio/windio.py +269 -0
- foxes/input/yaml/yaml.py +103 -0
- foxes/models/partial_wakes/axiwake.py +7 -6
- foxes/models/partial_wakes/centre.py +3 -2
- foxes/models/partial_wakes/segregated.py +5 -2
- foxes/models/point_models/set_uniform_data.py +5 -3
- foxes/models/rotor_models/centre.py +2 -2
- foxes/models/rotor_models/grid.py +5 -5
- foxes/models/rotor_models/levels.py +6 -6
- foxes/models/turbine_models/kTI_model.py +3 -1
- foxes/models/turbine_models/lookup_table.py +7 -4
- foxes/models/turbine_models/power_mask.py +14 -8
- foxes/models/turbine_models/sector_management.py +4 -2
- foxes/models/turbine_models/set_farm_vars.py +53 -23
- foxes/models/turbine_models/table_factors.py +8 -7
- foxes/models/turbine_models/yaw2yawm.py +0 -1
- foxes/models/turbine_models/yawm2yaw.py +0 -1
- foxes/models/turbine_types/CpCt_file.py +6 -3
- foxes/models/turbine_types/CpCt_from_two.py +6 -3
- foxes/models/turbine_types/PCt_file.py +7 -6
- foxes/models/turbine_types/PCt_from_two.py +11 -2
- foxes/models/turbine_types/TBL_file.py +3 -4
- foxes/models/turbine_types/wsrho2PCt_from_two.py +19 -11
- foxes/models/turbine_types/wsti2PCt_from_two.py +19 -11
- foxes/models/vertical_profiles/abl_log_neutral_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_stable_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_unstable_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_ws.py +1 -1
- foxes/models/wake_frames/dynamic_wakes.py +17 -9
- foxes/models/wake_frames/farm_order.py +4 -3
- foxes/models/wake_frames/rotor_wd.py +3 -1
- foxes/models/wake_frames/seq_dynamic_wakes.py +14 -7
- foxes/models/wake_frames/streamlines.py +9 -6
- foxes/models/wake_frames/timelines.py +21 -14
- foxes/models/wake_frames/yawed_wakes.py +3 -1
- foxes/models/wake_models/induction/vortex_sheet.py +0 -1
- foxes/models/wake_models/ti/crespo_hernandez.py +2 -1
- foxes/models/wake_models/wind/bastankhah14.py +3 -2
- foxes/models/wake_models/wind/bastankhah16.py +2 -1
- foxes/models/wake_models/wind/turbopark.py +9 -7
- foxes/models/wake_superpositions/ws_product.py +0 -1
- foxes/output/__init__.py +2 -1
- foxes/output/calc_points.py +7 -4
- foxes/output/farm_layout.py +30 -18
- foxes/output/farm_results_eval.py +61 -38
- foxes/output/grids.py +8 -7
- foxes/output/output.py +9 -20
- foxes/output/plt.py +19 -0
- foxes/output/results_writer.py +10 -11
- foxes/output/rose_plot.py +448 -224
- foxes/output/rotor_point_plots.py +7 -3
- foxes/output/slice_data.py +1 -1
- foxes/output/state_turbine_map.py +5 -1
- foxes/output/state_turbine_table.py +7 -3
- foxes/output/turbine_type_curves.py +7 -2
- foxes/utils/__init__.py +1 -2
- foxes/utils/dict.py +107 -3
- foxes/utils/geopandas_utils.py +3 -2
- foxes/utils/subclasses.py +69 -0
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/METADATA +18 -18
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/RECORD +145 -145
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/WHEEL +1 -1
- foxes-1.2.1.dist-info/entry_points.txt +3 -0
- tests/0_consistency/iterative/test_iterative.py +65 -67
- tests/0_consistency/partial_wakes/test_partial_wakes.py +58 -61
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +56 -53
- tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +41 -41
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +34 -34
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +57 -52
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +58 -54
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +80 -76
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +80 -76
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +58 -51
- tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +101 -103
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +67 -64
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +58 -54
- examples/windio/run.py +0 -29
- foxes/data/states/windio_timeseries_5000.nc +0 -0
- foxes/data/windio/DTU_10MW_turbine.yaml +0 -10
- foxes/data/windio/__init__.py +0 -0
- foxes/data/windio/windio_5turbines_timeseries.yaml +0 -79
- foxes/input/windio/__init__.py +0 -11
- foxes/input/windio/read_outputs.py +0 -172
- foxes/input/windio/runner.py +0 -183
- foxes/input/windio/windio.py +0 -193
- foxes/utils/windrose_plot.py +0 -152
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/LICENSE +0 -0
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/top_level.txt +0 -0
foxes/constants.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
|
|
3
1
|
XYH = "xyh"
|
|
4
2
|
""" The vector (x, y, height)
|
|
5
3
|
:group: foxes.variables
|
|
@@ -126,13 +124,13 @@ STATE_SOURCE_ORDERI = "state-source-orderi"
|
|
|
126
124
|
:group: foxes.constants
|
|
127
125
|
"""
|
|
128
126
|
|
|
129
|
-
DTYPE =
|
|
130
|
-
"""
|
|
127
|
+
DTYPE = "DTYPE"
|
|
128
|
+
"""Identifier for default double data type
|
|
131
129
|
:group: foxes.constants
|
|
132
130
|
"""
|
|
133
131
|
|
|
134
|
-
ITYPE =
|
|
135
|
-
"""
|
|
132
|
+
ITYPE = "ITYPE"
|
|
133
|
+
"""Identifier for default integer data type
|
|
136
134
|
:group: foxes.constants
|
|
137
135
|
"""
|
|
138
136
|
|
|
@@ -184,3 +182,14 @@ POP = "pop"
|
|
|
184
182
|
""" Population identifier
|
|
185
183
|
:group: foxes.constants
|
|
186
184
|
"""
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
WORK_DIR = "work_dir"
|
|
188
|
+
"""Identifier for the working directory
|
|
189
|
+
:group: foxes.constants
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
OUT_DIR = "out_dir"
|
|
193
|
+
"""Identifier for the default output directory
|
|
194
|
+
:group: foxes.constants
|
|
195
|
+
"""
|
foxes/core/algorithm.py
CHANGED
|
@@ -4,7 +4,8 @@ from abc import abstractmethod
|
|
|
4
4
|
|
|
5
5
|
from .model import Model
|
|
6
6
|
from foxes.data import StaticData
|
|
7
|
-
from foxes.utils import Dict,
|
|
7
|
+
from foxes.utils import Dict, new_instance
|
|
8
|
+
from foxes.config import config
|
|
8
9
|
import foxes.constants as FC
|
|
9
10
|
|
|
10
11
|
from .engine import Engine
|
|
@@ -33,7 +34,6 @@ class Algorithm(Model):
|
|
|
33
34
|
farm,
|
|
34
35
|
verbosity=1,
|
|
35
36
|
dbook=None,
|
|
36
|
-
engine=None,
|
|
37
37
|
**engine_pars,
|
|
38
38
|
):
|
|
39
39
|
"""
|
|
@@ -49,8 +49,6 @@ class Algorithm(Model):
|
|
|
49
49
|
The verbosity level, 0 means silent
|
|
50
50
|
dbook: foxes.DataBook, optional
|
|
51
51
|
The data book, or None for default
|
|
52
|
-
engine: str
|
|
53
|
-
The engine class name
|
|
54
52
|
engine_pars: dict, optional
|
|
55
53
|
Parameters for the engine constructor
|
|
56
54
|
|
|
@@ -68,14 +66,22 @@ class Algorithm(Model):
|
|
|
68
66
|
self.__idata_mem = Dict(name="idata_mem")
|
|
69
67
|
self.__chunk_store = Dict(name="chunk_store")
|
|
70
68
|
|
|
71
|
-
if
|
|
72
|
-
|
|
69
|
+
if len(engine_pars):
|
|
70
|
+
if "engine_type" in engine_pars:
|
|
71
|
+
if "engine" in engine_pars:
|
|
72
|
+
raise KeyError(
|
|
73
|
+
f"{self.name}: Expecting either 'engine' or 'engine_type', not both"
|
|
74
|
+
)
|
|
75
|
+
elif "engine" in engine_pars:
|
|
76
|
+
engine_pars["engine_type"] = engine_pars.pop("engine")
|
|
77
|
+
v = engine_pars.pop("verbosity", verbosity)
|
|
78
|
+
try:
|
|
79
|
+
e = Engine.new(verbosity=v, **engine_pars)
|
|
80
|
+
except TypeError as e:
|
|
81
|
+
print(f"\nError while interpreting engine_pars {engine_pars}\n")
|
|
82
|
+
raise e
|
|
73
83
|
self.print(f"Algorithm '{self.name}': Selecting engine '{e}'")
|
|
74
84
|
e.initialize()
|
|
75
|
-
elif len(engine_pars):
|
|
76
|
-
self.print(
|
|
77
|
-
f"Algorithm '{self.name}': Parameter 'engine' is None; ignoring engine parameters {engine_pars}"
|
|
78
|
-
)
|
|
79
85
|
|
|
80
86
|
@property
|
|
81
87
|
def farm(self):
|
|
@@ -171,6 +177,28 @@ class Algorithm(Model):
|
|
|
171
177
|
if self.verbosity >= vlim:
|
|
172
178
|
print(*args, **kwargs)
|
|
173
179
|
|
|
180
|
+
def print_deco(self, func_name=None, n_points=None):
|
|
181
|
+
"""
|
|
182
|
+
Helper function for printing model names
|
|
183
|
+
|
|
184
|
+
Parameters
|
|
185
|
+
----------
|
|
186
|
+
func_name: str, optional
|
|
187
|
+
Name of the calling function
|
|
188
|
+
n_points: int, optional
|
|
189
|
+
The number of points
|
|
190
|
+
|
|
191
|
+
"""
|
|
192
|
+
if self.verbosity > 0:
|
|
193
|
+
deco = "-" * 60
|
|
194
|
+
print(f"\n{deco}")
|
|
195
|
+
print(f" Algorithm: {type(self).__name__}")
|
|
196
|
+
if func_name is not None:
|
|
197
|
+
print(f" Running {self.name}: {func_name}")
|
|
198
|
+
print(deco)
|
|
199
|
+
print(f" n_states : {self.n_states}")
|
|
200
|
+
print(f" n_turbines: {self.n_turbines}")
|
|
201
|
+
|
|
174
202
|
def initialize(self):
|
|
175
203
|
"""
|
|
176
204
|
Initializes the algorithm.
|
|
@@ -375,6 +403,12 @@ class Algorithm(Model):
|
|
|
375
403
|
else:
|
|
376
404
|
idata = {"coords": {FC.STATE: states_indices}, "data_vars": {}}
|
|
377
405
|
|
|
406
|
+
if len(points.shape) == 2 and points.shape[1] == 3:
|
|
407
|
+
pts = np.zeros((n_states,) + points.shape, dtype=config.dtype_double)
|
|
408
|
+
pts[:] = points[None]
|
|
409
|
+
points = pts
|
|
410
|
+
del pts
|
|
411
|
+
|
|
378
412
|
if (
|
|
379
413
|
len(points.shape) != 3
|
|
380
414
|
or points.shape[0] != n_states
|
|
@@ -389,7 +423,7 @@ class Algorithm(Model):
|
|
|
389
423
|
)
|
|
390
424
|
idata["data_vars"][FC.TWEIGHTS] = (
|
|
391
425
|
(FC.TPOINT,),
|
|
392
|
-
np.array([1.0], dtype=
|
|
426
|
+
np.array([1.0], dtype=config.dtype_double),
|
|
393
427
|
)
|
|
394
428
|
|
|
395
429
|
return xr.Dataset(**idata)
|
|
@@ -914,22 +948,4 @@ class Algorithm(Model):
|
|
|
914
948
|
Additional parameters for the constructor
|
|
915
949
|
|
|
916
950
|
"""
|
|
917
|
-
|
|
918
|
-
if algo_type is None:
|
|
919
|
-
return None
|
|
920
|
-
|
|
921
|
-
allc = all_subclasses(cls)
|
|
922
|
-
found = algo_type in [scls.__name__ for scls in allc]
|
|
923
|
-
|
|
924
|
-
if found:
|
|
925
|
-
for scls in allc:
|
|
926
|
-
if scls.__name__ == algo_type:
|
|
927
|
-
return scls(*args, **kwargs)
|
|
928
|
-
|
|
929
|
-
else:
|
|
930
|
-
estr = (
|
|
931
|
-
"Algorithm type '{}' is not defined, available types are \n {}".format(
|
|
932
|
-
algo_type, sorted([i.__name__ for i in allc])
|
|
933
|
-
)
|
|
934
|
-
)
|
|
935
|
-
raise KeyError(estr)
|
|
951
|
+
return new_instance(cls, algo_type, *args, **kwargs)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
|
|
3
|
+
from foxes.utils import new_instance
|
|
3
4
|
from .model import Model
|
|
4
5
|
|
|
5
6
|
|
|
@@ -28,3 +29,20 @@ class AxialInductionModel(Model):
|
|
|
28
29
|
|
|
29
30
|
"""
|
|
30
31
|
pass
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def new(cls, induction_type, *args, **kwargs):
|
|
35
|
+
"""
|
|
36
|
+
Run-time axial induction model factory.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
induction_type: str
|
|
41
|
+
The selected derived class name
|
|
42
|
+
args: tuple, optional
|
|
43
|
+
Additional parameters for the constructor
|
|
44
|
+
kwargs: dict, optional
|
|
45
|
+
Additional parameters for the constructor
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
return new_instance(cls, induction_type, *args, **kwargs)
|
foxes/core/data.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.utils import Dict
|
|
4
|
+
from foxes.config import config
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
6
7
|
|
|
@@ -620,7 +621,7 @@ class TData(Data):
|
|
|
620
621
|
)
|
|
621
622
|
data[FC.TARGETS] = points[:, :, None, :]
|
|
622
623
|
dims[FC.TARGETS] = (FC.STATE, FC.TARGET, FC.TPOINT, FC.XYH)
|
|
623
|
-
data[FC.TWEIGHTS] = np.array([1], dtype=
|
|
624
|
+
data[FC.TWEIGHTS] = np.array([1], dtype=config.dtype_double)
|
|
624
625
|
dims[FC.TWEIGHTS] = (FC.TPOINT,)
|
|
625
626
|
return cls(data, dims, [FC.STATE, FC.TARGET], name=name, **kwargs)
|
|
626
627
|
|
foxes/core/engine.py
CHANGED
|
@@ -5,7 +5,8 @@ from tqdm import tqdm
|
|
|
5
5
|
from xarray import Dataset
|
|
6
6
|
|
|
7
7
|
from foxes.core import MData, FData, TData
|
|
8
|
-
from foxes.utils import
|
|
8
|
+
from foxes.utils import new_instance
|
|
9
|
+
from foxes.config import config
|
|
9
10
|
import foxes.constants as FC
|
|
10
11
|
|
|
11
12
|
__global_engine_data__ = dict(
|
|
@@ -246,26 +247,21 @@ class Engine(ABC):
|
|
|
246
247
|
if int(n_states / n_chunks_states) > chunk_size_states:
|
|
247
248
|
n_chunks_states += 1
|
|
248
249
|
chunk_size_states = int(n_states / n_chunks_states)
|
|
249
|
-
chunk_sizes_states = np.full(n_chunks_states, chunk_size_states)
|
|
250
|
-
extra = n_states - n_chunks_states * chunk_size_states
|
|
251
|
-
if extra > 0:
|
|
252
|
-
chunk_sizes_states[-extra:] += 1
|
|
253
|
-
|
|
254
|
-
s = np.sum(chunk_sizes_states)
|
|
255
|
-
assert (
|
|
256
|
-
s == n_states
|
|
257
|
-
), f"States count mismatch: Expecting {n_states}, chunks sum is {s}. Chunks: {[int(c) for c in chunk_sizes_states]}"
|
|
258
250
|
|
|
259
251
|
# determine points chunks:
|
|
260
252
|
chunk_sizes_targets = [n_targets]
|
|
261
253
|
if n_targets > 1:
|
|
262
254
|
if self.chunk_size_points is None:
|
|
263
|
-
if
|
|
264
|
-
n_chunks_targets = min(self.n_procs, n_targets)
|
|
265
|
-
chunk_size_targets = max(int(n_targets / self.n_procs), 1)
|
|
266
|
-
else:
|
|
255
|
+
if n_targets < max(n_states, 1000):
|
|
267
256
|
chunk_size_targets = n_targets
|
|
268
257
|
n_chunks_targets = 1
|
|
258
|
+
else:
|
|
259
|
+
n_chunks_targets = min(self.n_procs, n_targets)
|
|
260
|
+
chunk_size_targets = max(int(n_targets / self.n_procs), 1)
|
|
261
|
+
if self.chunk_size_states is None and n_chunks_states > 1:
|
|
262
|
+
while chunk_size_states * chunk_size_targets > n_targets:
|
|
263
|
+
n_chunks_states += 1
|
|
264
|
+
chunk_size_states = int(n_states / n_chunks_states)
|
|
269
265
|
else:
|
|
270
266
|
chunk_size_targets = min(n_targets, self.chunk_size_points)
|
|
271
267
|
n_chunks_targets = max(int(n_targets / chunk_size_targets), 1)
|
|
@@ -282,6 +278,16 @@ class Engine(ABC):
|
|
|
282
278
|
s == n_targets
|
|
283
279
|
), f"Targets count mismatch: Expecting {n_targets}, chunks sum is {s}. Chunks: {[int(c) for c in chunk_sizes_targets]}"
|
|
284
280
|
|
|
281
|
+
chunk_sizes_states = np.full(n_chunks_states, chunk_size_states)
|
|
282
|
+
extra = n_states - n_chunks_states * chunk_size_states
|
|
283
|
+
if extra > 0:
|
|
284
|
+
chunk_sizes_states[-extra:] += 1
|
|
285
|
+
|
|
286
|
+
s = np.sum(chunk_sizes_states)
|
|
287
|
+
assert (
|
|
288
|
+
s == n_states
|
|
289
|
+
), f"States count mismatch: Expecting {n_states}, chunks sum is {s}. Chunks: {[int(c) for c in chunk_sizes_states]}"
|
|
290
|
+
|
|
285
291
|
return chunk_sizes_states, chunk_sizes_targets
|
|
286
292
|
|
|
287
293
|
def get_chunk_input_data(
|
|
@@ -342,7 +348,7 @@ class Engine(ABC):
|
|
|
342
348
|
n_states = i1_states - i0_states
|
|
343
349
|
for o in set(out_vars).difference(data.keys()):
|
|
344
350
|
data[o] = np.full(
|
|
345
|
-
(n_states, algo.n_turbines), np.nan, dtype=
|
|
351
|
+
(n_states, algo.n_turbines), np.nan, dtype=config.dtype_double
|
|
346
352
|
)
|
|
347
353
|
dims[o] = (FC.STATE, FC.TURBINE)
|
|
348
354
|
|
|
@@ -366,7 +372,9 @@ class Engine(ABC):
|
|
|
366
372
|
n_states = i1_states - i0_states
|
|
367
373
|
n_targets = i1_targets - i0_targets
|
|
368
374
|
for o in set(out_vars).difference(data.keys()):
|
|
369
|
-
data[o] = np.full(
|
|
375
|
+
data[o] = np.full(
|
|
376
|
+
(n_states, n_targets, 1), np.nan, dtype=config.dtype_double
|
|
377
|
+
)
|
|
370
378
|
dims[o] = (FC.STATE, FC.TARGET, FC.TPOINT)
|
|
371
379
|
|
|
372
380
|
tdata = TData.from_dataset(
|
|
@@ -538,36 +546,24 @@ class Engine(ABC):
|
|
|
538
546
|
"""
|
|
539
547
|
|
|
540
548
|
if engine_type is None:
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
found = engine_type in [scls.__name__ for scls in allc]
|
|
560
|
-
|
|
561
|
-
if found:
|
|
562
|
-
for scls in allc:
|
|
563
|
-
if scls.__name__ == engine_type:
|
|
564
|
-
return scls(*args, **kwargs)
|
|
565
|
-
|
|
566
|
-
else:
|
|
567
|
-
estr = "engine type '{}' is not defined, available types are \n {}".format(
|
|
568
|
-
engine_type, sorted([i.__name__ for i in allc])
|
|
569
|
-
)
|
|
570
|
-
raise KeyError(estr)
|
|
549
|
+
engine_type = "default"
|
|
550
|
+
|
|
551
|
+
engine_type = dict(
|
|
552
|
+
default="DefaultEngine",
|
|
553
|
+
threads="ThreadsEngine",
|
|
554
|
+
process="ProcessEngine",
|
|
555
|
+
xarray="XArrayEngine",
|
|
556
|
+
dask="DaskEngine",
|
|
557
|
+
multiprocess="MultiprocessEngine",
|
|
558
|
+
local_cluster="LocalClusterEngine",
|
|
559
|
+
slurm_cluster="SlurmClusterEngine",
|
|
560
|
+
mpi="MPIEngine",
|
|
561
|
+
ray="RayEngine",
|
|
562
|
+
numpy="NumpyEngine",
|
|
563
|
+
single="SingleChunkEngine",
|
|
564
|
+
).get(engine_type, engine_type)
|
|
565
|
+
|
|
566
|
+
return new_instance(cls, engine_type, *args, **kwargs)
|
|
571
567
|
|
|
572
568
|
|
|
573
569
|
def get_engine(error=True, default=True):
|
|
@@ -602,9 +598,7 @@ def get_engine(error=True, default=True):
|
|
|
602
598
|
default.initialize()
|
|
603
599
|
return default
|
|
604
600
|
elif isinstance(default, bool) and default:
|
|
605
|
-
engine = Engine.new(
|
|
606
|
-
engine_type="DefaultEngine", chunk_size_points=20000, verbosity=0
|
|
607
|
-
)
|
|
601
|
+
engine = Engine.new(engine_type="DefaultEngine", verbosity=1)
|
|
608
602
|
print(f"Selecting '{engine}'")
|
|
609
603
|
engine.initialize()
|
|
610
604
|
return engine
|
foxes/core/farm_controller.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
|
+
from foxes.config import config
|
|
4
|
+
import foxes.constants as FC
|
|
5
|
+
from foxes.utils import new_instance
|
|
6
|
+
|
|
3
7
|
from .farm_data_model import FarmDataModelList, FarmDataModel
|
|
4
8
|
from .turbine_model import TurbineModel
|
|
5
9
|
from .turbine_type import TurbineType
|
|
6
|
-
import foxes.constants as FC
|
|
7
|
-
import foxes.variables as FV
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
class FarmController(FarmDataModel):
|
|
@@ -122,7 +124,7 @@ class FarmController(FarmDataModel):
|
|
|
122
124
|
tmodels = []
|
|
123
125
|
tmsels = []
|
|
124
126
|
mnames = [[m.name for m in mlist] for mlist in models]
|
|
125
|
-
tmis = np.zeros(algo.n_turbines, dtype=
|
|
127
|
+
tmis = np.zeros(algo.n_turbines, dtype=config.dtype_int)
|
|
126
128
|
news = True
|
|
127
129
|
while news:
|
|
128
130
|
news = False
|
|
@@ -394,3 +396,20 @@ class FarmController(FarmDataModel):
|
|
|
394
396
|
"""
|
|
395
397
|
super().finalize(algo, verbosity)
|
|
396
398
|
self.turbine_model_names = None
|
|
399
|
+
|
|
400
|
+
@classmethod
|
|
401
|
+
def new(cls, controller_type, *args, **kwargs):
|
|
402
|
+
"""
|
|
403
|
+
Run-time farm controller factory.
|
|
404
|
+
|
|
405
|
+
Parameters
|
|
406
|
+
----------
|
|
407
|
+
controller_type: str
|
|
408
|
+
The selected derived class name
|
|
409
|
+
args: tuple, optional
|
|
410
|
+
Additional parameters for the constructor
|
|
411
|
+
kwargs: dict, optional
|
|
412
|
+
Additional parameters for the constructor
|
|
413
|
+
|
|
414
|
+
"""
|
|
415
|
+
return new_instance(cls, controller_type, *args, **kwargs)
|
foxes/core/farm_data_model.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
import numpy as np
|
|
3
3
|
|
|
4
|
-
from .
|
|
4
|
+
from foxes.config import config
|
|
5
5
|
import foxes.constants as FC
|
|
6
6
|
|
|
7
|
+
from .data_calc_model import DataCalcModel
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
class FarmDataModel(DataCalcModel):
|
|
9
11
|
"""
|
|
@@ -82,7 +84,9 @@ class FarmDataModel(DataCalcModel):
|
|
|
82
84
|
n_turbines = fdata.n_turbines
|
|
83
85
|
for v in self.output_farm_vars(algo):
|
|
84
86
|
if v not in fdata:
|
|
85
|
-
fdata[v] = np.full(
|
|
87
|
+
fdata[v] = np.full(
|
|
88
|
+
(n_states, n_turbines), np.nan, dtype=config.dtype_double
|
|
89
|
+
)
|
|
86
90
|
fdata.dims[v] = (FC.STATE, FC.TURBINE)
|
|
87
91
|
|
|
88
92
|
@abstractmethod
|
foxes/core/ground_model.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from foxes.utils import new_instance
|
|
2
|
+
|
|
1
3
|
from .model import Model
|
|
2
4
|
|
|
3
5
|
|
|
@@ -252,3 +254,20 @@ class GroundModel(Model):
|
|
|
252
254
|
|
|
253
255
|
"""
|
|
254
256
|
wmodel.finalize_wake_deltas(algo, mdata, fdata, amb_results, wake_deltas)
|
|
257
|
+
|
|
258
|
+
@classmethod
|
|
259
|
+
def new(cls, ground_type, *args, **kwargs):
|
|
260
|
+
"""
|
|
261
|
+
Run-time ground model factory.
|
|
262
|
+
|
|
263
|
+
Parameters
|
|
264
|
+
----------
|
|
265
|
+
ground_type: str
|
|
266
|
+
The selected derived class name
|
|
267
|
+
args: tuple, optional
|
|
268
|
+
Additional parameters for the constructor
|
|
269
|
+
kwargs: dict, optional
|
|
270
|
+
Additional parameters for the constructor
|
|
271
|
+
|
|
272
|
+
"""
|
|
273
|
+
return new_instance(cls, ground_type, *args, **kwargs)
|
foxes/core/model.py
CHANGED
|
@@ -2,6 +2,7 @@ import numpy as np
|
|
|
2
2
|
from abc import ABC
|
|
3
3
|
from itertools import count
|
|
4
4
|
|
|
5
|
+
from foxes.config import config
|
|
5
6
|
import foxes.constants as FC
|
|
6
7
|
|
|
7
8
|
|
|
@@ -522,7 +523,7 @@ class Model(ABC):
|
|
|
522
523
|
if target == FC.STATE_TARGET and tdata.n_tpoints != 1:
|
|
523
524
|
# find the mean index and round it to nearest integer:
|
|
524
525
|
sts = tdata.tpoint_mean(FC.STATES_SEL)[:, :, None]
|
|
525
|
-
sts = (sts + 0.5).astype(
|
|
526
|
+
sts = (sts + 0.5).astype(config.dtype_int)
|
|
526
527
|
sel = sts < i0
|
|
527
528
|
if np.any(sel):
|
|
528
529
|
if not hasattr(algo, "farm_results_downwind"):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
|
|
3
|
-
from foxes.utils import
|
|
3
|
+
from foxes.utils import new_instance
|
|
4
4
|
|
|
5
5
|
from .model import Model
|
|
6
6
|
|
|
@@ -189,30 +189,18 @@ class PartialWakesModel(Model):
|
|
|
189
189
|
pass
|
|
190
190
|
|
|
191
191
|
@classmethod
|
|
192
|
-
def new(cls,
|
|
192
|
+
def new(cls, pwakes_type, *args, **kwargs):
|
|
193
193
|
"""
|
|
194
|
-
Run-time partial wakes factory.
|
|
194
|
+
Run-time partial wakes model factory.
|
|
195
195
|
|
|
196
196
|
Parameters
|
|
197
197
|
----------
|
|
198
|
-
|
|
198
|
+
pwakes_type: str
|
|
199
199
|
The selected derived class name
|
|
200
|
+
args: tuple, optional
|
|
201
|
+
Additional parameters for the constructor
|
|
202
|
+
kwargs: dict, optional
|
|
203
|
+
Additional parameters for the constructor
|
|
200
204
|
|
|
201
205
|
"""
|
|
202
|
-
|
|
203
|
-
if pwake_type is None:
|
|
204
|
-
return None
|
|
205
|
-
|
|
206
|
-
allc = all_subclasses(cls)
|
|
207
|
-
found = pwake_type in [scls.__name__ for scls in allc]
|
|
208
|
-
|
|
209
|
-
if found:
|
|
210
|
-
for scls in allc:
|
|
211
|
-
if scls.__name__ == pwake_type:
|
|
212
|
-
return scls(**kwargs)
|
|
213
|
-
|
|
214
|
-
else:
|
|
215
|
-
estr = "Partial wakes model type '{}' is not defined, available types are \n {}".format(
|
|
216
|
-
pwake_type, sorted([i.__name__ for i in allc])
|
|
217
|
-
)
|
|
218
|
-
raise KeyError(estr)
|
|
206
|
+
return new_instance(cls, pwakes_type, *args, **kwargs)
|
foxes/core/point_data_model.py
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from abc import abstractmethod
|
|
3
3
|
|
|
4
|
-
from .
|
|
4
|
+
from foxes.config import config
|
|
5
|
+
from foxes.utils import new_instance
|
|
5
6
|
import foxes.constants as FC
|
|
6
7
|
|
|
8
|
+
from .data_calc_model import DataCalcModel
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
class PointDataModel(DataCalcModel):
|
|
9
12
|
"""
|
|
@@ -60,7 +63,7 @@ class PointDataModel(DataCalcModel):
|
|
|
60
63
|
tdata[v] = np.full(
|
|
61
64
|
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
62
65
|
np.nan,
|
|
63
|
-
dtype=
|
|
66
|
+
dtype=config.dtype_double,
|
|
64
67
|
)
|
|
65
68
|
tdata.dims[v] = (FC.STATE, FC.TARGET, FC.TPOINT)
|
|
66
69
|
|
|
@@ -261,3 +264,20 @@ class PointDataModelList(PointDataModel):
|
|
|
261
264
|
tdata.update(res)
|
|
262
265
|
|
|
263
266
|
return {v: tdata[v] for v in self.output_point_vars(algo)}
|
|
267
|
+
|
|
268
|
+
@classmethod
|
|
269
|
+
def new(cls, model_type, *args, **kwargs):
|
|
270
|
+
"""
|
|
271
|
+
Run-time point model factory.
|
|
272
|
+
|
|
273
|
+
Parameters
|
|
274
|
+
----------
|
|
275
|
+
model_type: str
|
|
276
|
+
The selected derived class name
|
|
277
|
+
args: tuple, optional
|
|
278
|
+
Additional parameters for the constructor
|
|
279
|
+
kwargs: dict, optional
|
|
280
|
+
Additional parameters for the constructor
|
|
281
|
+
|
|
282
|
+
"""
|
|
283
|
+
return new_instance(cls, model_type, *args, **kwargs)
|
foxes/core/rotor_model.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from abc import abstractmethod
|
|
3
3
|
|
|
4
|
+
from foxes.config import config
|
|
5
|
+
from foxes.utils import wd2uv, uv2wd, new_instance
|
|
6
|
+
|
|
4
7
|
import foxes.variables as FV
|
|
5
8
|
import foxes.constants as FC
|
|
6
|
-
from .farm_data_model import FarmDataModel
|
|
7
|
-
from foxes.utils import wd2uv, uv2wd, all_subclasses
|
|
8
9
|
|
|
9
10
|
from .data import TData
|
|
11
|
+
from .farm_data_model import FarmDataModel
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class RotorModel(FarmDataModel):
|
|
@@ -146,14 +148,16 @@ class RotorModel(FarmDataModel):
|
|
|
146
148
|
dpoints = self.design_points()
|
|
147
149
|
D = fdata[FV.D]
|
|
148
150
|
|
|
149
|
-
rax = np.zeros((n_states, n_turbines, 3, 3), dtype=
|
|
151
|
+
rax = np.zeros((n_states, n_turbines, 3, 3), dtype=config.dtype_double)
|
|
150
152
|
n = rax[:, :, 0, 0:2]
|
|
151
153
|
m = rax[:, :, 1, 0:2]
|
|
152
154
|
n[:] = wd2uv(fdata[FV.YAW], axis=-1)
|
|
153
155
|
m[:] = np.stack([-n[:, :, 1], n[:, :, 0]], axis=-1)
|
|
154
156
|
rax[:, :, 2, 2] = 1
|
|
155
157
|
|
|
156
|
-
points = np.zeros(
|
|
158
|
+
points = np.zeros(
|
|
159
|
+
(n_states, n_turbines, n_points, 3), dtype=config.dtype_double
|
|
160
|
+
)
|
|
157
161
|
points[:] = fdata[FV.TXYH][:, :, None, :]
|
|
158
162
|
points[:] += (
|
|
159
163
|
0.5 * D[:, :, None, None] * np.einsum("stad,pa->stpd", rax, dpoints)
|
|
@@ -413,20 +417,4 @@ class RotorModel(FarmDataModel):
|
|
|
413
417
|
Additional parameters for constructor
|
|
414
418
|
|
|
415
419
|
"""
|
|
416
|
-
|
|
417
|
-
if rmodel_type is None:
|
|
418
|
-
return None
|
|
419
|
-
|
|
420
|
-
allc = all_subclasses(cls)
|
|
421
|
-
found = rmodel_type in [scls.__name__ for scls in allc]
|
|
422
|
-
|
|
423
|
-
if found:
|
|
424
|
-
for scls in allc:
|
|
425
|
-
if scls.__name__ == rmodel_type:
|
|
426
|
-
return scls(*args, **kwargs)
|
|
427
|
-
|
|
428
|
-
else:
|
|
429
|
-
estr = "Rotor model type '{}' is not defined, available types are \n {}".format(
|
|
430
|
-
rmodel_type, sorted([i.__name__ for i in allc])
|
|
431
|
-
)
|
|
432
|
-
raise KeyError(estr)
|
|
420
|
+
return new_instance(cls, rmodel_type, *args, **kwargs)
|
foxes/core/states.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
|
|
3
3
|
from .point_data_model import PointDataModel, PointDataModelList
|
|
4
|
-
from foxes.utils import
|
|
4
|
+
from foxes.utils import new_instance
|
|
5
5
|
import foxes.variables as FV
|
|
6
6
|
import foxes.constants as FC
|
|
7
7
|
|
|
@@ -163,22 +163,7 @@ class States(PointDataModel):
|
|
|
163
163
|
Additional parameters for constructor
|
|
164
164
|
|
|
165
165
|
"""
|
|
166
|
-
|
|
167
|
-
if states_type is None:
|
|
168
|
-
return None
|
|
169
|
-
|
|
170
|
-
allc = all_subclasses(cls)
|
|
171
|
-
found = states_type in [scls.__name__ for scls in allc]
|
|
172
|
-
|
|
173
|
-
if found:
|
|
174
|
-
for scls in allc:
|
|
175
|
-
if scls.__name__ == states_type:
|
|
176
|
-
return scls(*args, **kwargs)
|
|
177
|
-
else:
|
|
178
|
-
estr = "States type '{}' is not defined, available types are \n {}".format(
|
|
179
|
-
states_type, sorted([i.__name__ for i in allc])
|
|
180
|
-
)
|
|
181
|
-
raise KeyError(estr)
|
|
166
|
+
return new_instance(cls, states_type, *args, **kwargs)
|
|
182
167
|
|
|
183
168
|
|
|
184
169
|
class ExtendedStates(States):
|
foxes/core/turbine_model.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
|
|
3
|
-
from foxes.utils import
|
|
3
|
+
from foxes.utils import new_instance
|
|
4
4
|
|
|
5
5
|
from .farm_data_model import FarmDataModel
|
|
6
6
|
|
|
@@ -60,20 +60,4 @@ class TurbineModel(FarmDataModel):
|
|
|
60
60
|
Additional parameters for constructor
|
|
61
61
|
|
|
62
62
|
"""
|
|
63
|
-
|
|
64
|
-
if tmodel_type is None:
|
|
65
|
-
return None
|
|
66
|
-
|
|
67
|
-
allc = all_subclasses(cls)
|
|
68
|
-
found = tmodel_type in [scls.__name__ for scls in allc]
|
|
69
|
-
|
|
70
|
-
if found:
|
|
71
|
-
for scls in allc:
|
|
72
|
-
if scls.__name__ == tmodel_type:
|
|
73
|
-
return scls(*args, **kwargs)
|
|
74
|
-
|
|
75
|
-
else:
|
|
76
|
-
estr = "Turbine model type '{}' is not defined, available types are \n {}".format(
|
|
77
|
-
tmodel_type, sorted([i.__name__ for i in allc])
|
|
78
|
-
)
|
|
79
|
-
raise KeyError(estr)
|
|
63
|
+
return new_instance(cls, tmodel_type, *args, **kwargs)
|