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/input/yaml/yaml.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from foxes.utils import Dict
|
|
5
|
+
|
|
6
|
+
from .dict import run_dict
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def foxes_yaml():
|
|
10
|
+
"""
|
|
11
|
+
Command line tool for running foxes from yaml file input.
|
|
12
|
+
|
|
13
|
+
Examples
|
|
14
|
+
--------
|
|
15
|
+
>>> foxes_yaml input.yaml
|
|
16
|
+
|
|
17
|
+
:group: input.yaml
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
parser = argparse.ArgumentParser()
|
|
22
|
+
parser.add_argument(
|
|
23
|
+
"yml_file",
|
|
24
|
+
help="The input yaml file",
|
|
25
|
+
)
|
|
26
|
+
parser.add_argument("-o", "--out_dir", help="The output directory", default=".")
|
|
27
|
+
parser.add_argument("-r", "--rotor", help="The rotor model", default=None)
|
|
28
|
+
parser.add_argument(
|
|
29
|
+
"-p", "--pwakes", help="The partial wakes models", default=None, nargs="+"
|
|
30
|
+
)
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
"-w",
|
|
33
|
+
"--wakes",
|
|
34
|
+
help="The wake models",
|
|
35
|
+
default=None,
|
|
36
|
+
nargs="+",
|
|
37
|
+
)
|
|
38
|
+
parser.add_argument("-f", "--frame", help="The wake frame", default=None)
|
|
39
|
+
parser.add_argument("-e", "--engine", help="The engine", default=None)
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"-n", "--n_procs", help="The number of processes", default=None, type=int
|
|
42
|
+
)
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
"-c",
|
|
45
|
+
"--chunksize_states",
|
|
46
|
+
help="The chunk size for states",
|
|
47
|
+
default=None,
|
|
48
|
+
type=int,
|
|
49
|
+
)
|
|
50
|
+
parser.add_argument(
|
|
51
|
+
"-C",
|
|
52
|
+
"--chunksize_points",
|
|
53
|
+
help="The chunk size for points",
|
|
54
|
+
default=None,
|
|
55
|
+
type=int,
|
|
56
|
+
)
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
"-it", "--iterative", help="Use iterative algorithm", action="store_true"
|
|
59
|
+
)
|
|
60
|
+
parser.add_argument(
|
|
61
|
+
"-nf", "--nofig", help="Do not show figures", action="store_true"
|
|
62
|
+
)
|
|
63
|
+
parser.add_argument(
|
|
64
|
+
"-v",
|
|
65
|
+
"--verbosity",
|
|
66
|
+
help="The verbosity level, 0 = silent",
|
|
67
|
+
type=int,
|
|
68
|
+
default=None,
|
|
69
|
+
)
|
|
70
|
+
args = parser.parse_args()
|
|
71
|
+
|
|
72
|
+
v = 1 if args.verbosity is None else args.verbosity
|
|
73
|
+
fpath = Path(args.yml_file)
|
|
74
|
+
idata = Dict.from_yaml(fpath, verbosity=v)
|
|
75
|
+
|
|
76
|
+
if (
|
|
77
|
+
args.engine is not None
|
|
78
|
+
or args.n_procs is not None
|
|
79
|
+
or args.chunksize_states is not None
|
|
80
|
+
or args.chunksize_points is not None
|
|
81
|
+
):
|
|
82
|
+
epars = dict(
|
|
83
|
+
engine_type=args.engine,
|
|
84
|
+
n_procs=args.n_procs,
|
|
85
|
+
chunk_size_states=args.chunksize_states,
|
|
86
|
+
chunk_size_points=args.chunksize_points,
|
|
87
|
+
verbosity=v,
|
|
88
|
+
)
|
|
89
|
+
else:
|
|
90
|
+
epars = None
|
|
91
|
+
|
|
92
|
+
run_dict(
|
|
93
|
+
idata,
|
|
94
|
+
rotor_model=args.rotor,
|
|
95
|
+
partial_wakes=args.pwakes,
|
|
96
|
+
wake_models=args.wakes,
|
|
97
|
+
wake_frame=args.frame,
|
|
98
|
+
engine_pars=epars,
|
|
99
|
+
iterative=args.iterative,
|
|
100
|
+
work_dir=fpath.parent,
|
|
101
|
+
out_dir=args.out_dir,
|
|
102
|
+
verbosity=args.verbosity,
|
|
103
|
+
)
|
|
@@ -2,6 +2,7 @@ import numpy as np
|
|
|
2
2
|
|
|
3
3
|
from foxes.models.wake_models.axisymmetric import AxisymmetricWakeModel
|
|
4
4
|
from foxes.utils.two_circles import calc_area
|
|
5
|
+
from foxes.config import config
|
|
5
6
|
import foxes.variables as FV
|
|
6
7
|
import foxes.constants as FC
|
|
7
8
|
|
|
@@ -130,11 +131,11 @@ class PartialAxiwake(PartialCentre):
|
|
|
130
131
|
x = wcoos[..., 0, 0]
|
|
131
132
|
n = wcoos[..., 0, 1:3]
|
|
132
133
|
R = np.linalg.norm(n, axis=-1)
|
|
133
|
-
r = np.zeros((n_states, n_targets, self.n), dtype=
|
|
134
|
+
r = np.zeros((n_states, n_targets, self.n), dtype=config.dtype_double)
|
|
134
135
|
del wcoos
|
|
135
136
|
|
|
136
137
|
# prepare circle section area calculation:
|
|
137
|
-
A = np.zeros((n_states, n_targets, self.n), dtype=
|
|
138
|
+
A = np.zeros((n_states, n_targets, self.n), dtype=config.dtype_double)
|
|
138
139
|
weights = np.zeros_like(A)
|
|
139
140
|
|
|
140
141
|
# get normalized 2D vector between rotor and wake centres:
|
|
@@ -148,12 +149,12 @@ class PartialAxiwake(PartialCentre):
|
|
|
148
149
|
sel = (x > 1e-8) & (R > D / 2)
|
|
149
150
|
if np.any(sel):
|
|
150
151
|
n_sel = np.sum(sel)
|
|
151
|
-
Rsel = np.zeros((n_sel, self.n + 1), dtype=
|
|
152
|
+
Rsel = np.zeros((n_sel, self.n + 1), dtype=config.dtype_double)
|
|
152
153
|
Rsel[:] = R[sel][:, None]
|
|
153
154
|
Dsel = D[sel][:, None]
|
|
154
155
|
|
|
155
156
|
# equal delta R2:
|
|
156
|
-
R1 = np.zeros((n_sel, self.n + 1), dtype=
|
|
157
|
+
R1 = np.zeros((n_sel, self.n + 1), dtype=config.dtype_double)
|
|
157
158
|
R1[:] = Dsel / 2
|
|
158
159
|
steps = np.linspace(0.0, 1.0, self.n + 1, endpoint=True) - 0.5
|
|
159
160
|
R2 = np.zeros_like(R1)
|
|
@@ -170,12 +171,12 @@ class PartialAxiwake(PartialCentre):
|
|
|
170
171
|
sel = (x > 0) & (R < D / 2)
|
|
171
172
|
if np.any(sel):
|
|
172
173
|
n_sel = np.sum(sel)
|
|
173
|
-
Rsel = np.zeros((n_sel, self.n + 1), dtype=
|
|
174
|
+
Rsel = np.zeros((n_sel, self.n + 1), dtype=config.dtype_double)
|
|
174
175
|
Rsel[:] = R[sel][:, None]
|
|
175
176
|
Dsel = D[sel][:, None]
|
|
176
177
|
|
|
177
178
|
# equal delta R2:
|
|
178
|
-
R1 = np.zeros((n_sel, self.n + 1), dtype=
|
|
179
|
+
R1 = np.zeros((n_sel, self.n + 1), dtype=config.dtype_double)
|
|
179
180
|
R1[:, 1:] = Dsel / 2
|
|
180
181
|
R2 = np.zeros_like(R1)
|
|
181
182
|
# R2[:, 1:] = Rsel[:, :-1] + Dsel/2
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
import foxes.variables as FV
|
|
4
|
-
|
|
4
|
+
from foxes.config import config
|
|
5
|
+
|
|
5
6
|
from .rotor_points import RotorPoints
|
|
6
7
|
|
|
7
8
|
|
|
@@ -37,4 +38,4 @@ class PartialCentre(RotorPoints):
|
|
|
37
38
|
The target point weights, shape: (n_tpoints,)
|
|
38
39
|
|
|
39
40
|
"""
|
|
40
|
-
return fdata[FV.TXYH][:, :, None], np.ones(1, dtype=
|
|
41
|
+
return fdata[FV.TXYH][:, :, None], np.ones(1, dtype=config.dtype_double)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import PartialWakesModel
|
|
4
|
+
from foxes.config import config
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
6
7
|
|
|
@@ -143,7 +144,9 @@ class PartialSegregated(PartialWakesModel):
|
|
|
143
144
|
else:
|
|
144
145
|
ares = {}
|
|
145
146
|
for v, d in amb_res.items():
|
|
146
|
-
ares[v] = np.zeros(
|
|
147
|
+
ares[v] = np.zeros(
|
|
148
|
+
(n_states, 1, tdata.n_tpoints), dtype=config.dtype_double
|
|
149
|
+
)
|
|
147
150
|
ares[v][:] = np.einsum("sp,p->s", d[:, downwind_index], rpoint_weights)[
|
|
148
151
|
:, None, None
|
|
149
152
|
]
|
|
@@ -151,7 +154,7 @@ class PartialSegregated(PartialWakesModel):
|
|
|
151
154
|
wmodel.finalize_wake_deltas(algo, mdata, fdata, ares, wdel)
|
|
152
155
|
|
|
153
156
|
for v in wdel.keys():
|
|
154
|
-
hdel = np.zeros((n_states, n_rotor_points), dtype=
|
|
157
|
+
hdel = np.zeros((n_states, n_rotor_points), dtype=config.dtype_double)
|
|
155
158
|
hdel[:] = np.einsum("sp,p->s", wdel[v][:, 0], gweights)[:, None]
|
|
156
159
|
wdel[v] = hdel
|
|
157
160
|
|
|
@@ -2,8 +2,8 @@ import pandas as pd
|
|
|
2
2
|
|
|
3
3
|
from foxes.core.point_data_model import PointDataModel
|
|
4
4
|
from foxes.utils import PandasFileHelper
|
|
5
|
+
from foxes.config import config
|
|
5
6
|
import foxes.constants as FC
|
|
6
|
-
import foxes.variables as FV
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class SetUniformData(PointDataModel):
|
|
@@ -84,7 +84,7 @@ class SetUniformData(PointDataModel):
|
|
|
84
84
|
if isinstance(self.data_source, pd.DataFrame):
|
|
85
85
|
data = self.data_source[
|
|
86
86
|
[self.var2col.get(v, v) for v in self.ovars]
|
|
87
|
-
].to_numpy(
|
|
87
|
+
].to_numpy(config.dtype_double)
|
|
88
88
|
elif isinstance(self.data_source, dict):
|
|
89
89
|
pass
|
|
90
90
|
else:
|
|
@@ -93,7 +93,9 @@ class SetUniformData(PointDataModel):
|
|
|
93
93
|
rpars = dict(index_col=0)
|
|
94
94
|
rpars.update(self._rpars)
|
|
95
95
|
data = PandasFileHelper().read_file(self.data_source, **rpars)
|
|
96
|
-
data = data[[self.var2col.get(v, v) for v in self.ovars]].to_numpy(
|
|
96
|
+
data = data[[self.var2col.get(v, v) for v in self.ovars]].to_numpy(
|
|
97
|
+
config.dtype_double
|
|
98
|
+
)
|
|
97
99
|
|
|
98
100
|
idata = super().load_data(algo, verbosity)
|
|
99
101
|
idata["coords"][self.VARS] = self.ovars
|
|
@@ -3,7 +3,7 @@ import numpy as np
|
|
|
3
3
|
from foxes.core import RotorModel
|
|
4
4
|
from foxes.utils import wd2uv, uv2wd
|
|
5
5
|
import foxes.variables as FV
|
|
6
|
-
|
|
6
|
+
from foxes.config import config
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class CentreRotor(RotorModel):
|
|
@@ -155,7 +155,7 @@ class CentreRotor(RotorModel):
|
|
|
155
155
|
vdone = []
|
|
156
156
|
for v in self.calc_vars:
|
|
157
157
|
if v not in fdata:
|
|
158
|
-
fdata[v] = np.zeros((n_states, n_turbines), dtype=
|
|
158
|
+
fdata[v] = np.zeros((n_states, n_turbines), dtype=config.dtype_double)
|
|
159
159
|
|
|
160
160
|
if v == FV.WD or v == FV.YAW:
|
|
161
161
|
if wd is None:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import RotorModel
|
|
4
|
-
|
|
4
|
+
from foxes.config import config
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class GridRotor(RotorModel):
|
|
@@ -75,12 +75,12 @@ class GridRotor(RotorModel):
|
|
|
75
75
|
x = [-1.0 + (i + 0.5) * delta for i in range(self.n)]
|
|
76
76
|
x, y = np.meshgrid(x, x, indexing="ij")
|
|
77
77
|
|
|
78
|
-
self.__dpoints = np.zeros([N, 3], dtype=
|
|
78
|
+
self.__dpoints = np.zeros([N, 3], dtype=config.dtype_double)
|
|
79
79
|
self.__dpoints[:, 1] = x.reshape(N)
|
|
80
80
|
self.__dpoints[:, 2] = y.reshape(N)
|
|
81
81
|
|
|
82
82
|
if self.reduce:
|
|
83
|
-
self.__weights = np.zeros((self.n, self.n), dtype=
|
|
83
|
+
self.__weights = np.zeros((self.n, self.n), dtype=config.dtype_double)
|
|
84
84
|
for i in range(0, self.n):
|
|
85
85
|
for j in range(0, self.n):
|
|
86
86
|
d = delta / self.nint
|
|
@@ -90,7 +90,7 @@ class GridRotor(RotorModel):
|
|
|
90
90
|
hy = [
|
|
91
91
|
y[i, j] - delta / 2.0 + (k + 0.5) * d for k in range(self.nint)
|
|
92
92
|
]
|
|
93
|
-
pts = np.zeros((self.nint, self.nint, 2), dtype=
|
|
93
|
+
pts = np.zeros((self.nint, self.nint, 2), dtype=config.dtype_double)
|
|
94
94
|
pts[:, :, 0], pts[:, :, 1] = np.meshgrid(hx, hy, indexing="ij")
|
|
95
95
|
|
|
96
96
|
d = np.linalg.norm(pts, axis=2)
|
|
@@ -105,7 +105,7 @@ class GridRotor(RotorModel):
|
|
|
105
105
|
else:
|
|
106
106
|
self.__dpoints[:, 1] = x.reshape(N)
|
|
107
107
|
self.__dpoints[:, 2] = y.reshape(N)
|
|
108
|
-
self.__weights = np.ones(N, dtype=
|
|
108
|
+
self.__weights = np.ones(N, dtype=config.dtype_double) / N
|
|
109
109
|
|
|
110
110
|
def n_rotor_points(self):
|
|
111
111
|
"""
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import RotorModel
|
|
4
|
-
|
|
4
|
+
from foxes.config import config
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class LevelRotor(RotorModel):
|
|
@@ -69,20 +69,20 @@ class LevelRotor(RotorModel):
|
|
|
69
69
|
|
|
70
70
|
delta = 2.0 / self.n
|
|
71
71
|
y = [-1.0 + (i + 0.5) * delta for i in range(self.n)]
|
|
72
|
-
x = np.zeros(self.n, dtype=
|
|
72
|
+
x = np.zeros(self.n, dtype=config.dtype_double)
|
|
73
73
|
|
|
74
|
-
self.dpoints = np.zeros([self.n, 3], dtype=
|
|
74
|
+
self.dpoints = np.zeros([self.n, 3], dtype=config.dtype_double)
|
|
75
75
|
self.dpoints[:, 1] = x
|
|
76
76
|
self.dpoints[:, 2] = y
|
|
77
77
|
|
|
78
78
|
if self.reduce:
|
|
79
|
-
self.weights = np.zeros((self.n), dtype=
|
|
79
|
+
self.weights = np.zeros((self.n), dtype=config.dtype_double)
|
|
80
80
|
hx = np.linspace(1, -1, self.nint)
|
|
81
81
|
|
|
82
82
|
for i in range(0, self.n):
|
|
83
83
|
d = delta / self.nint
|
|
84
84
|
hy = [y[i] - delta / 2.0 + (k + 0.5) * d for k in range(self.nint)]
|
|
85
|
-
pts = np.zeros((self.nint, self.nint, 2), dtype=
|
|
85
|
+
pts = np.zeros((self.nint, self.nint, 2), dtype=config.dtype_double)
|
|
86
86
|
pts[:, :, 0], pts[:, :, 1] = np.meshgrid(hx, hy, indexing="ij")
|
|
87
87
|
|
|
88
88
|
d = np.linalg.norm(pts, axis=2)
|
|
@@ -96,7 +96,7 @@ class LevelRotor(RotorModel):
|
|
|
96
96
|
else:
|
|
97
97
|
self.dpoints[:, 1] = x
|
|
98
98
|
self.dpoints[:, 2] = y
|
|
99
|
-
self.weights = np.ones(self.n, dtype=
|
|
99
|
+
self.weights = np.ones(self.n, dtype=config.dtype_double) / self.n
|
|
100
100
|
|
|
101
101
|
def n_rotor_points(self):
|
|
102
102
|
"""
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import TurbineModel
|
|
4
|
+
from foxes.config import config
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
6
7
|
|
|
@@ -128,7 +129,8 @@ class kTI(TurbineModel):
|
|
|
128
129
|
)
|
|
129
130
|
|
|
130
131
|
k = fdata.get(
|
|
131
|
-
self.k_var,
|
|
132
|
+
self.k_var,
|
|
133
|
+
np.zeros((fdata.n_states, fdata.n_turbines), dtype=config.dtype_double),
|
|
132
134
|
)
|
|
133
135
|
|
|
134
136
|
k[st_sel] = kti * ti + kb
|
|
@@ -4,6 +4,7 @@ import xarray as xr
|
|
|
4
4
|
|
|
5
5
|
from foxes.core import TurbineModel
|
|
6
6
|
from foxes.utils import PandasFileHelper
|
|
7
|
+
from foxes.config import config, get_path
|
|
7
8
|
import foxes.constants as FC
|
|
8
9
|
|
|
9
10
|
|
|
@@ -127,9 +128,10 @@ class LookupTable(TurbineModel):
|
|
|
127
128
|
if isinstance(self.data_source, pd.DataFrame):
|
|
128
129
|
data = self.data_source
|
|
129
130
|
else:
|
|
131
|
+
fpath = get_path(self.data_source)
|
|
130
132
|
if verbosity > 0:
|
|
131
|
-
print(f"{self.name}: Reading file {
|
|
132
|
-
data = PandasFileHelper.read_file(
|
|
133
|
+
print(f"{self.name}: Reading file {fpath}")
|
|
134
|
+
data = PandasFileHelper.read_file(fpath, **self._rpars)
|
|
133
135
|
|
|
134
136
|
if verbosity > 0:
|
|
135
137
|
print(f"{self.name}: Preparing interpolation data")
|
|
@@ -138,7 +140,8 @@ class LookupTable(TurbineModel):
|
|
|
138
140
|
data = data[self.input_vars + self.output_vars]
|
|
139
141
|
data.sort_values(by=self.input_vars, inplace=True)
|
|
140
142
|
coords = {
|
|
141
|
-
v: np.asarray(data[v].unique(), dtype=
|
|
143
|
+
v: np.asarray(data[v].unique(), dtype=config.dtype_double)
|
|
144
|
+
for v in self.input_vars
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
dvars = {}
|
|
@@ -146,7 +149,7 @@ class LookupTable(TurbineModel):
|
|
|
146
149
|
pivot_matrix = data.pivot_table(index=self.input_vars, values=[oname])
|
|
147
150
|
dvars[oname] = (
|
|
148
151
|
self.input_vars,
|
|
149
|
-
pivot_matrix.to_numpy(
|
|
152
|
+
pivot_matrix.to_numpy(config.dtype_double).reshape(
|
|
150
153
|
pivot_matrix.index.levshape
|
|
151
154
|
),
|
|
152
155
|
)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import TurbineModel
|
|
4
|
-
|
|
5
|
-
import foxes.constants as FC
|
|
4
|
+
from foxes.config import config
|
|
6
5
|
from foxes.utils import cubic_roots
|
|
6
|
+
import foxes.variables as FV
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class PowerMask(TurbineModel):
|
|
@@ -33,7 +33,13 @@ class PowerMask(TurbineModel):
|
|
|
33
33
|
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
|
-
def __init__(
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
var_ws_P=FV.REWS3,
|
|
39
|
+
factor_P=1.0e3,
|
|
40
|
+
P_lim=100,
|
|
41
|
+
induction="Betz",
|
|
42
|
+
):
|
|
37
43
|
"""
|
|
38
44
|
Constructor.
|
|
39
45
|
|
|
@@ -110,13 +116,13 @@ class PowerMask(TurbineModel):
|
|
|
110
116
|
|
|
111
117
|
self._P_rated = []
|
|
112
118
|
for t in algo.farm_controller.turbine_types:
|
|
113
|
-
Pnom =
|
|
119
|
+
Pnom = config.dtype_double(t.P_nominal)
|
|
114
120
|
if np.isnan(Pnom):
|
|
115
121
|
raise ValueError(
|
|
116
122
|
f"Model '{self.name}': P_nominal is NaN for turbine type '{t.name}'"
|
|
117
123
|
)
|
|
118
124
|
self._P_rated.append(Pnom)
|
|
119
|
-
self._P_rated = np.array(self._P_rated, dtype=
|
|
125
|
+
self._P_rated = np.array(self._P_rated, dtype=config.dtype_double)
|
|
120
126
|
|
|
121
127
|
def calculate(self, algo, mdata, fdata, st_sel):
|
|
122
128
|
"""
|
|
@@ -183,9 +189,9 @@ class PowerMask(TurbineModel):
|
|
|
183
189
|
|
|
184
190
|
# find roots:
|
|
185
191
|
N = len(cp)
|
|
186
|
-
a3 = np.full(N, 4.0, dtype=
|
|
187
|
-
a2 = np.full(N, -8.0, dtype=
|
|
188
|
-
a1 = np.full(N, 4.0, dtype=
|
|
192
|
+
a3 = np.full(N, 4.0, dtype=config.dtype_double)
|
|
193
|
+
a2 = np.full(N, -8.0, dtype=config.dtype_double)
|
|
194
|
+
a1 = np.full(N, 4.0, dtype=config.dtype_double)
|
|
189
195
|
a0 = -cp / e
|
|
190
196
|
rts = cubic_roots(a0, a1, a2, a3)
|
|
191
197
|
rts[np.isnan(rts)] = np.inf
|
|
@@ -3,6 +3,7 @@ import pandas as pd
|
|
|
3
3
|
|
|
4
4
|
from foxes.core import TurbineModel
|
|
5
5
|
from foxes.utils import PandasFileHelper
|
|
6
|
+
from foxes.config import get_path
|
|
6
7
|
import foxes.variables as FV
|
|
7
8
|
import foxes.constants as FC
|
|
8
9
|
|
|
@@ -90,9 +91,10 @@ class SectorManagement(TurbineModel):
|
|
|
90
91
|
if isinstance(self.source, pd.DataFrame):
|
|
91
92
|
data = self.source
|
|
92
93
|
else:
|
|
94
|
+
fpath = get_path(self.source)
|
|
93
95
|
if verbosity > 0:
|
|
94
|
-
print(f"{self.name}: Reading file {
|
|
95
|
-
data = PandasFileHelper.read_file(
|
|
96
|
+
print(f"{self.name}: Reading file {fpath}")
|
|
97
|
+
data = PandasFileHelper.read_file(fpath, **self._rpars)
|
|
96
98
|
|
|
97
99
|
if self._trbs is None:
|
|
98
100
|
if self._col_i is not None and self._col_t is None:
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import TurbineModel
|
|
4
|
-
|
|
4
|
+
from foxes.config import config
|
|
5
5
|
import foxes.variables as FV
|
|
6
|
+
import foxes.constants as FC
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class SetFarmVars(TurbineModel):
|
|
@@ -13,12 +14,14 @@ class SetFarmVars(TurbineModel):
|
|
|
13
14
|
----------
|
|
14
15
|
vars: list of str
|
|
15
16
|
The variables to be set
|
|
17
|
+
once: bool
|
|
18
|
+
Flag for running only once
|
|
16
19
|
|
|
17
20
|
:group: models.turbine_models
|
|
18
21
|
|
|
19
22
|
"""
|
|
20
23
|
|
|
21
|
-
def __init__(self, pre_rotor=False):
|
|
24
|
+
def __init__(self, pre_rotor=False, once=False):
|
|
22
25
|
"""
|
|
23
26
|
Constructor.
|
|
24
27
|
|
|
@@ -27,9 +30,12 @@ class SetFarmVars(TurbineModel):
|
|
|
27
30
|
pre_rotor: bool
|
|
28
31
|
Flag for running this model before
|
|
29
32
|
running the rotor model.
|
|
33
|
+
once: bool
|
|
34
|
+
Flag for running only once
|
|
30
35
|
|
|
31
36
|
"""
|
|
32
37
|
super().__init__(pre_rotor=pre_rotor)
|
|
38
|
+
self.once = once
|
|
33
39
|
self.reset()
|
|
34
40
|
|
|
35
41
|
def add_var(self, var, data):
|
|
@@ -51,7 +57,7 @@ class SetFarmVars(TurbineModel):
|
|
|
51
57
|
if self.running:
|
|
52
58
|
raise ValueError(f"Model '{self.name}': Cannot add_var while running")
|
|
53
59
|
self.vars.append(var)
|
|
54
|
-
self.__vdata.append(np.asarray(data, dtype=
|
|
60
|
+
self.__vdata.append(np.asarray(data, dtype=config.dtype_double))
|
|
55
61
|
|
|
56
62
|
def reset(self):
|
|
57
63
|
"""
|
|
@@ -62,6 +68,23 @@ class SetFarmVars(TurbineModel):
|
|
|
62
68
|
self.vars = []
|
|
63
69
|
self.__vdata = []
|
|
64
70
|
|
|
71
|
+
def initialize(self, algo, verbosity=0, force=False):
|
|
72
|
+
"""
|
|
73
|
+
Initializes the model.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
algo: foxes.core.Algorithm
|
|
78
|
+
The calculation algorithm
|
|
79
|
+
verbosity: int
|
|
80
|
+
The verbosity level, 0 = silent
|
|
81
|
+
force: bool
|
|
82
|
+
Overwrite existing data
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
super().initialize(algo, verbosity, force)
|
|
86
|
+
self.__once_done = set()
|
|
87
|
+
|
|
65
88
|
def output_farm_vars(self, algo):
|
|
66
89
|
"""
|
|
67
90
|
The variables which are being modified by the model.
|
|
@@ -105,7 +128,9 @@ class SetFarmVars(TurbineModel):
|
|
|
105
128
|
idata = super().load_data(algo, verbosity)
|
|
106
129
|
|
|
107
130
|
for i, v in enumerate(self.vars):
|
|
108
|
-
data = np.full(
|
|
131
|
+
data = np.full(
|
|
132
|
+
(algo.n_states, algo.n_turbines), np.nan, dtype=config.dtype_double
|
|
133
|
+
)
|
|
109
134
|
vdata = self.__vdata[i]
|
|
110
135
|
|
|
111
136
|
# handle special case of call during vectorized optimization:
|
|
@@ -117,7 +142,7 @@ class SetFarmVars(TurbineModel):
|
|
|
117
142
|
n_pop = algo.states.n_pop
|
|
118
143
|
n_ost = algo.states.states.size()
|
|
119
144
|
n_trb = algo.n_turbines
|
|
120
|
-
vdata = np.zeros((n_pop, n_ost, n_trb), dtype=
|
|
145
|
+
vdata = np.zeros((n_pop, n_ost, n_trb), dtype=config.dtype_double)
|
|
121
146
|
vdata[:] = self.__vdata[i][None, :]
|
|
122
147
|
vdata = vdata.reshape(n_pop * n_ost, n_trb)
|
|
123
148
|
|
|
@@ -130,7 +155,7 @@ class SetFarmVars(TurbineModel):
|
|
|
130
155
|
for ti in range(algo.n_turbines):
|
|
131
156
|
t = algo.farm.turbines[ti]
|
|
132
157
|
if len(t.xy.shape) == 1:
|
|
133
|
-
xy = np.zeros((algo.n_states, 2), dtype=
|
|
158
|
+
xy = np.zeros((algo.n_states, 2), dtype=config.dtype_double)
|
|
134
159
|
xy[:] = t.xy[None, :]
|
|
135
160
|
t.xy = xy
|
|
136
161
|
t.xy[:, i] = np.where(
|
|
@@ -141,7 +166,7 @@ class SetFarmVars(TurbineModel):
|
|
|
141
166
|
if v in [FV.D, FV.H]:
|
|
142
167
|
for ti in range(algo.n_turbines):
|
|
143
168
|
t = algo.farm.turbines[ti]
|
|
144
|
-
x = np.zeros(algo.n_states, dtype=
|
|
169
|
+
x = np.zeros(algo.n_states, dtype=config.dtype_double)
|
|
145
170
|
if v == FV.D:
|
|
146
171
|
x[:] = t.D
|
|
147
172
|
t.D = x
|
|
@@ -243,21 +268,26 @@ class SetFarmVars(TurbineModel):
|
|
|
243
268
|
Values: numpy.ndarray with shape (n_states, n_turbines)
|
|
244
269
|
|
|
245
270
|
"""
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
271
|
+
i0 = mdata.states_i0(counter=True)
|
|
272
|
+
if not self.once or i0 not in self.__once_done:
|
|
273
|
+
|
|
274
|
+
if self.pre_rotor:
|
|
275
|
+
order = np.s_[:]
|
|
276
|
+
ssel = np.s_[:]
|
|
277
|
+
else:
|
|
278
|
+
order = fdata[FV.ORDER]
|
|
279
|
+
ssel = fdata[FV.ORDER_SSEL]
|
|
280
|
+
|
|
281
|
+
bsel = np.zeros((fdata.n_states, fdata.n_turbines), dtype=bool)
|
|
282
|
+
bsel[st_sel] = True
|
|
283
|
+
|
|
284
|
+
for v in self.vars:
|
|
285
|
+
data = mdata[self.var(v)][ssel, order]
|
|
286
|
+
hsel = ~np.isnan(data)
|
|
287
|
+
tsel = bsel & hsel
|
|
288
|
+
|
|
289
|
+
fdata[v][tsel] = data[tsel]
|
|
290
|
+
|
|
291
|
+
self.__once_done.add(i0)
|
|
262
292
|
|
|
263
293
|
return {v: fdata[v] for v in self.vars}
|
|
@@ -4,7 +4,7 @@ from scipy.interpolate import interpn
|
|
|
4
4
|
|
|
5
5
|
from foxes.core import TurbineModel
|
|
6
6
|
from foxes.utils import PandasFileHelper
|
|
7
|
-
|
|
7
|
+
from foxes.config import config, get_path
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class TableFactors(TurbineModel):
|
|
@@ -106,15 +106,16 @@ class TableFactors(TurbineModel):
|
|
|
106
106
|
if isinstance(self.data_source, pd.DataFrame):
|
|
107
107
|
self._data = self.data_source
|
|
108
108
|
else:
|
|
109
|
+
fpath = get_path(self.data_source)
|
|
109
110
|
if verbosity > 0:
|
|
110
|
-
print(f"{self.name}: Reading file {
|
|
111
|
+
print(f"{self.name}: Reading file {fpath}")
|
|
111
112
|
rpars = dict(index_col=0)
|
|
112
113
|
rpars.update(self._rpars)
|
|
113
|
-
self._data = PandasFileHelper.read_file(
|
|
114
|
+
self._data = PandasFileHelper.read_file(fpath, **rpars)
|
|
114
115
|
|
|
115
|
-
self._rvals = self._data.index.to_numpy(
|
|
116
|
-
self._cvals = self._data.columns.to_numpy(
|
|
117
|
-
self._data = self._data.to_numpy(
|
|
116
|
+
self._rvals = self._data.index.to_numpy(config.dtype_double)
|
|
117
|
+
self._cvals = self._data.columns.to_numpy(config.dtype_double)
|
|
118
|
+
self._data = self._data.to_numpy(config.dtype_double)
|
|
118
119
|
|
|
119
120
|
def calculate(self, algo, mdata, fdata, st_sel):
|
|
120
121
|
"""
|
|
@@ -143,7 +144,7 @@ class TableFactors(TurbineModel):
|
|
|
143
144
|
|
|
144
145
|
"""
|
|
145
146
|
n_sel = np.sum(st_sel)
|
|
146
|
-
qts = np.zeros((n_sel, 2), dtype=
|
|
147
|
+
qts = np.zeros((n_sel, 2), dtype=config.dtype_double)
|
|
147
148
|
qts[:, 0] = fdata[self.row_var][st_sel]
|
|
148
149
|
qts[:, 1] = fdata[self.col_var][st_sel]
|
|
149
150
|
|