foxes 1.2.5__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 +16 -0
- 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 +22 -18
- foxes/algorithms/__init__.py +6 -6
- foxes/algorithms/downwind/__init__.py +2 -2
- foxes/algorithms/downwind/downwind.py +53 -27
- foxes/algorithms/downwind/models/__init__.py +6 -6
- foxes/algorithms/downwind/models/farm_wakes_calc.py +22 -14
- foxes/algorithms/downwind/models/init_farm_data.py +4 -5
- foxes/algorithms/downwind/models/point_wakes_calc.py +7 -13
- foxes/algorithms/downwind/models/reorder_farm_output.py +5 -1
- foxes/algorithms/downwind/models/set_amb_point_results.py +7 -7
- 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 +15 -8
- foxes/algorithms/sequential/__init__.py +3 -3
- foxes/algorithms/sequential/models/__init__.py +2 -2
- foxes/algorithms/sequential/models/seq_state.py +0 -18
- foxes/algorithms/sequential/sequential.py +8 -22
- foxes/config/__init__.py +5 -1
- foxes/constants.py +22 -0
- foxes/core/__init__.py +45 -22
- foxes/core/algorithm.py +0 -1
- foxes/core/data.py +56 -29
- foxes/core/engine.py +28 -14
- foxes/core/farm_controller.py +2 -2
- foxes/core/farm_data_model.py +1 -0
- 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 +42 -38
- foxes/core/states.py +4 -50
- 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 -11
- foxes/input/states/create/__init__.py +3 -2
- foxes/input/states/field_data_nc.py +48 -84
- foxes/input/states/multi_height.py +40 -60
- foxes/input/states/one_point_flow.py +22 -25
- foxes/input/states/scan.py +6 -19
- foxes/input/states/single.py +6 -18
- foxes/input/states/states_table.py +25 -44
- foxes/input/states/weibull_sectors.py +225 -0
- foxes/input/states/wrg_states.py +151 -37
- 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 +45 -9
- foxes/models/partial_wakes/segregated.py +2 -20
- 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/rotor_models/centre.py +6 -4
- 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 +45 -8
- foxes/models/wake_frames/streamlines.py +8 -6
- foxes/models/wake_frames/timelines.py +19 -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 +14 -6
- foxes/output/farm_results_eval.py +51 -27
- foxes/output/flow_plots_2d/__init__.py +2 -2
- foxes/output/flow_plots_2d/get_fig.py +4 -2
- foxes/output/rose_plot.py +23 -5
- 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/slice_data.py +16 -19
- 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.2.5.dist-info → foxes-1.4.dist-info}/METADATA +14 -21
- foxes-1.4.dist-info/RECORD +320 -0
- {foxes-1.2.5.dist-info → foxes-1.4.dist-info}/WHEEL +1 -1
- tests/0_consistency/iterative/test_iterative.py +2 -3
- tests/0_consistency/partial_wakes/test_partial_wakes.py +2 -2
- 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 +48 -56
- tests/1_verification/flappy_0_6/abl_states/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +33 -36
- 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 +3 -3
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +3 -4
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +3 -4
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +3 -4
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +3 -4
- tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +0 -2
- tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +3 -3
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +3 -3
- 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 +3 -4
- tests/3_examples/test_examples.py +3 -2
- foxes/output/round.py +0 -10
- foxes/utils/pandas_helpers.py +0 -178
- foxes-1.2.5.dist-info/RECORD +0 -312
- {foxes-1.2.5.dist-info → foxes-1.4.dist-info}/entry_points.txt +0 -0
- {foxes-1.2.5.dist-info → foxes-1.4.dist-info/licenses}/LICENSE +0 -0
- {foxes-1.2.5.dist-info → foxes-1.4.dist-info}/top_level.txt +0 -0
foxes/__init__.py
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
"""
|
|
2
2
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
|
14
|
+
|
|
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
|
|
17
21
|
|
|
18
|
-
from . import algorithms
|
|
19
|
-
from . import engines
|
|
20
|
-
from . import models
|
|
21
|
-
from . import input
|
|
22
|
-
from . import output
|
|
23
|
-
from . import utils
|
|
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
|
|
@@ -61,8 +63,6 @@ class Downwind(Algorithm):
|
|
|
61
63
|
FV.TI,
|
|
62
64
|
FV.CT,
|
|
63
65
|
FV.P,
|
|
64
|
-
FV.ORDER,
|
|
65
|
-
FV.WEIGHT,
|
|
66
66
|
]
|
|
67
67
|
|
|
68
68
|
def __init__(
|
|
@@ -72,6 +72,7 @@ class Downwind(Algorithm):
|
|
|
72
72
|
wake_models,
|
|
73
73
|
rotor_model="centre",
|
|
74
74
|
wake_frame="rotor_wd",
|
|
75
|
+
wake_deflection="no_deflection",
|
|
75
76
|
partial_wakes=None,
|
|
76
77
|
ground_models=None,
|
|
77
78
|
farm_controller="basic_ctrl",
|
|
@@ -96,6 +97,8 @@ class Downwind(Algorithm):
|
|
|
96
97
|
wake_frame: str
|
|
97
98
|
The wake frame. Will be looked up in the
|
|
98
99
|
model book
|
|
100
|
+
deflection: foxes.core.WakeDeflection, optional
|
|
101
|
+
The wake deflection model
|
|
99
102
|
partial_wakes: dict, list or str, optional
|
|
100
103
|
The partial wakes mapping. Key: wake model name,
|
|
101
104
|
value: partial wake model name
|
|
@@ -125,6 +128,9 @@ class Downwind(Algorithm):
|
|
|
125
128
|
self.__wake_frame = self.mbook.wake_frames.get_item(wake_frame)
|
|
126
129
|
self.wake_frame.name = wake_frame
|
|
127
130
|
|
|
131
|
+
self.__wake_deflection = self.mbook.wake_deflections.get_item(wake_deflection)
|
|
132
|
+
self.wake_deflection.name = wake_deflection
|
|
133
|
+
|
|
128
134
|
self.__wake_models = {}
|
|
129
135
|
for w in wake_models:
|
|
130
136
|
m = self.mbook.wake_models.get_item(w)
|
|
@@ -253,6 +259,19 @@ class Downwind(Algorithm):
|
|
|
253
259
|
"""
|
|
254
260
|
return self.__wake_frame
|
|
255
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
|
+
|
|
256
275
|
@property
|
|
257
276
|
def partial_wakes(self):
|
|
258
277
|
"""
|
|
@@ -312,6 +331,15 @@ class Downwind(Algorithm):
|
|
|
312
331
|
"""
|
|
313
332
|
return getattr(mdls, name)
|
|
314
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
|
+
|
|
315
343
|
def print_deco(self, func_name=None, n_points=None):
|
|
316
344
|
"""
|
|
317
345
|
Helper function for printing model names
|
|
@@ -336,25 +364,26 @@ class Downwind(Algorithm):
|
|
|
336
364
|
if n_points is not None:
|
|
337
365
|
print(f" n_points : {n_points}")
|
|
338
366
|
print(deco)
|
|
339
|
-
print(f" states
|
|
340
|
-
print(f" rotor
|
|
367
|
+
print(f" states : {self.states}")
|
|
368
|
+
print(f" rotor : {self.rotor_model}")
|
|
341
369
|
print(f" controller: {self.farm_controller}")
|
|
342
370
|
print(f" wake frame: {self.wake_frame}")
|
|
371
|
+
print(f" deflection: {self.wake_deflection}")
|
|
343
372
|
print(deco)
|
|
344
|
-
print(
|
|
373
|
+
print(" wakes:")
|
|
345
374
|
for i, w in enumerate(self.wake_models.values()):
|
|
346
375
|
print(f" {i}) {w.name}: {w}")
|
|
347
376
|
print(deco)
|
|
348
|
-
print(
|
|
377
|
+
print(" partial wakes:")
|
|
349
378
|
for i, (w, p) in enumerate(self.partial_wakes.items()):
|
|
350
379
|
print(f" {i}) {w}: {p.name}, {p}")
|
|
351
380
|
print(deco)
|
|
352
|
-
print(
|
|
381
|
+
print(" turbine models:")
|
|
353
382
|
for i, m in enumerate(self.farm_controller.pre_rotor_models.models):
|
|
354
383
|
print(f" {i}) {m.name}: {m} [pre-rotor]")
|
|
355
384
|
for i, m in enumerate(self.farm_controller.post_rotor_models.models):
|
|
356
385
|
print(
|
|
357
|
-
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}"
|
|
358
387
|
)
|
|
359
388
|
print(deco)
|
|
360
389
|
print()
|
|
@@ -366,7 +395,7 @@ class Downwind(Algorithm):
|
|
|
366
395
|
if self.verbosity > 0:
|
|
367
396
|
deco = "-" * 50
|
|
368
397
|
print(f"\n{deco}")
|
|
369
|
-
print(
|
|
398
|
+
print(" Model oder")
|
|
370
399
|
print(f"{deco}")
|
|
371
400
|
|
|
372
401
|
for i, m in enumerate(mlist.models):
|
|
@@ -404,6 +433,7 @@ class Downwind(Algorithm):
|
|
|
404
433
|
self.states,
|
|
405
434
|
self.farm_controller,
|
|
406
435
|
self.rotor_model,
|
|
436
|
+
self.wake_deflection,
|
|
407
437
|
self.wake_frame,
|
|
408
438
|
]
|
|
409
439
|
mdls += list(self.wake_models.values())
|
|
@@ -447,9 +477,7 @@ class Downwind(Algorithm):
|
|
|
447
477
|
# 2) calculate ambient rotor results:
|
|
448
478
|
mlist.models.append(self.rotor_model)
|
|
449
479
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
450
|
-
calc_pars[-1].update(
|
|
451
|
-
{"store_rpoints": True, "store_rweights": True, "store_amb_res": True}
|
|
452
|
-
)
|
|
480
|
+
calc_pars[-1].update({"store": True})
|
|
453
481
|
|
|
454
482
|
# 3) run post-rotor turbine models via farm controller:
|
|
455
483
|
mlist.models.append(self.farm_controller)
|
|
@@ -467,7 +495,7 @@ class Downwind(Algorithm):
|
|
|
467
495
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
468
496
|
|
|
469
497
|
# 6) reorder back to state-turbine dimensions:
|
|
470
|
-
if outputs
|
|
498
|
+
if not isinstance(outputs, bool) or outputs:
|
|
471
499
|
mlist.models.append(self.get_model("ReorderFarmOutput")(outputs))
|
|
472
500
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
473
501
|
|
|
@@ -475,13 +503,14 @@ class Downwind(Algorithm):
|
|
|
475
503
|
|
|
476
504
|
def _calc_farm_vars(self, mlist):
|
|
477
505
|
"""Helper function that gathers the farm variables"""
|
|
478
|
-
self.farm_vars = sorted(list(
|
|
506
|
+
self.farm_vars = sorted(list(mlist.output_farm_vars(self)))
|
|
479
507
|
|
|
480
508
|
def _launch_parallel_farm_calc(
|
|
481
509
|
self,
|
|
482
510
|
mlist,
|
|
483
511
|
*data,
|
|
484
512
|
outputs=None,
|
|
513
|
+
normalize=False,
|
|
485
514
|
**kwargs,
|
|
486
515
|
):
|
|
487
516
|
"""
|
|
@@ -495,6 +524,8 @@ class Downwind(Algorithm):
|
|
|
495
524
|
The (mdata, fdata) inputs
|
|
496
525
|
outputs: list of str, optional
|
|
497
526
|
The output variables, or None for defaults
|
|
527
|
+
normalize: bool
|
|
528
|
+
Normalize the weights to 1 wrt sum over states
|
|
498
529
|
kwargs: dict, optional
|
|
499
530
|
Additional parameters for running
|
|
500
531
|
|
|
@@ -510,6 +541,9 @@ class Downwind(Algorithm):
|
|
|
510
541
|
self, mlist, *data, out_vars=out_vars, **kwargs
|
|
511
542
|
)
|
|
512
543
|
|
|
544
|
+
if normalize:
|
|
545
|
+
farm_results[FV.WEIGHT] /= farm_results[FV.WEIGHT].sum(dim=FC.STATE)
|
|
546
|
+
|
|
513
547
|
return farm_results
|
|
514
548
|
|
|
515
549
|
def calc_farm(
|
|
@@ -571,8 +605,8 @@ class Downwind(Algorithm):
|
|
|
571
605
|
# get input model data:
|
|
572
606
|
model_data = self.get_models_data()
|
|
573
607
|
self.print("\nInput data:\n\n", model_data, "\n")
|
|
574
|
-
self.print(
|
|
575
|
-
self.print(
|
|
608
|
+
self.print("\nFarm variables:", ", ".join(self.farm_vars))
|
|
609
|
+
self.print("\nOutput variables:", ", ".join(outputs))
|
|
576
610
|
|
|
577
611
|
# run main calculation:
|
|
578
612
|
farm_results = super().calc_farm(
|
|
@@ -679,13 +713,7 @@ class Downwind(Algorithm):
|
|
|
679
713
|
"""
|
|
680
714
|
return (
|
|
681
715
|
get_engine()
|
|
682
|
-
.run_calculation(
|
|
683
|
-
self,
|
|
684
|
-
mlist,
|
|
685
|
-
*data,
|
|
686
|
-
out_vars=outputs,
|
|
687
|
-
**kwargs,
|
|
688
|
-
)
|
|
716
|
+
.run_calculation(self, mlist, *data, out_vars=outputs, **kwargs)
|
|
689
717
|
.sel({FC.TPOINT: 0})
|
|
690
718
|
.rename({FC.TARGET: FC.POINT})
|
|
691
719
|
)
|
|
@@ -783,7 +811,7 @@ class Downwind(Algorithm):
|
|
|
783
811
|
if persist_mdata:
|
|
784
812
|
model_data = model_data.persist()
|
|
785
813
|
self.print("\nInput data:\n\n", model_data, "\n")
|
|
786
|
-
self.print(
|
|
814
|
+
self.print("\nOutput farm variables:", ", ".join(self.farm_vars))
|
|
787
815
|
|
|
788
816
|
# chunk farm results:
|
|
789
817
|
self.print("\nInput farm data:\n\n", farm_results, "\n")
|
|
@@ -802,7 +830,7 @@ class Downwind(Algorithm):
|
|
|
802
830
|
|
|
803
831
|
# check vars:
|
|
804
832
|
ovars = mlist.output_point_vars(self) if outputs is None else outputs
|
|
805
|
-
self.print(
|
|
833
|
+
self.print("\nOutput point variables:", ", ".join(ovars))
|
|
806
834
|
|
|
807
835
|
# calculate:
|
|
808
836
|
point_results = super().calc_points(
|
|
@@ -812,8 +840,6 @@ class Downwind(Algorithm):
|
|
|
812
840
|
point_data,
|
|
813
841
|
outputs=ovars,
|
|
814
842
|
parameters=calc_pars,
|
|
815
|
-
# sel=sel,
|
|
816
|
-
# isel=isel,
|
|
817
843
|
**kwargs,
|
|
818
844
|
)
|
|
819
845
|
del model_data, farm_results, point_data
|
|
@@ -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,8 +1,9 @@
|
|
|
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
|
+
import foxes.variables as FV
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class FarmWakesCalculation(FarmDataModel):
|
|
@@ -58,8 +59,9 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
58
59
|
"""
|
|
59
60
|
# collect ambient rotor results and weights:
|
|
60
61
|
rotor = algo.rotor_model
|
|
61
|
-
|
|
62
|
+
rwghts = algo.get_from_chunk_store(FC.ROTOR_WEIGHTS, mdata=mdata)
|
|
62
63
|
amb_res = algo.get_from_chunk_store(FC.AMB_ROTOR_RES, mdata=mdata)
|
|
64
|
+
weights = algo.get_from_chunk_store(FC.WEIGHT_RES, mdata=mdata)
|
|
63
65
|
|
|
64
66
|
# generate all wake evaluation points
|
|
65
67
|
# (n_states, n_order, n_rpoints)
|
|
@@ -67,8 +69,14 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
67
69
|
for wname, wmodel in algo.wake_models.items():
|
|
68
70
|
pwake = algo.partial_wakes[wname]
|
|
69
71
|
if pwake.name not in pwake2tdata:
|
|
70
|
-
|
|
71
|
-
|
|
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
|
+
)
|
|
72
80
|
|
|
73
81
|
def _get_wdata(tdatap, wdeltas, variables, s):
|
|
74
82
|
"""Helper function for wake data extraction"""
|
|
@@ -76,21 +84,23 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
76
84
|
wdelta = {v: d[s] for v, d in wdeltas.items()}
|
|
77
85
|
return tdata, wdelta
|
|
78
86
|
|
|
79
|
-
def _evaluate(
|
|
80
|
-
gmodel, tdata, amb_res, weights, wake_res, wdeltas, oi, wmodel, pwake
|
|
81
|
-
):
|
|
87
|
+
def _evaluate(gmodel, tdata, rwghts, wake_res, wdeltas, oi, wmodel, pwake):
|
|
82
88
|
"""Helper function for data evaluation at turbines"""
|
|
83
89
|
wres = gmodel.finalize_farm_wakes(
|
|
84
|
-
algo, mdata, fdata, tdata,
|
|
90
|
+
algo, mdata, fdata, tdata, rwghts, wdeltas, wmodel, oi, pwake
|
|
85
91
|
)
|
|
86
92
|
|
|
87
|
-
hres = {
|
|
93
|
+
hres = {
|
|
94
|
+
v: d[:, oi, None] if d.shape[1] > 1 else d[:, 0, None]
|
|
95
|
+
for v, d in wake_res.items()
|
|
96
|
+
}
|
|
88
97
|
for v, d in wres.items():
|
|
89
98
|
if v in wake_res:
|
|
90
99
|
hres[v] += d[:, None]
|
|
100
|
+
hres[FV.WEIGHT] = weights
|
|
91
101
|
|
|
92
102
|
rotor.eval_rpoint_results(
|
|
93
|
-
algo, mdata, fdata, hres,
|
|
103
|
+
algo, mdata, fdata, hres, rwghts, downwind_index=oi
|
|
94
104
|
)
|
|
95
105
|
|
|
96
106
|
res = algo.farm_controller.calculate(
|
|
@@ -118,8 +128,7 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
118
128
|
_evaluate(
|
|
119
129
|
gmodel,
|
|
120
130
|
tdatap,
|
|
121
|
-
|
|
122
|
-
weights,
|
|
131
|
+
rwghts,
|
|
123
132
|
wake_res,
|
|
124
133
|
wdeltas,
|
|
125
134
|
oi,
|
|
@@ -143,8 +152,7 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
143
152
|
_evaluate(
|
|
144
153
|
gmodel,
|
|
145
154
|
tdatap,
|
|
146
|
-
|
|
147
|
-
weights,
|
|
155
|
+
rwghts,
|
|
148
156
|
wake_res,
|
|
149
157
|
wdeltas,
|
|
150
158
|
oi,
|
|
@@ -43,7 +43,6 @@ class InitFarmData(FarmDataModel):
|
|
|
43
43
|
FV.WD,
|
|
44
44
|
FV.YAW,
|
|
45
45
|
FV.ORDER,
|
|
46
|
-
FV.WEIGHT,
|
|
47
46
|
FV.ORDER_SSEL,
|
|
48
47
|
FV.ORDER_INV,
|
|
49
48
|
]
|
|
@@ -87,7 +86,6 @@ class InitFarmData(FarmDataModel):
|
|
|
87
86
|
# set X, Y, H, D:
|
|
88
87
|
fdata[FV.D] = np.zeros((n_states, n_turbines), dtype=config.dtype_double)
|
|
89
88
|
for ti, t in enumerate(algo.farm.turbines):
|
|
90
|
-
|
|
91
89
|
if len(t.xy.shape) == 1:
|
|
92
90
|
fdata[FV.TXYH][:, ti, :2] = t.xy[None, :]
|
|
93
91
|
else:
|
|
@@ -106,10 +104,11 @@ class InitFarmData(FarmDataModel):
|
|
|
106
104
|
fdata[FV.D][:, ti] = D
|
|
107
105
|
|
|
108
106
|
# calc WD and YAW at rotor centres:
|
|
109
|
-
|
|
107
|
+
svrs = algo.states.output_point_vars(algo)
|
|
108
|
+
tdata = TData.from_points(points=fdata[FV.TXYH], variables=svrs)
|
|
110
109
|
sres = algo.states.calculate(algo, mdata, fdata, tdata)
|
|
111
110
|
fdata[FV.WD] = sres[FV.WD][:, :, 0]
|
|
112
|
-
del tdata, sres
|
|
111
|
+
del tdata, sres, svrs
|
|
113
112
|
|
|
114
113
|
# calculate and inverse:
|
|
115
114
|
order = algo.wake_frame.calc_order(algo, mdata, fdata)
|
|
@@ -124,7 +123,7 @@ class InitFarmData(FarmDataModel):
|
|
|
124
123
|
fdata[FV.TXYH] = fdata[FV.TXYH][ssel, order]
|
|
125
124
|
for i, v in enumerate([FV.X, FV.Y, FV.H]):
|
|
126
125
|
fdata[v] = fdata[FV.TXYH][..., i]
|
|
127
|
-
for v in [FV.D, FV.WD
|
|
126
|
+
for v in [FV.D, FV.WD]:
|
|
128
127
|
if np.any(fdata[v] != fdata[v][0, 0, None, None]):
|
|
129
128
|
fdata[v] = fdata[v][ssel, order]
|
|
130
129
|
fdata[FV.YAW] = fdata[FV.WD].copy()
|
|
@@ -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)
|
|
@@ -75,7 +75,11 @@ class ReorderFarmOutput(FarmDataModel):
|
|
|
75
75
|
|
|
76
76
|
out = {}
|
|
77
77
|
for v in self.output_farm_vars(algo):
|
|
78
|
-
if
|
|
78
|
+
if (
|
|
79
|
+
v != FV.ORDER
|
|
80
|
+
and fdata[v].shape[1] > 1
|
|
81
|
+
and np.any(fdata[v] != fdata[v][0, 0, None, None])
|
|
82
|
+
):
|
|
79
83
|
out[v] = fdata[v][ssel, order_inv]
|
|
80
84
|
else:
|
|
81
85
|
out[v] = fdata[v]
|
|
@@ -58,9 +58,9 @@ class SetAmbPointResults(PointDataModel):
|
|
|
58
58
|
The output variable names
|
|
59
59
|
|
|
60
60
|
"""
|
|
61
|
-
return [FV.var2amb[v] for v in self.vars]
|
|
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,8 +1,9 @@
|
|
|
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
|
+
import foxes.variables as FV
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class FarmWakesCalculation(FarmDataModel):
|
|
@@ -88,8 +89,9 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
88
89
|
"""
|
|
89
90
|
# collect ambient rotor results and weights:
|
|
90
91
|
rotor = algo.rotor_model
|
|
91
|
-
|
|
92
|
+
rwghts = algo.get_from_chunk_store(FC.ROTOR_WEIGHTS, mdata=mdata)
|
|
92
93
|
amb_res = algo.get_from_chunk_store(FC.AMB_ROTOR_RES, mdata=mdata)
|
|
94
|
+
weights = algo.get_from_chunk_store(FC.WEIGHT_RES, mdata=mdata)
|
|
93
95
|
|
|
94
96
|
# generate all wake evaluation points
|
|
95
97
|
# (n_states, n_order, n_rpoints)
|
|
@@ -97,8 +99,14 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
97
99
|
for wname, wmodel in algo.wake_models.items():
|
|
98
100
|
pwake = algo.partial_wakes[wname]
|
|
99
101
|
if pwake.name not in pwake2tdata:
|
|
100
|
-
|
|
101
|
-
|
|
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
|
+
)
|
|
102
110
|
|
|
103
111
|
def _get_wdata(tdatap, wdeltas, variables, s):
|
|
104
112
|
"""Helper function for wake data extraction"""
|
|
@@ -115,7 +123,6 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
115
123
|
wdeltas = pwake.new_wake_deltas(algo, mdata, fdata, tdatap, wmodel)
|
|
116
124
|
|
|
117
125
|
for oi in range(n_turbines):
|
|
118
|
-
|
|
119
126
|
if oi > 0:
|
|
120
127
|
tdata, wdelta = _get_wdata(
|
|
121
128
|
tdatap, wdeltas, [FC.STATE, FC.TARGET], np.s_[:, :oi]
|
|
@@ -138,8 +145,7 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
138
145
|
mdata,
|
|
139
146
|
fdata,
|
|
140
147
|
tdatap,
|
|
141
|
-
|
|
142
|
-
weights,
|
|
148
|
+
rwghts,
|
|
143
149
|
wdeltas,
|
|
144
150
|
wmodel,
|
|
145
151
|
oi,
|
|
@@ -151,7 +157,8 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
151
157
|
|
|
152
158
|
del pwake, tdatap, wdeltas
|
|
153
159
|
|
|
154
|
-
|
|
160
|
+
wake_res[FV.WEIGHT] = weights
|
|
161
|
+
rotor.eval_rpoint_results(algo, mdata, fdata, wake_res, rwghts)
|
|
155
162
|
res = algo.farm_controller.calculate(algo, mdata, fdata, pre_rotor=False)
|
|
156
163
|
if self.urelax is not None:
|
|
157
164
|
res = self.urelax.calculate(algo, mdata, fdata, res)
|
|
@@ -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
|