foxes 1.3__py3-none-any.whl → 1.4__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 -3
- examples/abl_states/run.py +2 -2
- examples/compare_rotors_pwakes/run.py +1 -1
- examples/compare_wakes/run.py +1 -2
- examples/dyn_wakes/run.py +29 -6
- examples/induction/run.py +3 -3
- examples/multi_height/run.py +1 -1
- examples/power_mask/run.py +2 -2
- examples/quickstart/run.py +0 -1
- examples/random_timeseries/run.py +3 -4
- examples/scan_row/run.py +3 -3
- examples/sequential/run.py +33 -10
- examples/single_state/run.py +3 -4
- examples/states_lookup_table/run.py +3 -3
- examples/streamline_wakes/run.py +27 -4
- examples/tab_file/run.py +3 -3
- examples/timelines/run.py +29 -5
- examples/timeseries/run.py +3 -3
- examples/timeseries_slurm/run.py +3 -3
- examples/wind_rose/run.py +3 -3
- examples/yawed_wake/run.py +16 -8
- foxes/__init__.py +21 -17
- foxes/algorithms/__init__.py +6 -6
- foxes/algorithms/downwind/__init__.py +2 -2
- foxes/algorithms/downwind/downwind.py +44 -12
- foxes/algorithms/downwind/models/__init__.py +6 -6
- foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -9
- foxes/algorithms/downwind/models/init_farm_data.py +0 -1
- foxes/algorithms/downwind/models/point_wakes_calc.py +7 -13
- foxes/algorithms/downwind/models/set_amb_point_results.py +6 -6
- foxes/algorithms/iterative/__init__.py +7 -3
- foxes/algorithms/iterative/iterative.py +1 -2
- foxes/algorithms/iterative/models/__init__.py +7 -3
- foxes/algorithms/iterative/models/farm_wakes_calc.py +9 -5
- foxes/algorithms/sequential/__init__.py +3 -3
- foxes/algorithms/sequential/models/__init__.py +2 -2
- foxes/algorithms/sequential/sequential.py +3 -4
- foxes/config/__init__.py +5 -1
- foxes/constants.py +16 -0
- foxes/core/__init__.py +45 -22
- foxes/core/algorithm.py +0 -1
- foxes/core/data.py +19 -18
- foxes/core/engine.py +9 -13
- foxes/core/farm_controller.py +2 -2
- foxes/core/ground_model.py +4 -13
- foxes/core/model.py +5 -5
- foxes/core/partial_wakes_model.py +147 -10
- foxes/core/point_data_model.py +2 -3
- foxes/core/rotor_model.py +3 -3
- foxes/core/states.py +2 -3
- foxes/core/turbine.py +2 -1
- foxes/core/wake_deflection.py +130 -0
- foxes/core/wake_model.py +222 -9
- foxes/core/wake_superposition.py +122 -4
- foxes/core/wind_farm.py +6 -6
- foxes/data/__init__.py +7 -2
- foxes/data/states/weibull_sectors_12.csv +13 -0
- foxes/data/states/weibull_sectors_12.nc +0 -0
- foxes/engines/__init__.py +14 -15
- foxes/engines/dask.py +39 -14
- foxes/engines/numpy.py +0 -3
- foxes/input/__init__.py +3 -3
- foxes/input/farm_layout/__init__.py +8 -8
- foxes/input/farm_layout/from_csv.py +1 -1
- foxes/input/farm_layout/ring.py +0 -1
- foxes/input/states/__init__.py +22 -12
- foxes/input/states/create/__init__.py +3 -2
- foxes/input/states/field_data_nc.py +10 -24
- foxes/input/states/multi_height.py +9 -6
- foxes/input/states/one_point_flow.py +0 -4
- foxes/input/states/single.py +1 -1
- foxes/input/states/states_table.py +10 -7
- foxes/input/states/weibull_sectors.py +225 -0
- foxes/input/states/wrg_states.py +7 -5
- foxes/input/yaml/__init__.py +9 -3
- foxes/input/yaml/dict.py +19 -19
- foxes/input/yaml/windio/__init__.py +10 -5
- foxes/input/yaml/windio/read_attributes.py +2 -2
- foxes/input/yaml/windio/read_farm.py +5 -5
- foxes/input/yaml/windio/read_fields.py +4 -2
- foxes/input/yaml/windio/read_site.py +52 -0
- foxes/input/yaml/windio/windio.py +1 -1
- foxes/models/__init__.py +15 -14
- foxes/models/axial_induction/__init__.py +2 -2
- foxes/models/farm_controllers/__init__.py +1 -1
- foxes/models/farm_models/__init__.py +1 -1
- foxes/models/ground_models/__init__.py +3 -2
- foxes/models/ground_models/wake_mirror.py +3 -3
- foxes/models/model_book.py +175 -49
- foxes/models/partial_wakes/__init__.py +6 -6
- foxes/models/partial_wakes/axiwake.py +30 -5
- foxes/models/partial_wakes/centre.py +47 -0
- foxes/models/partial_wakes/rotor_points.py +41 -11
- foxes/models/partial_wakes/segregated.py +2 -25
- foxes/models/partial_wakes/top_hat.py +27 -2
- foxes/models/point_models/__init__.py +4 -4
- foxes/models/rotor_models/__init__.py +3 -3
- foxes/models/turbine_models/__init__.py +11 -11
- foxes/models/turbine_models/set_farm_vars.py +0 -1
- foxes/models/turbine_types/PCt_file.py +0 -2
- foxes/models/turbine_types/PCt_from_two.py +0 -2
- foxes/models/turbine_types/__init__.py +9 -9
- foxes/models/vertical_profiles/__init__.py +7 -7
- foxes/models/wake_deflections/__init__.py +3 -0
- foxes/models/{wake_frames/yawed_wakes.py → wake_deflections/bastankhah2016.py} +32 -111
- foxes/models/wake_deflections/jimenez.py +277 -0
- foxes/models/wake_deflections/no_deflection.py +94 -0
- foxes/models/wake_frames/__init__.py +6 -7
- foxes/models/wake_frames/dynamic_wakes.py +12 -3
- foxes/models/wake_frames/rotor_wd.py +3 -1
- foxes/models/wake_frames/seq_dynamic_wakes.py +41 -7
- foxes/models/wake_frames/streamlines.py +8 -6
- foxes/models/wake_frames/timelines.py +9 -3
- foxes/models/wake_models/__init__.py +7 -7
- foxes/models/wake_models/dist_sliced.py +50 -84
- foxes/models/wake_models/gaussian.py +20 -0
- foxes/models/wake_models/induction/__init__.py +5 -5
- foxes/models/wake_models/induction/rankine_half_body.py +30 -71
- foxes/models/wake_models/induction/rathmann.py +65 -64
- foxes/models/wake_models/induction/self_similar.py +65 -68
- foxes/models/wake_models/induction/self_similar2020.py +0 -3
- foxes/models/wake_models/induction/vortex_sheet.py +71 -75
- foxes/models/wake_models/ti/__init__.py +2 -2
- foxes/models/wake_models/ti/crespo_hernandez.py +5 -3
- foxes/models/wake_models/ti/iec_ti.py +6 -4
- foxes/models/wake_models/top_hat.py +58 -7
- foxes/models/wake_models/wind/__init__.py +6 -4
- foxes/models/wake_models/wind/bastankhah14.py +25 -7
- foxes/models/wake_models/wind/bastankhah16.py +35 -3
- foxes/models/wake_models/wind/jensen.py +15 -2
- foxes/models/wake_models/wind/turbopark.py +28 -2
- foxes/models/wake_superpositions/__init__.py +18 -9
- foxes/models/wake_superpositions/ti_linear.py +4 -4
- foxes/models/wake_superpositions/ti_max.py +4 -4
- foxes/models/wake_superpositions/ti_pow.py +4 -4
- foxes/models/wake_superpositions/ti_quadratic.py +4 -4
- foxes/models/wake_superpositions/wind_vector.py +257 -0
- foxes/models/wake_superpositions/ws_linear.py +9 -10
- foxes/models/wake_superpositions/ws_max.py +8 -8
- foxes/models/wake_superpositions/ws_pow.py +8 -8
- foxes/models/wake_superpositions/ws_product.py +4 -4
- foxes/models/wake_superpositions/ws_quadratic.py +8 -8
- foxes/output/__init__.py +21 -19
- foxes/output/farm_layout.py +2 -2
- foxes/output/farm_results_eval.py +15 -15
- foxes/output/flow_plots_2d/__init__.py +2 -2
- foxes/output/flow_plots_2d/get_fig.py +4 -2
- foxes/output/rose_plot.py +3 -3
- foxes/output/seq_plugins/__init__.py +2 -2
- foxes/output/seq_plugins/seq_flow_ani_plugin.py +0 -3
- foxes/output/seq_plugins/seq_wake_debug_plugin.py +0 -1
- foxes/output/turbine_type_curves.py +7 -8
- foxes/utils/__init__.py +37 -19
- foxes/utils/abl/__init__.py +4 -4
- foxes/utils/cubic_roots.py +1 -1
- foxes/utils/data_book.py +4 -3
- foxes/utils/dict.py +3 -3
- foxes/utils/exec_python.py +5 -5
- foxes/utils/factory.py +1 -3
- foxes/utils/geom2d/__init__.py +7 -5
- foxes/utils/geopandas_utils.py +2 -2
- foxes/utils/pandas_utils.py +4 -3
- foxes/utils/tab_files.py +0 -1
- foxes/utils/weibull.py +28 -0
- foxes/utils/wrg_utils.py +3 -1
- foxes/utils/xarray_utils.py +9 -2
- foxes/variables.py +67 -9
- {foxes-1.3.dist-info → foxes-1.4.dist-info}/METADATA +6 -15
- foxes-1.4.dist-info/RECORD +320 -0
- {foxes-1.3.dist-info → foxes-1.4.dist-info}/WHEEL +1 -1
- tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +2 -3
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +1 -1
- tests/1_verification/flappy_0_6/abl_states/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +0 -2
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +0 -1
- tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +0 -2
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +0 -1
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +0 -1
- foxes/output/round.py +0 -10
- foxes/utils/pandas_helpers.py +0 -178
- foxes-1.3.dist-info/RECORD +0 -313
- {foxes-1.3.dist-info → foxes-1.4.dist-info}/entry_points.txt +0 -0
- {foxes-1.3.dist-info → foxes-1.4.dist-info/licenses}/LICENSE +0 -0
- {foxes-1.3.dist-info → foxes-1.4.dist-info}/top_level.txt +0 -0
foxes/__init__.py
CHANGED
|
@@ -3,24 +3,28 @@ Farm Optimization and eXtended yield Evaluation Software
|
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from .config import config
|
|
7
|
-
from .
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
PCTCURVE,
|
|
15
|
-
StaticData,
|
|
16
|
-
) # noqa: F401
|
|
6
|
+
from .config import config as config
|
|
7
|
+
from .config import get_path as get_path
|
|
8
|
+
from .core import Engine as Engine
|
|
9
|
+
from .core import WindFarm as WindFarm
|
|
10
|
+
from .core import Turbine as Turbine
|
|
11
|
+
from .core import get_engine as get_engine
|
|
12
|
+
from .core import reset_engine as reset_engine
|
|
13
|
+
from .models import ModelBook as ModelBook
|
|
17
14
|
|
|
18
|
-
from . import
|
|
19
|
-
from . import
|
|
20
|
-
from . import
|
|
21
|
-
from . import
|
|
22
|
-
from . import
|
|
23
|
-
from . import
|
|
15
|
+
from .data import parse_Pct_file_name as parse_Pct_file_name
|
|
16
|
+
from .data import parse_Pct_two_files as parse_Pct_two_files
|
|
17
|
+
from .data import FARM as FARM
|
|
18
|
+
from .data import STATES as STATES
|
|
19
|
+
from .data import PCTCURVE as PCTCURVE
|
|
20
|
+
from .data import StaticData as StaticData
|
|
21
|
+
|
|
22
|
+
from . import algorithms as algorithms
|
|
23
|
+
from . import engines as engines
|
|
24
|
+
from . import models as models
|
|
25
|
+
from . import input as input
|
|
26
|
+
from . import output as output
|
|
27
|
+
from . import utils as utils
|
|
24
28
|
|
|
25
29
|
import importlib
|
|
26
30
|
from pathlib import Path
|
foxes/algorithms/__init__.py
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Algorithms define the main calculation routines.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from .downwind.downwind import Downwind
|
|
6
|
-
from .iterative.iterative import Iterative
|
|
7
|
-
from .sequential import Sequential
|
|
5
|
+
from .downwind.downwind import Downwind as Downwind
|
|
6
|
+
from .iterative.iterative import Iterative as Iterative
|
|
7
|
+
from .sequential import Sequential as Sequential
|
|
8
8
|
|
|
9
|
-
from . import downwind
|
|
10
|
-
from . import iterative
|
|
11
|
-
from . import sequential
|
|
9
|
+
from . import downwind as downwind
|
|
10
|
+
from . import iterative as iterative
|
|
11
|
+
from . import sequential as sequential
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from .downwind import Downwind
|
|
1
|
+
from .downwind import Downwind as Downwind
|
|
2
2
|
|
|
3
|
-
from . import models
|
|
3
|
+
from . import models as models
|
|
@@ -32,6 +32,8 @@ class Downwind(Algorithm):
|
|
|
32
32
|
partial_wakes: dict
|
|
33
33
|
The partial wakes mapping. Key: wake model name,
|
|
34
34
|
value: foxes.core.PartialWakesModel
|
|
35
|
+
deflection: foxes.core.WakeDeflection
|
|
36
|
+
The wake deflection model
|
|
35
37
|
ground_models: dict
|
|
36
38
|
The ground models mapping. Key: wake model name,
|
|
37
39
|
value: foxes.core.GroundModel
|
|
@@ -70,6 +72,7 @@ class Downwind(Algorithm):
|
|
|
70
72
|
wake_models,
|
|
71
73
|
rotor_model="centre",
|
|
72
74
|
wake_frame="rotor_wd",
|
|
75
|
+
wake_deflection="no_deflection",
|
|
73
76
|
partial_wakes=None,
|
|
74
77
|
ground_models=None,
|
|
75
78
|
farm_controller="basic_ctrl",
|
|
@@ -94,6 +97,8 @@ class Downwind(Algorithm):
|
|
|
94
97
|
wake_frame: str
|
|
95
98
|
The wake frame. Will be looked up in the
|
|
96
99
|
model book
|
|
100
|
+
deflection: foxes.core.WakeDeflection, optional
|
|
101
|
+
The wake deflection model
|
|
97
102
|
partial_wakes: dict, list or str, optional
|
|
98
103
|
The partial wakes mapping. Key: wake model name,
|
|
99
104
|
value: partial wake model name
|
|
@@ -123,6 +128,9 @@ class Downwind(Algorithm):
|
|
|
123
128
|
self.__wake_frame = self.mbook.wake_frames.get_item(wake_frame)
|
|
124
129
|
self.wake_frame.name = wake_frame
|
|
125
130
|
|
|
131
|
+
self.__wake_deflection = self.mbook.wake_deflections.get_item(wake_deflection)
|
|
132
|
+
self.wake_deflection.name = wake_deflection
|
|
133
|
+
|
|
126
134
|
self.__wake_models = {}
|
|
127
135
|
for w in wake_models:
|
|
128
136
|
m = self.mbook.wake_models.get_item(w)
|
|
@@ -251,6 +259,19 @@ class Downwind(Algorithm):
|
|
|
251
259
|
"""
|
|
252
260
|
return self.__wake_frame
|
|
253
261
|
|
|
262
|
+
@property
|
|
263
|
+
def wake_deflection(self):
|
|
264
|
+
"""
|
|
265
|
+
The wake deflection
|
|
266
|
+
|
|
267
|
+
Returns
|
|
268
|
+
-------
|
|
269
|
+
m: foxes.core.WakeDeflection
|
|
270
|
+
The wake deflection model
|
|
271
|
+
|
|
272
|
+
"""
|
|
273
|
+
return self.__wake_deflection
|
|
274
|
+
|
|
254
275
|
@property
|
|
255
276
|
def partial_wakes(self):
|
|
256
277
|
"""
|
|
@@ -310,6 +331,15 @@ class Downwind(Algorithm):
|
|
|
310
331
|
"""
|
|
311
332
|
return getattr(mdls, name)
|
|
312
333
|
|
|
334
|
+
def update_n_turbines(self):
|
|
335
|
+
"""
|
|
336
|
+
Reset the number of turbines,
|
|
337
|
+
according to self.farm
|
|
338
|
+
"""
|
|
339
|
+
if self.n_turbines != self.farm.n_turbines:
|
|
340
|
+
super().update_n_turbines()
|
|
341
|
+
self.farm_controller.find_turbine_types(self)
|
|
342
|
+
|
|
313
343
|
def print_deco(self, func_name=None, n_points=None):
|
|
314
344
|
"""
|
|
315
345
|
Helper function for printing model names
|
|
@@ -334,25 +364,26 @@ class Downwind(Algorithm):
|
|
|
334
364
|
if n_points is not None:
|
|
335
365
|
print(f" n_points : {n_points}")
|
|
336
366
|
print(deco)
|
|
337
|
-
print(f" states
|
|
338
|
-
print(f" rotor
|
|
367
|
+
print(f" states : {self.states}")
|
|
368
|
+
print(f" rotor : {self.rotor_model}")
|
|
339
369
|
print(f" controller: {self.farm_controller}")
|
|
340
370
|
print(f" wake frame: {self.wake_frame}")
|
|
371
|
+
print(f" deflection: {self.wake_deflection}")
|
|
341
372
|
print(deco)
|
|
342
|
-
print(
|
|
373
|
+
print(" wakes:")
|
|
343
374
|
for i, w in enumerate(self.wake_models.values()):
|
|
344
375
|
print(f" {i}) {w.name}: {w}")
|
|
345
376
|
print(deco)
|
|
346
|
-
print(
|
|
377
|
+
print(" partial wakes:")
|
|
347
378
|
for i, (w, p) in enumerate(self.partial_wakes.items()):
|
|
348
379
|
print(f" {i}) {w}: {p.name}, {p}")
|
|
349
380
|
print(deco)
|
|
350
|
-
print(
|
|
381
|
+
print(" turbine models:")
|
|
351
382
|
for i, m in enumerate(self.farm_controller.pre_rotor_models.models):
|
|
352
383
|
print(f" {i}) {m.name}: {m} [pre-rotor]")
|
|
353
384
|
for i, m in enumerate(self.farm_controller.post_rotor_models.models):
|
|
354
385
|
print(
|
|
355
|
-
f" {i+len(self.farm_controller.pre_rotor_models.models)}) {m.name}: {m}"
|
|
386
|
+
f" {i + len(self.farm_controller.pre_rotor_models.models)}) {m.name}: {m}"
|
|
356
387
|
)
|
|
357
388
|
print(deco)
|
|
358
389
|
print()
|
|
@@ -364,7 +395,7 @@ class Downwind(Algorithm):
|
|
|
364
395
|
if self.verbosity > 0:
|
|
365
396
|
deco = "-" * 50
|
|
366
397
|
print(f"\n{deco}")
|
|
367
|
-
print(
|
|
398
|
+
print(" Model oder")
|
|
368
399
|
print(f"{deco}")
|
|
369
400
|
|
|
370
401
|
for i, m in enumerate(mlist.models):
|
|
@@ -402,6 +433,7 @@ class Downwind(Algorithm):
|
|
|
402
433
|
self.states,
|
|
403
434
|
self.farm_controller,
|
|
404
435
|
self.rotor_model,
|
|
436
|
+
self.wake_deflection,
|
|
405
437
|
self.wake_frame,
|
|
406
438
|
]
|
|
407
439
|
mdls += list(self.wake_models.values())
|
|
@@ -463,7 +495,7 @@ class Downwind(Algorithm):
|
|
|
463
495
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
464
496
|
|
|
465
497
|
# 6) reorder back to state-turbine dimensions:
|
|
466
|
-
if outputs
|
|
498
|
+
if not isinstance(outputs, bool) or outputs:
|
|
467
499
|
mlist.models.append(self.get_model("ReorderFarmOutput")(outputs))
|
|
468
500
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
469
501
|
|
|
@@ -573,8 +605,8 @@ class Downwind(Algorithm):
|
|
|
573
605
|
# get input model data:
|
|
574
606
|
model_data = self.get_models_data()
|
|
575
607
|
self.print("\nInput data:\n\n", model_data, "\n")
|
|
576
|
-
self.print(
|
|
577
|
-
self.print(
|
|
608
|
+
self.print("\nFarm variables:", ", ".join(self.farm_vars))
|
|
609
|
+
self.print("\nOutput variables:", ", ".join(outputs))
|
|
578
610
|
|
|
579
611
|
# run main calculation:
|
|
580
612
|
farm_results = super().calc_farm(
|
|
@@ -779,7 +811,7 @@ class Downwind(Algorithm):
|
|
|
779
811
|
if persist_mdata:
|
|
780
812
|
model_data = model_data.persist()
|
|
781
813
|
self.print("\nInput data:\n\n", model_data, "\n")
|
|
782
|
-
self.print(
|
|
814
|
+
self.print("\nOutput farm variables:", ", ".join(self.farm_vars))
|
|
783
815
|
|
|
784
816
|
# chunk farm results:
|
|
785
817
|
self.print("\nInput farm data:\n\n", farm_results, "\n")
|
|
@@ -798,7 +830,7 @@ class Downwind(Algorithm):
|
|
|
798
830
|
|
|
799
831
|
# check vars:
|
|
800
832
|
ovars = mlist.output_point_vars(self) if outputs is None else outputs
|
|
801
|
-
self.print(
|
|
833
|
+
self.print("\nOutput point variables:", ", ".join(ovars))
|
|
802
834
|
|
|
803
835
|
# calculate:
|
|
804
836
|
point_results = super().calc_points(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from .set_amb_farm_results import SetAmbFarmResults
|
|
2
|
-
from .set_amb_point_results import SetAmbPointResults
|
|
3
|
-
from .farm_wakes_calc import FarmWakesCalculation
|
|
4
|
-
from .point_wakes_calc import PointWakesCalculation
|
|
5
|
-
from .init_farm_data import InitFarmData
|
|
6
|
-
from .reorder_farm_output import ReorderFarmOutput
|
|
1
|
+
from .set_amb_farm_results import SetAmbFarmResults as SetAmbFarmResults
|
|
2
|
+
from .set_amb_point_results import SetAmbPointResults as SetAmbPointResults
|
|
3
|
+
from .farm_wakes_calc import FarmWakesCalculation as FarmWakesCalculation
|
|
4
|
+
from .point_wakes_calc import PointWakesCalculation as PointWakesCalculation
|
|
5
|
+
from .init_farm_data import InitFarmData as InitFarmData
|
|
6
|
+
from .reorder_farm_output import ReorderFarmOutput as ReorderFarmOutput
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from copy import deepcopy
|
|
3
3
|
|
|
4
|
-
from foxes.core import FarmDataModel
|
|
4
|
+
from foxes.core import FarmDataModel
|
|
5
5
|
import foxes.constants as FC
|
|
6
6
|
import foxes.variables as FV
|
|
7
7
|
|
|
@@ -69,8 +69,14 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
69
69
|
for wname, wmodel in algo.wake_models.items():
|
|
70
70
|
pwake = algo.partial_wakes[wname]
|
|
71
71
|
if pwake.name not in pwake2tdata:
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
wmodels = [
|
|
73
|
+
wm
|
|
74
|
+
for wn, wm in algo.wake_models.items()
|
|
75
|
+
if algo.partial_wakes[wn] is pwake
|
|
76
|
+
]
|
|
77
|
+
pwake2tdata[pwake.name] = pwake.get_initial_tdata(
|
|
78
|
+
algo, mdata, fdata, amb_res, rwghts, wmodels
|
|
79
|
+
)
|
|
74
80
|
|
|
75
81
|
def _get_wdata(tdatap, wdeltas, variables, s):
|
|
76
82
|
"""Helper function for wake data extraction"""
|
|
@@ -78,12 +84,10 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
78
84
|
wdelta = {v: d[s] for v, d in wdeltas.items()}
|
|
79
85
|
return tdata, wdelta
|
|
80
86
|
|
|
81
|
-
def _evaluate(
|
|
82
|
-
gmodel, tdata, amb_res, rwghts, wake_res, wdeltas, oi, wmodel, pwake
|
|
83
|
-
):
|
|
87
|
+
def _evaluate(gmodel, tdata, rwghts, wake_res, wdeltas, oi, wmodel, pwake):
|
|
84
88
|
"""Helper function for data evaluation at turbines"""
|
|
85
89
|
wres = gmodel.finalize_farm_wakes(
|
|
86
|
-
algo, mdata, fdata, tdata,
|
|
90
|
+
algo, mdata, fdata, tdata, rwghts, wdeltas, wmodel, oi, pwake
|
|
87
91
|
)
|
|
88
92
|
|
|
89
93
|
hres = {
|
|
@@ -124,7 +128,6 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
124
128
|
_evaluate(
|
|
125
129
|
gmodel,
|
|
126
130
|
tdatap,
|
|
127
|
-
amb_res,
|
|
128
131
|
rwghts,
|
|
129
132
|
wake_res,
|
|
130
133
|
wdeltas,
|
|
@@ -149,7 +152,6 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
149
152
|
_evaluate(
|
|
150
153
|
gmodel,
|
|
151
154
|
tdatap,
|
|
152
|
-
amb_res,
|
|
153
155
|
rwghts,
|
|
154
156
|
wake_res,
|
|
155
157
|
wdeltas,
|
|
@@ -86,7 +86,6 @@ class InitFarmData(FarmDataModel):
|
|
|
86
86
|
# set X, Y, H, D:
|
|
87
87
|
fdata[FV.D] = np.zeros((n_states, n_turbines), dtype=config.dtype_double)
|
|
88
88
|
for ti, t in enumerate(algo.farm.turbines):
|
|
89
|
-
|
|
90
89
|
if len(t.xy.shape) == 1:
|
|
91
90
|
fdata[FV.TXYH][:, ti, :2] = t.xy[None, :]
|
|
92
91
|
else:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from foxes.core import PointDataModel
|
|
2
|
+
import foxes.variables as FV
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class PointWakesCalculation(PointDataModel):
|
|
@@ -114,17 +115,17 @@ class PointWakesCalculation(PointDataModel):
|
|
|
114
115
|
(n_states, n_targets, n_tpoints)
|
|
115
116
|
|
|
116
117
|
"""
|
|
117
|
-
|
|
118
|
+
|
|
118
119
|
wmodels = (
|
|
119
120
|
algo.wake_models.values() if self.wake_models is None else self.wake_models
|
|
120
121
|
)
|
|
122
|
+
pvrs = self.pvars + [FV.UV]
|
|
121
123
|
for wmodel in wmodels:
|
|
122
124
|
gmodel = algo.ground_models[wmodel.name]
|
|
123
125
|
|
|
124
126
|
wdeltas = gmodel.new_point_wake_deltas(algo, mdata, fdata, tdata, wmodel)
|
|
125
127
|
|
|
126
|
-
if len(set(
|
|
127
|
-
|
|
128
|
+
if len(set(pvrs).intersection(wdeltas.keys())):
|
|
128
129
|
if downwind_index is None:
|
|
129
130
|
for oi in range(fdata.n_turbines):
|
|
130
131
|
gmodel.contribute_to_point_wakes(
|
|
@@ -135,18 +136,11 @@ class PointWakesCalculation(PointDataModel):
|
|
|
135
136
|
algo, mdata, fdata, tdata, downwind_index, wdeltas, wmodel
|
|
136
137
|
)
|
|
137
138
|
|
|
138
|
-
|
|
139
|
-
if v not in res and v in tdata:
|
|
140
|
-
res[v] = tdata[v].copy()
|
|
139
|
+
gmodel.finalize_point_wakes(algo, mdata, fdata, tdata, wdeltas, wmodel)
|
|
141
140
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
for v in res.keys():
|
|
141
|
+
for v in tdata.keys():
|
|
145
142
|
if v in wdeltas:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
for v in res.keys():
|
|
149
|
-
tdata[v] = res[v]
|
|
143
|
+
tdata[v] += wdeltas[v]
|
|
150
144
|
|
|
151
145
|
if self.emodels is not None:
|
|
152
146
|
self.emodels.calculate(algo, mdata, fdata, tdata, self.emodels_cpars)
|
|
@@ -60,7 +60,7 @@ class SetAmbPointResults(PointDataModel):
|
|
|
60
60
|
"""
|
|
61
61
|
return [FV.var2amb[v] for v in self.vars] + [FV.WEIGHT]
|
|
62
62
|
|
|
63
|
-
def calculate(self, algo, mdata, fdata,
|
|
63
|
+
def calculate(self, algo, mdata, fdata, tdata):
|
|
64
64
|
"""
|
|
65
65
|
The main model calculation.
|
|
66
66
|
|
|
@@ -71,11 +71,11 @@ class SetAmbPointResults(PointDataModel):
|
|
|
71
71
|
----------
|
|
72
72
|
algo: foxes.core.Algorithm
|
|
73
73
|
The calculation algorithm
|
|
74
|
-
mdata: foxes.core.
|
|
74
|
+
mdata: foxes.core.MData
|
|
75
75
|
The model data
|
|
76
|
-
fdata: foxes.core.
|
|
76
|
+
fdata: foxes.core.FData
|
|
77
77
|
The farm data
|
|
78
|
-
|
|
78
|
+
tdata: foxes.core.TData
|
|
79
79
|
The point data
|
|
80
80
|
|
|
81
81
|
Returns
|
|
@@ -86,5 +86,5 @@ class SetAmbPointResults(PointDataModel):
|
|
|
86
86
|
|
|
87
87
|
"""
|
|
88
88
|
for v in self.vars:
|
|
89
|
-
|
|
90
|
-
return {v:
|
|
89
|
+
tdata.add(FV.var2amb[v], tdata[v].copy(), tdata.dims[v])
|
|
90
|
+
return {v: tdata[v] for v in self.output_point_vars(algo)}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
from .iterative import Iterative
|
|
2
|
-
from .models.convergence import ConvCrit, ConvCritList, ConvVarDelta, DefaultConv
|
|
1
|
+
from .iterative import Iterative as Iterative
|
|
3
2
|
|
|
4
|
-
from . import
|
|
3
|
+
from .models.convergence import ConvCrit as ConvCrit
|
|
4
|
+
from .models.convergence import ConvCritList as ConvCritList
|
|
5
|
+
from .models.convergence import ConvVarDelta as ConvVarDelta
|
|
6
|
+
from .models.convergence import DefaultConv as DefaultConv
|
|
7
|
+
|
|
8
|
+
from . import models as models
|
|
@@ -114,7 +114,7 @@ class Iterative(Downwind):
|
|
|
114
114
|
|
|
115
115
|
"""
|
|
116
116
|
if self.initialized:
|
|
117
|
-
raise ValueError(
|
|
117
|
+
raise ValueError("Attempt to set_urelax after initialization")
|
|
118
118
|
if self._urelax is None:
|
|
119
119
|
self._urelax = Dict(
|
|
120
120
|
first={},
|
|
@@ -219,7 +219,6 @@ class Iterative(Downwind):
|
|
|
219
219
|
|
|
220
220
|
# do not rotate back from downwind order:
|
|
221
221
|
if not self._final_run:
|
|
222
|
-
|
|
223
222
|
# add under-relaxation during wake calculation:
|
|
224
223
|
urelax = None
|
|
225
224
|
if self._urelax is not None and len(self._urelax["pre_wake"]):
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
from .convergence import ConvCrit
|
|
2
|
-
from .
|
|
3
|
-
from .
|
|
1
|
+
from .convergence import ConvCrit as ConvCrit
|
|
2
|
+
from .convergence import ConvCritList as ConvCritList
|
|
3
|
+
from .convergence import ConvVarDelta as ConvVarDelta
|
|
4
|
+
from .convergence import DefaultConv as DefaultConv
|
|
5
|
+
|
|
6
|
+
from .farm_wakes_calc import FarmWakesCalculation as FarmWakesCalculation
|
|
7
|
+
from .urelax import URelax as URelax
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from copy import deepcopy
|
|
3
3
|
|
|
4
|
-
from foxes.core import FarmDataModel
|
|
4
|
+
from foxes.core import FarmDataModel
|
|
5
5
|
import foxes.constants as FC
|
|
6
6
|
import foxes.variables as FV
|
|
7
7
|
|
|
@@ -99,8 +99,14 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
99
99
|
for wname, wmodel in algo.wake_models.items():
|
|
100
100
|
pwake = algo.partial_wakes[wname]
|
|
101
101
|
if pwake.name not in pwake2tdata:
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
wmodels = [
|
|
103
|
+
wm
|
|
104
|
+
for wn, wm in algo.wake_models.items()
|
|
105
|
+
if algo.partial_wakes[wn] is pwake
|
|
106
|
+
]
|
|
107
|
+
pwake2tdata[pwake.name] = pwake.get_initial_tdata(
|
|
108
|
+
algo, mdata, fdata, amb_res, rwghts, wmodels
|
|
109
|
+
)
|
|
104
110
|
|
|
105
111
|
def _get_wdata(tdatap, wdeltas, variables, s):
|
|
106
112
|
"""Helper function for wake data extraction"""
|
|
@@ -117,7 +123,6 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
117
123
|
wdeltas = pwake.new_wake_deltas(algo, mdata, fdata, tdatap, wmodel)
|
|
118
124
|
|
|
119
125
|
for oi in range(n_turbines):
|
|
120
|
-
|
|
121
126
|
if oi > 0:
|
|
122
127
|
tdata, wdelta = _get_wdata(
|
|
123
128
|
tdatap, wdeltas, [FC.STATE, FC.TARGET], np.s_[:, :oi]
|
|
@@ -140,7 +145,6 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
140
145
|
mdata,
|
|
141
146
|
fdata,
|
|
142
147
|
tdatap,
|
|
143
|
-
amb_res,
|
|
144
148
|
rwghts,
|
|
145
149
|
wdeltas,
|
|
146
150
|
wmodel,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from .sequential import Sequential
|
|
2
|
-
from .models import SequentialPlugin
|
|
1
|
+
from .sequential import Sequential as Sequential
|
|
2
|
+
from .models import SequentialPlugin as SequentialPlugin
|
|
3
3
|
|
|
4
|
-
from . import models
|
|
4
|
+
from . import models as models
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .plugin import SequentialPlugin
|
|
2
|
-
from .seq_state import SeqState
|
|
1
|
+
from .plugin import SequentialPlugin as SequentialPlugin
|
|
2
|
+
from .seq_state import SeqState as SeqState
|
|
@@ -154,7 +154,7 @@ class Sequential(Iterative):
|
|
|
154
154
|
if self._verbo0 > 0:
|
|
155
155
|
print("\nInput data:\n")
|
|
156
156
|
print(self._model_data)
|
|
157
|
-
print(
|
|
157
|
+
print("\nOutput farm variables:", ", ".join(self.farm_vars))
|
|
158
158
|
print()
|
|
159
159
|
|
|
160
160
|
sts = self._model_data[FC.STATE].to_numpy()
|
|
@@ -188,7 +188,6 @@ class Sequential(Iterative):
|
|
|
188
188
|
"""Run calculation for current step, then iterate to next"""
|
|
189
189
|
|
|
190
190
|
if self._i < len(self._inds):
|
|
191
|
-
|
|
192
191
|
self._counter = self._i
|
|
193
192
|
self.states._counter = self._i
|
|
194
193
|
self.states._size = 1
|
|
@@ -401,7 +400,7 @@ class Sequential(Iterative):
|
|
|
401
400
|
|
|
402
401
|
"""
|
|
403
402
|
if not self.iterating:
|
|
404
|
-
raise ValueError(
|
|
403
|
+
raise ValueError("calc_farm call is only allowed during iterations")
|
|
405
404
|
return self.cur_farm_results
|
|
406
405
|
|
|
407
406
|
def calc_points(
|
|
@@ -433,6 +432,6 @@ class Sequential(Iterative):
|
|
|
433
432
|
|
|
434
433
|
"""
|
|
435
434
|
if not self.iterating:
|
|
436
|
-
raise ValueError(
|
|
435
|
+
raise ValueError("calc_points call is only allowed during iterations")
|
|
437
436
|
|
|
438
437
|
return super().calc_points(farm_results, points, finalize=False, **kwargs)
|
foxes/config/__init__.py
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
from .config import Config
|
|
1
|
+
from .config import Config as Config
|
|
2
|
+
from .config import config as config
|
|
3
|
+
from .config import get_path as get_path
|
|
4
|
+
from .config import get_input_path as get_input_path
|
|
5
|
+
from .config import get_output_path as get_output_path
|
foxes/constants.py
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
XY = "xy"
|
|
2
|
+
""" The vector (x, y)
|
|
3
|
+
:group: foxes.variables
|
|
4
|
+
"""
|
|
5
|
+
|
|
1
6
|
XYH = "xyh"
|
|
2
7
|
""" The vector (x, y, height)
|
|
3
8
|
:group: foxes.variables
|
|
@@ -146,6 +151,17 @@ BLOCK_CONVERGENCE = "block_convergence"
|
|
|
146
151
|
"""
|
|
147
152
|
|
|
148
153
|
|
|
154
|
+
WDEFL_ROT_ANGLE = "wake_deflection_rotation_angle"
|
|
155
|
+
"""Identifier for the wake deflection rotation angle data
|
|
156
|
+
:group: foxes.constants
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
WDEFL_DWS_FACTOR = "wake_deflection_deltaws_factor"
|
|
160
|
+
"""Identifier for the wake deflection delta wind speed factor data
|
|
161
|
+
:group: foxes.constants
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
|
|
149
165
|
KAPPA = 0.41
|
|
150
166
|
""" The Von Karman constant
|
|
151
167
|
:group: foxes.constants
|
foxes/core/__init__.py
CHANGED
|
@@ -2,25 +2,48 @@
|
|
|
2
2
|
Abstract classes and core functionality.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from .
|
|
6
|
-
from .
|
|
7
|
-
from .
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
10
|
-
from .
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
13
|
-
from .
|
|
14
|
-
from .
|
|
15
|
-
from .
|
|
16
|
-
from .
|
|
17
|
-
from .
|
|
18
|
-
from .
|
|
19
|
-
from .
|
|
20
|
-
from .
|
|
21
|
-
|
|
22
|
-
from .
|
|
23
|
-
from .
|
|
24
|
-
from .
|
|
25
|
-
from .
|
|
26
|
-
|
|
5
|
+
from .model import Model as Model
|
|
6
|
+
from .data_calc_model import DataCalcModel as DataCalcModel
|
|
7
|
+
from .wind_farm import WindFarm as WindFarm
|
|
8
|
+
from .algorithm import Algorithm as Algorithm
|
|
9
|
+
from .rotor_model import RotorModel as RotorModel
|
|
10
|
+
from .farm_model import FarmModel as FarmModel
|
|
11
|
+
from .turbine_model import TurbineModel as TurbineModel
|
|
12
|
+
from .turbine_type import TurbineType as TurbineType
|
|
13
|
+
from .farm_controller import FarmController as FarmController
|
|
14
|
+
from .turbine import Turbine as Turbine
|
|
15
|
+
from .partial_wakes_model import PartialWakesModel as PartialWakesModel
|
|
16
|
+
from .wake_frame import WakeFrame as WakeFrame
|
|
17
|
+
from .wake_deflection import WakeDeflection as WakeDeflection
|
|
18
|
+
from .vertical_profile import VerticalProfile as VerticalProfile
|
|
19
|
+
from .axial_induction_model import AxialInductionModel as AxialInductionModel
|
|
20
|
+
from .ground_model import GroundModel as GroundModel
|
|
21
|
+
|
|
22
|
+
from .data import Data as Data
|
|
23
|
+
from .data import MData as MData
|
|
24
|
+
from .data import FData as FData
|
|
25
|
+
from .data import TData as TData
|
|
26
|
+
|
|
27
|
+
from .engine import Engine as Engine
|
|
28
|
+
from .engine import get_engine as get_engine
|
|
29
|
+
from .engine import has_engine as has_engine
|
|
30
|
+
from .engine import reset_engine as reset_engine
|
|
31
|
+
|
|
32
|
+
from .states import States as States
|
|
33
|
+
from .states import ExtendedStates as ExtendedStates
|
|
34
|
+
|
|
35
|
+
from .farm_data_model import FarmDataModel as FarmDataModel
|
|
36
|
+
from .farm_data_model import FarmDataModelList as FarmDataModelList
|
|
37
|
+
|
|
38
|
+
from .point_data_model import PointDataModel as PointDataModel
|
|
39
|
+
from .point_data_model import PointDataModelList as PointDataModelList
|
|
40
|
+
|
|
41
|
+
from .wake_model import WakeModel as WakeModel
|
|
42
|
+
from .wake_model import SingleTurbineWakeModel as SingleTurbineWakeModel
|
|
43
|
+
from .wake_model import TurbineInductionModel as TurbineInductionModel
|
|
44
|
+
from .wake_model import WakeK as WakeK
|
|
45
|
+
|
|
46
|
+
from .wake_superposition import WakeSuperposition as WakeSuperposition
|
|
47
|
+
from .wake_superposition import (
|
|
48
|
+
WindVectorWakeSuperposition as WindVectorWakeSuperposition,
|
|
49
|
+
)
|