foxes 0.7.2__py3-none-any.whl → 0.7.3__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.
- foxes/VERSION +1 -1
- foxes/algorithms/downwind/downwind.py +57 -45
- foxes/algorithms/downwind/models/farm_wakes_calc.py +17 -6
- foxes/algorithms/downwind/models/point_wakes_calc.py +13 -45
- foxes/algorithms/iterative/iterative.py +1 -1
- foxes/algorithms/iterative/models/farm_wakes_calc.py +18 -4
- foxes/constants.py +5 -0
- foxes/core/__init__.py +2 -1
- foxes/core/ground_model.py +254 -0
- foxes/core/model.py +3 -2
- foxes/core/partial_wakes_model.py +19 -3
- foxes/core/states.py +33 -0
- foxes/core/wake_model.py +138 -2
- foxes/data/__init__.py +1 -1
- foxes/data/states/WRF-Timeseries-3000.nc +0 -0
- foxes/data/states/windio_timeseries_5000.nc +0 -0
- foxes/data/static_data.py +7 -0
- foxes/data/windio/DTU_10MW_turbine.yaml +10 -0
- foxes/data/windio/__init__.py +0 -0
- foxes/data/windio/windio_5turbines_timeseries.yaml +63 -0
- foxes/input/states/__init__.py +1 -0
- foxes/input/states/multi_height.py +225 -6
- foxes/input/windio/__init__.py +6 -1
- foxes/input/windio/get_states.py +115 -0
- foxes/input/windio/read_attributes.py +321 -0
- foxes/input/windio/read_farm.py +163 -0
- foxes/input/windio/read_fields.py +164 -0
- foxes/input/windio/runner.py +105 -0
- foxes/input/windio/windio.py +136 -254
- foxes/models/__init__.py +1 -0
- foxes/models/ground_models/__init__.py +2 -0
- foxes/models/ground_models/no_ground.py +12 -0
- foxes/models/ground_models/wake_mirror.py +161 -0
- foxes/models/model_book.py +68 -149
- foxes/models/partial_wakes/axiwake.py +27 -4
- foxes/models/partial_wakes/top_hat.py +26 -4
- foxes/models/turbine_types/PCt_file.py +1 -0
- foxes/models/turbine_types/PCt_from_two.py +92 -0
- foxes/models/wake_frames/yawed_wakes.py +41 -38
- foxes/models/wake_models/__init__.py +0 -1
- foxes/models/wake_models/induction/__init__.py +1 -0
- foxes/models/wake_models/induction/rankine_half_body.py +1 -1
- foxes/models/wake_models/induction/vortex_sheet.py +227 -0
- foxes/models/wake_models/ti/crespo_hernandez.py +26 -24
- foxes/models/wake_models/ti/iec_ti.py +33 -26
- foxes/models/wake_models/wind/bastankhah14.py +11 -32
- foxes/models/wake_models/wind/bastankhah16.py +30 -34
- foxes/models/wake_models/wind/jensen.py +13 -29
- foxes/models/wake_models/wind/turbopark.py +31 -61
- foxes/output/grids.py +6 -6
- foxes/output/output.py +6 -6
- foxes/utils/__init__.py +1 -1
- foxes/utils/factory.py +203 -11
- {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/METADATA +8 -6
- {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/RECORD +59 -45
- {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/WHEEL +1 -1
- foxes/models/wake_models/wake_mirror.py +0 -196
- {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/LICENSE +0 -0
- {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/top_level.txt +0 -0
- {foxes-0.7.2.dist-info → foxes-0.7.3.dist-info}/zip-safe +0 -0
foxes/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.7.
|
|
1
|
+
0.7.3
|
|
@@ -28,6 +28,9 @@ class Downwind(Algorithm):
|
|
|
28
28
|
partial_wakes: dict
|
|
29
29
|
The partial wakes mapping. Key: wake model name,
|
|
30
30
|
value: foxes.core.PartialWakesModel
|
|
31
|
+
ground_models: dict
|
|
32
|
+
The ground models mapping. Key: wake model name,
|
|
33
|
+
value: foxes.core.GroundModel
|
|
31
34
|
farm_controller: foxes.core.FarmController
|
|
32
35
|
The farm controller
|
|
33
36
|
n_states: int
|
|
@@ -65,9 +68,9 @@ class Downwind(Algorithm):
|
|
|
65
68
|
rotor_model="centre",
|
|
66
69
|
wake_frame="rotor_wd",
|
|
67
70
|
partial_wakes=None,
|
|
71
|
+
ground_models=None,
|
|
68
72
|
farm_controller="basic_ctrl",
|
|
69
73
|
chunks={FC.STATE: 1000, FC.POINT: 4000},
|
|
70
|
-
wake_mirrors={},
|
|
71
74
|
mbook=None,
|
|
72
75
|
dbook=None,
|
|
73
76
|
verbosity=1,
|
|
@@ -93,15 +96,15 @@ class Downwind(Algorithm):
|
|
|
93
96
|
partial_wakes: dict, list or str, optional
|
|
94
97
|
The partial wakes mapping. Key: wake model name,
|
|
95
98
|
value: partial wake model name
|
|
99
|
+
ground_models: dict, list or str, optional
|
|
100
|
+
The ground models mapping. Key: wake model name,
|
|
101
|
+
value: ground model name
|
|
96
102
|
farm_controller: str
|
|
97
103
|
The farm controller. Will be
|
|
98
104
|
looked up in the model book
|
|
99
105
|
chunks: dict
|
|
100
106
|
The chunks choice for running in parallel with dask,
|
|
101
107
|
e.g. `{"state": 1000}` for chunks of 1000 states
|
|
102
|
-
wake_mirrors: dict
|
|
103
|
-
Switch on wake mirrors for wake models.
|
|
104
|
-
Key: wake model name, value: list of heights
|
|
105
108
|
mbook: foxes.ModelBook, optional
|
|
106
109
|
The model book
|
|
107
110
|
dbook: foxes.DataBook, optional
|
|
@@ -129,51 +132,60 @@ class Downwind(Algorithm):
|
|
|
129
132
|
for w in wake_models:
|
|
130
133
|
m = self.mbook.wake_models[w]
|
|
131
134
|
m.name = w
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
135
|
+
self.wake_models[w] = m
|
|
136
|
+
|
|
137
|
+
def _set_wspecific(descr, target, values, deffunc, mbooks, checkw):
|
|
138
|
+
if values is None:
|
|
139
|
+
values = {}
|
|
140
|
+
if isinstance(values, list) and len(values) == 1:
|
|
141
|
+
values = values[0]
|
|
142
|
+
if isinstance(values, str):
|
|
143
|
+
for w in wake_models:
|
|
144
|
+
try:
|
|
145
|
+
pw = values
|
|
146
|
+
if checkw:
|
|
147
|
+
mbooks[pw].check_wmodel(self.wake_models[w], error=True)
|
|
148
|
+
except TypeError:
|
|
149
|
+
pw = deffunc(self.wake_models[w])
|
|
150
|
+
target[w] = mbooks[pw]
|
|
151
|
+
target[w].name = pw
|
|
152
|
+
elif isinstance(values, list):
|
|
153
|
+
for i, w in enumerate(wake_models):
|
|
154
|
+
if i >= len(values):
|
|
155
|
+
raise IndexError(
|
|
156
|
+
f"Not enough {descr} in list {values}, expecting {len(wake_models)}"
|
|
140
157
|
)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
158
|
+
pw = values[i]
|
|
159
|
+
target[w] = mbooks[pw]
|
|
160
|
+
target[w].name = pw
|
|
144
161
|
else:
|
|
145
|
-
|
|
162
|
+
for w in wake_models:
|
|
163
|
+
if w in values:
|
|
164
|
+
pw = values[w]
|
|
165
|
+
else:
|
|
166
|
+
pw = deffunc(self.wake_models[w])
|
|
167
|
+
target[w] = mbooks[pw]
|
|
168
|
+
target[w].name = pw
|
|
146
169
|
|
|
147
170
|
self.partial_wakes = {}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
pw = partial_wakes[i]
|
|
167
|
-
self.partial_wakes[w] = self.mbook.partial_wakes[pw]
|
|
168
|
-
self.partial_wakes[w].name = pw
|
|
169
|
-
else:
|
|
170
|
-
for w in wake_models:
|
|
171
|
-
if w in partial_wakes:
|
|
172
|
-
pw = partial_wakes[w]
|
|
173
|
-
else:
|
|
174
|
-
pw = mbook.default_partial_wakes(self.wake_models[w])
|
|
175
|
-
self.partial_wakes[w] = self.mbook.partial_wakes[pw]
|
|
176
|
-
self.partial_wakes[w].name = pw
|
|
171
|
+
_set_wspecific(
|
|
172
|
+
descr="partial wakes",
|
|
173
|
+
target=self.partial_wakes,
|
|
174
|
+
values=partial_wakes,
|
|
175
|
+
deffunc=mbook.default_partial_wakes,
|
|
176
|
+
mbooks=self.mbook.partial_wakes,
|
|
177
|
+
checkw=True,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
self.ground_models = {}
|
|
181
|
+
_set_wspecific(
|
|
182
|
+
descr="ground models",
|
|
183
|
+
target=self.ground_models,
|
|
184
|
+
values=ground_models,
|
|
185
|
+
deffunc=lambda w: "no_ground",
|
|
186
|
+
mbooks=self.mbook.ground_models,
|
|
187
|
+
checkw=False,
|
|
188
|
+
)
|
|
177
189
|
|
|
178
190
|
self.farm_controller = self.mbook.farm_controllers[farm_controller]
|
|
179
191
|
self.farm_controller.name = farm_controller
|
|
@@ -75,10 +75,12 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
75
75
|
wdelta = {v: d[s] for v, d in wdeltas.items()}
|
|
76
76
|
return tdata, wdelta
|
|
77
77
|
|
|
78
|
-
def _evaluate(
|
|
78
|
+
def _evaluate(
|
|
79
|
+
gmodel, tdata, amb_res, weights, wake_res, wdeltas, oi, wmodel, pwake
|
|
80
|
+
):
|
|
79
81
|
"""Helper function for data evaluation at turbines"""
|
|
80
|
-
wres =
|
|
81
|
-
algo, mdata, fdata, tdata, amb_res, weights, wdeltas, wmodel, oi
|
|
82
|
+
wres = gmodel.finalize_farm_wakes(
|
|
83
|
+
algo, mdata, fdata, tdata, amb_res, weights, wdeltas, wmodel, oi, pwake
|
|
82
84
|
)
|
|
83
85
|
|
|
84
86
|
hres = {v: d[:, oi, None] for v, d in wake_res.items()}
|
|
@@ -101,8 +103,11 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
101
103
|
run_down = None
|
|
102
104
|
for wname, wmodel in algo.wake_models.items():
|
|
103
105
|
pwake = algo.partial_wakes[wname]
|
|
106
|
+
gmodel = algo.ground_models[wname]
|
|
104
107
|
tdatap = pwake2tdata[pwake.name]
|
|
105
|
-
wdeltas =
|
|
108
|
+
wdeltas = gmodel.new_farm_wake_deltas(
|
|
109
|
+
algo, mdata, fdata, tdatap, wmodel, pwake
|
|
110
|
+
)
|
|
106
111
|
|
|
107
112
|
# downwind:
|
|
108
113
|
if wmodel.affects_downwind:
|
|
@@ -110,6 +115,7 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
110
115
|
for oi in range(n_turbines):
|
|
111
116
|
if oi > 0:
|
|
112
117
|
_evaluate(
|
|
118
|
+
gmodel,
|
|
113
119
|
tdatap,
|
|
114
120
|
amb_res,
|
|
115
121
|
weights,
|
|
@@ -122,7 +128,9 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
122
128
|
|
|
123
129
|
if oi < n_turbines - 1:
|
|
124
130
|
tdata, wdelta = _get_wdata(tdatap, wdeltas, np.s_[:, oi + 1 :])
|
|
125
|
-
|
|
131
|
+
gmodel.contribute_to_farm_wakes(
|
|
132
|
+
algo, mdata, fdata, tdata, oi, wdelta, wmodel, pwake
|
|
133
|
+
)
|
|
126
134
|
|
|
127
135
|
# upwind:
|
|
128
136
|
else:
|
|
@@ -130,6 +138,7 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
130
138
|
for oi in range(n_turbines - 1, -1, -1):
|
|
131
139
|
if oi < n_turbines - 1:
|
|
132
140
|
_evaluate(
|
|
141
|
+
gmodel,
|
|
133
142
|
tdatap,
|
|
134
143
|
amb_res,
|
|
135
144
|
weights,
|
|
@@ -142,7 +151,9 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
142
151
|
|
|
143
152
|
if oi > 0:
|
|
144
153
|
tdata, wdelta = _get_wdata(tdatap, wdeltas, np.s_[:, :oi])
|
|
145
|
-
|
|
154
|
+
gmodel.contribute_to_farm_wakes(
|
|
155
|
+
algo, mdata, fdata, tdata, oi, wdelta, wmodel, pwake
|
|
156
|
+
)
|
|
146
157
|
|
|
147
158
|
if run_up is not None and run_down is not None:
|
|
148
159
|
raise KeyError(
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from foxes.core import PointDataModel, TData
|
|
1
3
|
import foxes.variables as FV
|
|
2
4
|
import foxes.constants as FC
|
|
3
|
-
from foxes.core import PointDataModel
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class PointWakesCalculation(PointDataModel):
|
|
@@ -86,43 +87,6 @@ class PointWakesCalculation(PointDataModel):
|
|
|
86
87
|
"""
|
|
87
88
|
return self.pvars
|
|
88
89
|
|
|
89
|
-
def contribute(
|
|
90
|
-
self,
|
|
91
|
-
algo,
|
|
92
|
-
mdata,
|
|
93
|
-
fdata,
|
|
94
|
-
tdata,
|
|
95
|
-
downwind_index,
|
|
96
|
-
wmodel,
|
|
97
|
-
wdeltas,
|
|
98
|
-
):
|
|
99
|
-
"""
|
|
100
|
-
Contribute to wake deltas from source turbines
|
|
101
|
-
|
|
102
|
-
Parameters
|
|
103
|
-
----------
|
|
104
|
-
algo: foxes.core.Algorithm
|
|
105
|
-
The calculation algorithm
|
|
106
|
-
mdata: foxes.core.Data
|
|
107
|
-
The model data
|
|
108
|
-
fdata: foxes.core.Data
|
|
109
|
-
The farm data
|
|
110
|
-
tdata: foxes.core.Data
|
|
111
|
-
The target point data
|
|
112
|
-
downwind_index: int
|
|
113
|
-
The index in the downwind order
|
|
114
|
-
wmodel: foxes.core.WakeModel
|
|
115
|
-
The wake model
|
|
116
|
-
wdeltas: dict
|
|
117
|
-
The wake deltas, are being modified ob the fly.
|
|
118
|
-
Key: Variable name str, for which the
|
|
119
|
-
wake delta applies, values: numpy.ndarray with
|
|
120
|
-
shape (n_states, n_targets, n_tpoints, ...)
|
|
121
|
-
|
|
122
|
-
"""
|
|
123
|
-
wcoos = algo.wake_frame.get_wake_coos(algo, mdata, fdata, tdata, downwind_index)
|
|
124
|
-
wmodel.contribute(algo, mdata, fdata, tdata, downwind_index, wcoos, wdeltas)
|
|
125
|
-
|
|
126
90
|
def calculate(self, algo, mdata, fdata, tdata, downwind_index=None):
|
|
127
91
|
""" "
|
|
128
92
|
The main model calculation.
|
|
@@ -151,29 +115,33 @@ class PointWakesCalculation(PointDataModel):
|
|
|
151
115
|
(n_states, n_targets, n_tpoints)
|
|
152
116
|
|
|
153
117
|
"""
|
|
154
|
-
|
|
155
118
|
res = {}
|
|
156
119
|
wmodels = (
|
|
157
120
|
algo.wake_models.values() if self.wake_models is None else self.wake_models
|
|
158
121
|
)
|
|
159
122
|
for wmodel in wmodels:
|
|
160
|
-
|
|
123
|
+
pwake = algo.partial_wakes[wmodel.name]
|
|
124
|
+
gmodel = algo.ground_models[wmodel.name]
|
|
125
|
+
|
|
126
|
+
wdeltas = gmodel.new_point_wake_deltas(algo, mdata, fdata, tdata, wmodel)
|
|
127
|
+
|
|
161
128
|
if len(set(self.pvars).intersection(wdeltas.keys())):
|
|
162
129
|
|
|
163
130
|
if downwind_index is None:
|
|
164
131
|
for oi in range(fdata.n_turbines):
|
|
165
|
-
|
|
166
|
-
|
|
132
|
+
gmodel.contribute_to_point_wakes(
|
|
133
|
+
algo, mdata, fdata, tdata, oi, wdeltas, wmodel
|
|
134
|
+
)
|
|
167
135
|
else:
|
|
168
|
-
|
|
169
|
-
algo, mdata, fdata, tdata, downwind_index,
|
|
136
|
+
gmodel.contribute_to_point_wakes(
|
|
137
|
+
algo, mdata, fdata, tdata, downwind_index, wdeltas, wmodel
|
|
170
138
|
)
|
|
171
139
|
|
|
172
140
|
for v in self.pvars:
|
|
173
141
|
if v not in res and v in tdata:
|
|
174
142
|
res[v] = tdata[v].copy()
|
|
175
143
|
|
|
176
|
-
|
|
144
|
+
gmodel.finalize_point_wakes(algo, mdata, fdata, res, wdeltas, wmodel)
|
|
177
145
|
|
|
178
146
|
for v in res.keys():
|
|
179
147
|
if v in wdeltas:
|
|
@@ -64,7 +64,7 @@ class Iterative(Downwind):
|
|
|
64
64
|
"""
|
|
65
65
|
super().__init__(*args, **kwargs)
|
|
66
66
|
|
|
67
|
-
self.max_it = 2
|
|
67
|
+
self.max_it = 2 + self.farm.n_turbines**2 if max_it is None else max_it
|
|
68
68
|
self.conv_crit = (
|
|
69
69
|
self.get_model("DefaultConv")() if conv_crit == "default" else conv_crit
|
|
70
70
|
)
|
|
@@ -109,6 +109,7 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
109
109
|
n_turbines = mdata.n_turbines
|
|
110
110
|
for wname, wmodel in algo.wake_models.items():
|
|
111
111
|
pwake = algo.partial_wakes[wname]
|
|
112
|
+
gmodel = algo.ground_models[wname]
|
|
112
113
|
tdatap = pwake2tdata[pwake.name]
|
|
113
114
|
wdeltas = pwake.new_wake_deltas(algo, mdata, fdata, tdatap, wmodel)
|
|
114
115
|
|
|
@@ -116,15 +117,28 @@ class FarmWakesCalculation(FarmDataModel):
|
|
|
116
117
|
|
|
117
118
|
if oi > 0:
|
|
118
119
|
tdata, wdelta = _get_wdata(tdatap, wdeltas, np.s_[:, :oi])
|
|
119
|
-
|
|
120
|
+
gmodel.contribute_to_farm_wakes(
|
|
121
|
+
algo, mdata, fdata, tdata, oi, wdelta, wmodel, pwake
|
|
122
|
+
)
|
|
120
123
|
|
|
121
124
|
if oi < n_turbines - 1:
|
|
122
125
|
tdata, wdelta = _get_wdata(tdatap, wdeltas, np.s_[:, oi + 1 :])
|
|
123
|
-
|
|
126
|
+
gmodel.contribute_to_farm_wakes(
|
|
127
|
+
algo, mdata, fdata, tdata, oi, wdelta, wmodel, pwake
|
|
128
|
+
)
|
|
124
129
|
|
|
125
130
|
for oi in range(n_turbines):
|
|
126
|
-
wres =
|
|
127
|
-
algo,
|
|
131
|
+
wres = gmodel.finalize_farm_wakes(
|
|
132
|
+
algo,
|
|
133
|
+
mdata,
|
|
134
|
+
fdata,
|
|
135
|
+
tdatap,
|
|
136
|
+
amb_res,
|
|
137
|
+
weights,
|
|
138
|
+
wdeltas,
|
|
139
|
+
wmodel,
|
|
140
|
+
oi,
|
|
141
|
+
pwake,
|
|
128
142
|
)
|
|
129
143
|
for v, d in wres.items():
|
|
130
144
|
if v in wake_res:
|
foxes/constants.py
CHANGED
foxes/core/__init__.py
CHANGED
|
@@ -18,7 +18,8 @@ from .farm_controller import FarmController
|
|
|
18
18
|
from .turbine import Turbine
|
|
19
19
|
from .partial_wakes_model import PartialWakesModel
|
|
20
20
|
from .wake_frame import WakeFrame
|
|
21
|
-
from .wake_model import WakeModel, TurbineInductionModel
|
|
21
|
+
from .wake_model import WakeModel, TurbineInductionModel, WakeK
|
|
22
22
|
from .wake_superposition import WakeSuperposition
|
|
23
23
|
from .vertical_profile import VerticalProfile
|
|
24
24
|
from .axial_induction_model import AxialInductionModel
|
|
25
|
+
from .ground_model import GroundModel
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
from .model import Model
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class GroundModel(Model):
|
|
5
|
+
"""
|
|
6
|
+
Base class for ground models.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
def new_farm_wake_deltas(
|
|
10
|
+
self,
|
|
11
|
+
algo,
|
|
12
|
+
mdata,
|
|
13
|
+
fdata,
|
|
14
|
+
tdata,
|
|
15
|
+
wmodel,
|
|
16
|
+
pwake,
|
|
17
|
+
):
|
|
18
|
+
"""
|
|
19
|
+
Creates new initial wake deltas, filled
|
|
20
|
+
with zeros.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
algo: foxes.core.Algorithm
|
|
25
|
+
The calculation algorithm
|
|
26
|
+
mdata: foxes.core.Data
|
|
27
|
+
The model data
|
|
28
|
+
fdata: foxes.core.Data
|
|
29
|
+
The farm data
|
|
30
|
+
tdata: foxes.core.Data
|
|
31
|
+
The target point data
|
|
32
|
+
wmodel: foxes.core.WakeModel
|
|
33
|
+
The wake model
|
|
34
|
+
pwake: foxes.core.PartialWakesModel
|
|
35
|
+
The partial wakes model
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
wake_deltas: dict
|
|
40
|
+
Key: variable name, value: The zero filled
|
|
41
|
+
wake deltas, shape: (n_states, n_turbines, n_tpoints, ...)
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
return pwake.new_wake_deltas(algo, mdata, fdata, tdata, wmodel)
|
|
45
|
+
|
|
46
|
+
def contribute_to_farm_wakes(
|
|
47
|
+
self,
|
|
48
|
+
algo,
|
|
49
|
+
mdata,
|
|
50
|
+
fdata,
|
|
51
|
+
tdata,
|
|
52
|
+
downwind_index,
|
|
53
|
+
wake_deltas,
|
|
54
|
+
wmodel,
|
|
55
|
+
pwake,
|
|
56
|
+
):
|
|
57
|
+
"""
|
|
58
|
+
Modifies wake deltas at target points by
|
|
59
|
+
contributions from the specified wake source turbines.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
algo: foxes.core.Algorithm
|
|
64
|
+
The calculation algorithm
|
|
65
|
+
mdata: foxes.core.MData
|
|
66
|
+
The model data
|
|
67
|
+
fdata: foxes.core.FData
|
|
68
|
+
The farm data
|
|
69
|
+
tdata: foxes.core.TData
|
|
70
|
+
The target point data
|
|
71
|
+
downwind_index: int
|
|
72
|
+
The index of the wake causing turbine
|
|
73
|
+
in the downwnd order
|
|
74
|
+
wake_deltas: dict
|
|
75
|
+
The wake deltas. Key: variable name,
|
|
76
|
+
value: numpy.ndarray with shape
|
|
77
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
78
|
+
wmodel: foxes.core.WakeModel
|
|
79
|
+
The wake model
|
|
80
|
+
pwake: foxes.core.PartialWakesModel
|
|
81
|
+
The partial wakes model
|
|
82
|
+
|
|
83
|
+
"""
|
|
84
|
+
pwake.contribute(algo, mdata, fdata, tdata, downwind_index, wake_deltas, wmodel)
|
|
85
|
+
|
|
86
|
+
def finalize_farm_wakes(
|
|
87
|
+
self,
|
|
88
|
+
algo,
|
|
89
|
+
mdata,
|
|
90
|
+
fdata,
|
|
91
|
+
tdata,
|
|
92
|
+
amb_res,
|
|
93
|
+
rpoint_weights,
|
|
94
|
+
wake_deltas,
|
|
95
|
+
wmodel,
|
|
96
|
+
downwind_index,
|
|
97
|
+
pwake,
|
|
98
|
+
):
|
|
99
|
+
"""
|
|
100
|
+
Updates the wake_deltas at the selected target
|
|
101
|
+
downwind index.
|
|
102
|
+
|
|
103
|
+
Modifies wake_deltas on the fly.
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
algo: foxes.core.Algorithm
|
|
108
|
+
The calculation algorithm
|
|
109
|
+
mdata: foxes.core.MData
|
|
110
|
+
The model data
|
|
111
|
+
fdata: foxes.core.FData
|
|
112
|
+
The farm data
|
|
113
|
+
tdata: foxes.core.Data
|
|
114
|
+
The target point data
|
|
115
|
+
amb_res: dict
|
|
116
|
+
The ambient results at the target points
|
|
117
|
+
of all rotors. Key: variable name, value
|
|
118
|
+
np.ndarray of shape:
|
|
119
|
+
(n_states, n_turbines, n_rotor_points)
|
|
120
|
+
rpoint_weights: numpy.ndarray
|
|
121
|
+
The rotor point weights, shape: (n_rotor_points,)
|
|
122
|
+
wake_deltas: dict
|
|
123
|
+
The wake deltas. Key: variable name,
|
|
124
|
+
value: np.ndarray of shape
|
|
125
|
+
(n_states, n_turbines, n_tpoints)
|
|
126
|
+
wmodel: foxes.core.WakeModel
|
|
127
|
+
The wake model
|
|
128
|
+
downwind_index: int
|
|
129
|
+
The index in the downwind order
|
|
130
|
+
|
|
131
|
+
Returns
|
|
132
|
+
-------
|
|
133
|
+
final_wake_deltas: dict
|
|
134
|
+
The final wake deltas at the selected downwind
|
|
135
|
+
turbines. Key: variable name, value: np.ndarray
|
|
136
|
+
of shape (n_states, n_rotor_points)
|
|
137
|
+
|
|
138
|
+
"""
|
|
139
|
+
return pwake.finalize_wakes(
|
|
140
|
+
algo,
|
|
141
|
+
mdata,
|
|
142
|
+
fdata,
|
|
143
|
+
tdata,
|
|
144
|
+
amb_res,
|
|
145
|
+
rpoint_weights,
|
|
146
|
+
wake_deltas,
|
|
147
|
+
wmodel,
|
|
148
|
+
downwind_index,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
def new_point_wake_deltas(
|
|
152
|
+
self,
|
|
153
|
+
algo,
|
|
154
|
+
mdata,
|
|
155
|
+
fdata,
|
|
156
|
+
tdata,
|
|
157
|
+
wmodel,
|
|
158
|
+
):
|
|
159
|
+
"""
|
|
160
|
+
Creates new empty wake delta arrays.
|
|
161
|
+
|
|
162
|
+
Parameters
|
|
163
|
+
----------
|
|
164
|
+
algo: foxes.core.Algorithm
|
|
165
|
+
The calculation algorithm
|
|
166
|
+
mdata: foxes.core.MData
|
|
167
|
+
The model data
|
|
168
|
+
fdata: foxes.core.FData
|
|
169
|
+
The farm data
|
|
170
|
+
tdata: foxes.core.TData
|
|
171
|
+
The target point data
|
|
172
|
+
wmodel: foxes.core.WakeModel
|
|
173
|
+
The wake model
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
wake_deltas: dict
|
|
178
|
+
Key: variable name, value: The zero filled
|
|
179
|
+
wake deltas, shape: (n_states, n_targets, n_tpoints, ...)
|
|
180
|
+
|
|
181
|
+
"""
|
|
182
|
+
return wmodel.new_wake_deltas(algo, mdata, fdata, tdata)
|
|
183
|
+
|
|
184
|
+
def contribute_to_point_wakes(
|
|
185
|
+
self,
|
|
186
|
+
algo,
|
|
187
|
+
mdata,
|
|
188
|
+
fdata,
|
|
189
|
+
tdata,
|
|
190
|
+
downwind_index,
|
|
191
|
+
wake_deltas,
|
|
192
|
+
wmodel,
|
|
193
|
+
):
|
|
194
|
+
"""
|
|
195
|
+
Modifies wake deltas at target points by
|
|
196
|
+
contributions from the specified wake source turbines.
|
|
197
|
+
|
|
198
|
+
Parameters
|
|
199
|
+
----------
|
|
200
|
+
algo: foxes.core.Algorithm
|
|
201
|
+
The calculation algorithm
|
|
202
|
+
mdata: foxes.core.MData
|
|
203
|
+
The model data
|
|
204
|
+
fdata: foxes.core.FData
|
|
205
|
+
The farm data
|
|
206
|
+
tdata: foxes.core.TData
|
|
207
|
+
The target point data
|
|
208
|
+
downwind_index: int
|
|
209
|
+
The index of the wake causing turbine
|
|
210
|
+
in the downwnd order
|
|
211
|
+
wake_deltas: dict
|
|
212
|
+
The wake deltas. Key: variable name,
|
|
213
|
+
value: numpy.ndarray with shape
|
|
214
|
+
(n_states, n_targets, n_tpoints, ...)
|
|
215
|
+
wmodel: foxes.core.WakeModel
|
|
216
|
+
The wake model
|
|
217
|
+
|
|
218
|
+
"""
|
|
219
|
+
wcoos = algo.wake_frame.get_wake_coos(algo, mdata, fdata, tdata, downwind_index)
|
|
220
|
+
wmodel.contribute(algo, mdata, fdata, tdata, downwind_index, wcoos, wake_deltas)
|
|
221
|
+
|
|
222
|
+
def finalize_point_wakes(
|
|
223
|
+
self,
|
|
224
|
+
algo,
|
|
225
|
+
mdata,
|
|
226
|
+
fdata,
|
|
227
|
+
amb_results,
|
|
228
|
+
wake_deltas,
|
|
229
|
+
wmodel,
|
|
230
|
+
):
|
|
231
|
+
"""
|
|
232
|
+
Finalize the wake calculation.
|
|
233
|
+
|
|
234
|
+
Modifies wake_deltas on the fly.
|
|
235
|
+
|
|
236
|
+
Parameters
|
|
237
|
+
----------
|
|
238
|
+
algo: foxes.core.Algorithm
|
|
239
|
+
The calculation algorithm
|
|
240
|
+
mdata: foxes.core.MData
|
|
241
|
+
The model data
|
|
242
|
+
fdata: foxes.core.FData
|
|
243
|
+
The farm data
|
|
244
|
+
amb_results: dict
|
|
245
|
+
The ambient results, key: variable name str,
|
|
246
|
+
values: numpy.ndarray with shape
|
|
247
|
+
(n_states, n_targets, n_tpoints)
|
|
248
|
+
wake_deltas: dict
|
|
249
|
+
The wake deltas object at the selected target
|
|
250
|
+
turbines. Key: variable str, value: numpy.ndarray
|
|
251
|
+
with shape (n_states, n_targets, n_tpoints)
|
|
252
|
+
|
|
253
|
+
"""
|
|
254
|
+
wmodel.finalize_wake_deltas(algo, mdata, fdata, amb_results, wake_deltas)
|
foxes/core/model.py
CHANGED
|
@@ -31,8 +31,9 @@ class Model(ABC):
|
|
|
31
31
|
self._ids[t] = count(0)
|
|
32
32
|
self._id = next(self._ids[t])
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
self.
|
|
34
|
+
self.name = f"{type(self).__name__}"
|
|
35
|
+
if self._id > 0:
|
|
36
|
+
self.name += f"_instance{self._id}"
|
|
36
37
|
|
|
37
38
|
self._store = {}
|
|
38
39
|
self.__initialized = False
|
|
@@ -23,6 +23,25 @@ class PartialWakesModel(Model):
|
|
|
23
23
|
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
+
def check_wmodel(self, wmodel, error=True):
|
|
27
|
+
"""
|
|
28
|
+
Checks the wake model type
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
wmodel: foxes.core.WakeModel
|
|
33
|
+
The wake model to be tested
|
|
34
|
+
error: bool
|
|
35
|
+
Flag for raising TypeError
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
chk: bool
|
|
40
|
+
True if wake model is compatible
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
return True
|
|
44
|
+
|
|
26
45
|
@abstractmethod
|
|
27
46
|
def get_wake_points(self, algo, mdata, fdata):
|
|
28
47
|
"""
|
|
@@ -66,9 +85,6 @@ class PartialWakesModel(Model):
|
|
|
66
85
|
The target point data
|
|
67
86
|
wmodel: foxes.core.WakeModel
|
|
68
87
|
The wake model
|
|
69
|
-
wpoints: numpy.ndarray
|
|
70
|
-
The wake evaluation points,
|
|
71
|
-
shape: (n_states, n_turbines, n_tpoints, 3)
|
|
72
88
|
|
|
73
89
|
Returns
|
|
74
90
|
-------
|