foxes 0.7.4.25__py3-none-any.whl → 0.8.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.
- foxes/VERSION +1 -1
- {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/METADATA +20 -116
- {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/RECORD +7 -33
- foxes/opt/__init__.py +0 -9
- foxes/opt/constraints/__init__.py +0 -6
- foxes/opt/constraints/area_geometry.py +0 -214
- foxes/opt/constraints/min_dist.py +0 -239
- foxes/opt/core/__init__.py +0 -9
- foxes/opt/core/farm_constraint.py +0 -96
- foxes/opt/core/farm_objective.py +0 -97
- foxes/opt/core/farm_opt_problem.py +0 -346
- foxes/opt/core/farm_vars_problem.py +0 -219
- foxes/opt/core/pop_states.py +0 -206
- foxes/opt/objectives/__init__.py +0 -6
- foxes/opt/objectives/farm_vars.py +0 -323
- foxes/opt/objectives/max_n_turbines.py +0 -142
- foxes/opt/problems/__init__.py +0 -7
- foxes/opt/problems/layout/__init__.py +0 -9
- foxes/opt/problems/layout/farm_layout.py +0 -137
- foxes/opt/problems/layout/geom_layouts/__init__.py +0 -10
- foxes/opt/problems/layout/geom_layouts/constraints.py +0 -802
- foxes/opt/problems/layout/geom_layouts/geom_layout.py +0 -290
- foxes/opt/problems/layout/geom_layouts/geom_layout_gridded.py +0 -276
- foxes/opt/problems/layout/geom_layouts/geom_reggrid.py +0 -351
- foxes/opt/problems/layout/geom_layouts/geom_reggrids.py +0 -482
- foxes/opt/problems/layout/geom_layouts/objectives.py +0 -666
- foxes/opt/problems/layout/reggrids_layout.py +0 -417
- foxes/opt/problems/layout/regular_layout.py +0 -350
- foxes/opt/problems/opt_farm_vars.py +0 -586
- {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/LICENSE +0 -0
- {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/WHEEL +0 -0
- {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/top_level.txt +0 -0
- {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/zip-safe +0 -0
|
@@ -1,417 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
from copy import deepcopy
|
|
3
|
-
|
|
4
|
-
from foxes.opt.core import FarmOptProblem, FarmVarsProblem
|
|
5
|
-
from foxes.models.turbine_models import Calculator
|
|
6
|
-
import foxes.variables as FV
|
|
7
|
-
import foxes.constants as FC
|
|
8
|
-
from .geom_layouts.geom_reggrids import GeomRegGrids
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class RegGridsLayoutOptProblem(FarmVarsProblem):
|
|
12
|
-
"""
|
|
13
|
-
Places turbines on several regular grids and optimizes
|
|
14
|
-
their parameters.
|
|
15
|
-
|
|
16
|
-
Note that this problem has both int and float variables
|
|
17
|
-
(mixed problem).
|
|
18
|
-
|
|
19
|
-
Attributes
|
|
20
|
-
----------
|
|
21
|
-
min_spacing: float
|
|
22
|
-
The minimal turbine spacing
|
|
23
|
-
n_grids: int
|
|
24
|
-
The number of grids
|
|
25
|
-
max_n_row: int
|
|
26
|
-
The maximal number of turbines per
|
|
27
|
-
grid and row
|
|
28
|
-
|
|
29
|
-
:group: opt.problems.layout
|
|
30
|
-
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
def __init__(
|
|
34
|
-
self,
|
|
35
|
-
name,
|
|
36
|
-
algo,
|
|
37
|
-
min_dist,
|
|
38
|
-
n_grids=1,
|
|
39
|
-
n_row_max=None,
|
|
40
|
-
max_dist=None,
|
|
41
|
-
runner=None,
|
|
42
|
-
**kwargs,
|
|
43
|
-
):
|
|
44
|
-
"""
|
|
45
|
-
Constraints.
|
|
46
|
-
|
|
47
|
-
Parameters
|
|
48
|
-
----------
|
|
49
|
-
name: str
|
|
50
|
-
The problem's name
|
|
51
|
-
algo: foxes.core.Algorithm
|
|
52
|
-
The algorithm
|
|
53
|
-
min_dist: float
|
|
54
|
-
The minimal distance between points
|
|
55
|
-
n_grids: int
|
|
56
|
-
The number of grids
|
|
57
|
-
n_row_max: int, optional
|
|
58
|
-
The maximal number of points in a row
|
|
59
|
-
max_dist: float, optional
|
|
60
|
-
The maximal distance between points
|
|
61
|
-
runner: foxes.core.Runner, optional
|
|
62
|
-
The runner for running the algorithm
|
|
63
|
-
kwargs: dict, optional
|
|
64
|
-
Additional parameters for `FarmVarsProblem`
|
|
65
|
-
|
|
66
|
-
"""
|
|
67
|
-
super().__init__(name, algo, runner, **kwargs)
|
|
68
|
-
|
|
69
|
-
b = algo.farm.boundary
|
|
70
|
-
assert b is not None, f"Problem '{self.name}': Missing wind farm boundary."
|
|
71
|
-
|
|
72
|
-
self._geomp = GeomRegGrids(
|
|
73
|
-
b,
|
|
74
|
-
min_dist=min_dist,
|
|
75
|
-
n_grids=n_grids,
|
|
76
|
-
n_row_max=n_row_max,
|
|
77
|
-
max_dist=max_dist,
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
def initialize(self, verbosity=1, **kwargs):
|
|
81
|
-
"""
|
|
82
|
-
Initialize the object.
|
|
83
|
-
|
|
84
|
-
Parameters
|
|
85
|
-
----------
|
|
86
|
-
verbosity: int
|
|
87
|
-
The verbosity level, 0 = silent
|
|
88
|
-
kwargs: dict, optional
|
|
89
|
-
Additional parameters for super class init
|
|
90
|
-
|
|
91
|
-
"""
|
|
92
|
-
self._geomp.objs = self.objs
|
|
93
|
-
self._geomp.cons = self.cons
|
|
94
|
-
self._geomp.initialize(verbosity)
|
|
95
|
-
|
|
96
|
-
self._mname = self.name + "_calc"
|
|
97
|
-
for t in self.algo.farm.turbines:
|
|
98
|
-
if self._mname not in t.models:
|
|
99
|
-
t.models.append(self._mname)
|
|
100
|
-
self._turbine = deepcopy(self.farm.turbines[-1])
|
|
101
|
-
|
|
102
|
-
self.algo.mbook.turbine_models[self._mname] = Calculator(
|
|
103
|
-
in_vars=[FC.VALID, FV.P, FV.CT],
|
|
104
|
-
out_vars=[FC.VALID, FV.P, FV.CT],
|
|
105
|
-
func=lambda valid, P, ct, st_sel: (valid, P * valid, ct * valid),
|
|
106
|
-
pre_rotor=False,
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
super().initialize(
|
|
110
|
-
pre_rotor_vars=[FV.X, FV.Y, FC.VALID],
|
|
111
|
-
post_rotor_vars=[],
|
|
112
|
-
verbosity=verbosity,
|
|
113
|
-
**kwargs,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
def var_names_int(self):
|
|
117
|
-
"""
|
|
118
|
-
The names of int variables.
|
|
119
|
-
|
|
120
|
-
Returns
|
|
121
|
-
-------
|
|
122
|
-
names: list of str
|
|
123
|
-
The names of the int variables
|
|
124
|
-
|
|
125
|
-
"""
|
|
126
|
-
return self._geomp.var_names_int()
|
|
127
|
-
|
|
128
|
-
def initial_values_int(self):
|
|
129
|
-
"""
|
|
130
|
-
The initial values of the int variables.
|
|
131
|
-
|
|
132
|
-
Returns
|
|
133
|
-
-------
|
|
134
|
-
values: numpy.ndarray
|
|
135
|
-
Initial int values, shape: (n_vars_int,)
|
|
136
|
-
|
|
137
|
-
"""
|
|
138
|
-
return self._geomp.initial_values_int()
|
|
139
|
-
|
|
140
|
-
def min_values_int(self):
|
|
141
|
-
"""
|
|
142
|
-
The minimal values of the integer variables.
|
|
143
|
-
|
|
144
|
-
Use -self.INT_INF for unbounded.
|
|
145
|
-
|
|
146
|
-
Returns
|
|
147
|
-
-------
|
|
148
|
-
values: numpy.ndarray
|
|
149
|
-
Minimal int values, shape: (n_vars_int,)
|
|
150
|
-
|
|
151
|
-
"""
|
|
152
|
-
return self._geomp.min_values_int()
|
|
153
|
-
|
|
154
|
-
def max_values_int(self):
|
|
155
|
-
"""
|
|
156
|
-
The maximal values of the integer variables.
|
|
157
|
-
|
|
158
|
-
Use self.INT_INF for unbounded.
|
|
159
|
-
|
|
160
|
-
Returns
|
|
161
|
-
-------
|
|
162
|
-
values: numpy.ndarray
|
|
163
|
-
Maximal int values, shape: (n_vars_int,)
|
|
164
|
-
|
|
165
|
-
"""
|
|
166
|
-
return self._geomp.max_values_int()
|
|
167
|
-
|
|
168
|
-
def var_names_float(self):
|
|
169
|
-
"""
|
|
170
|
-
The names of float variables.
|
|
171
|
-
|
|
172
|
-
Returns
|
|
173
|
-
-------
|
|
174
|
-
names: list of str
|
|
175
|
-
The names of the float variables
|
|
176
|
-
|
|
177
|
-
"""
|
|
178
|
-
return self._geomp.var_names_float()
|
|
179
|
-
|
|
180
|
-
def initial_values_float(self):
|
|
181
|
-
"""
|
|
182
|
-
The initial values of the float variables.
|
|
183
|
-
|
|
184
|
-
Returns
|
|
185
|
-
-------
|
|
186
|
-
values: numpy.ndarray
|
|
187
|
-
Initial float values, shape: (n_vars_float,)
|
|
188
|
-
|
|
189
|
-
"""
|
|
190
|
-
return self._geomp.initial_values_float()
|
|
191
|
-
|
|
192
|
-
def min_values_float(self):
|
|
193
|
-
"""
|
|
194
|
-
The minimal values of the float variables.
|
|
195
|
-
|
|
196
|
-
Use -numpy.inf for unbounded.
|
|
197
|
-
|
|
198
|
-
Returns
|
|
199
|
-
-------
|
|
200
|
-
values: numpy.ndarray
|
|
201
|
-
Minimal float values, shape: (n_vars_float,)
|
|
202
|
-
|
|
203
|
-
"""
|
|
204
|
-
return self._geomp.min_values_float()
|
|
205
|
-
|
|
206
|
-
def max_values_float(self):
|
|
207
|
-
"""
|
|
208
|
-
The maximal values of the float variables.
|
|
209
|
-
|
|
210
|
-
Use numpy.inf for unbounded.
|
|
211
|
-
|
|
212
|
-
Returns
|
|
213
|
-
-------
|
|
214
|
-
values: numpy.ndarray
|
|
215
|
-
Maximal float values, shape: (n_vars_float,)
|
|
216
|
-
|
|
217
|
-
"""
|
|
218
|
-
return self._geomp.max_values_float()
|
|
219
|
-
|
|
220
|
-
def update_problem_individual(self, vars_int, vars_float):
|
|
221
|
-
"""
|
|
222
|
-
Update the algo and other data using
|
|
223
|
-
the latest optimization variables.
|
|
224
|
-
|
|
225
|
-
This function is called before running the farm
|
|
226
|
-
calculation.
|
|
227
|
-
|
|
228
|
-
Parameters
|
|
229
|
-
----------
|
|
230
|
-
vars_int: np.array
|
|
231
|
-
The integer variable values, shape: (n_vars_int,)
|
|
232
|
-
vars_float: np.array
|
|
233
|
-
The float variable values, shape: (n_vars_float,)
|
|
234
|
-
|
|
235
|
-
"""
|
|
236
|
-
n0 = self.farm.n_turbines
|
|
237
|
-
nxny = vars_int.reshape(self._geomp.n_grids, 2)
|
|
238
|
-
n = np.sum(np.product(nxny, axis=1))
|
|
239
|
-
if n0 > n:
|
|
240
|
-
self.farm.turbines = self.farm.turbines[:n]
|
|
241
|
-
elif n0 < n:
|
|
242
|
-
for i in range(n0, n):
|
|
243
|
-
self.farm.turbines.append(deepcopy(self._turbine))
|
|
244
|
-
self.farm.turbines[-1].index = n0 + i
|
|
245
|
-
self.farm.turbines[-1].name = f"T{n0 + i}"
|
|
246
|
-
if n != n0:
|
|
247
|
-
self.algo.update_n_turbines()
|
|
248
|
-
|
|
249
|
-
super().update_problem_individual(vars_int, vars_float)
|
|
250
|
-
|
|
251
|
-
def update_problem_population(self, vars_int, vars_float):
|
|
252
|
-
"""
|
|
253
|
-
Update the algo and other data using
|
|
254
|
-
the latest optimization variables.
|
|
255
|
-
|
|
256
|
-
This function is called before running the farm
|
|
257
|
-
calculation.
|
|
258
|
-
|
|
259
|
-
Parameters
|
|
260
|
-
----------
|
|
261
|
-
vars_int: np.array
|
|
262
|
-
The integer variable values, shape: (n_pop, n_vars_int,)
|
|
263
|
-
vars_float: np.array
|
|
264
|
-
The float variable values, shape: (n_pop, n_vars_float,)
|
|
265
|
-
|
|
266
|
-
"""
|
|
267
|
-
n0 = self.farm.n_turbines
|
|
268
|
-
n_pop = vars_int.shape[0]
|
|
269
|
-
nxny = vars_int.reshape(n_pop, self._geomp.n_grids, 2)
|
|
270
|
-
n = np.max(np.sum(np.product(nxny, axis=2), axis=1))
|
|
271
|
-
if n0 > n:
|
|
272
|
-
self.farm.turbines = self.farm.turbines[:n]
|
|
273
|
-
elif n0 < n:
|
|
274
|
-
for i in range(n0, n):
|
|
275
|
-
self.farm.turbines.append(deepcopy(self._turbine))
|
|
276
|
-
self.farm.turbines[-1].index = n0 + i
|
|
277
|
-
self.farm.turbines[-1].name = f"T{n0 + i}"
|
|
278
|
-
if n != n0:
|
|
279
|
-
self.algo.update_n_turbines()
|
|
280
|
-
|
|
281
|
-
super().update_problem_population(vars_int, vars_float)
|
|
282
|
-
|
|
283
|
-
def opt2farm_vars_individual(self, vars_int, vars_float):
|
|
284
|
-
"""
|
|
285
|
-
Translates optimization variables to farm variables
|
|
286
|
-
|
|
287
|
-
Parameters
|
|
288
|
-
----------
|
|
289
|
-
vars_int: numpy.ndarray
|
|
290
|
-
The integer optimization variable values,
|
|
291
|
-
shape: (n_vars_int,)
|
|
292
|
-
vars_float: numpy.ndarray
|
|
293
|
-
The float optimization variable values,
|
|
294
|
-
shape: (n_vars_float,)
|
|
295
|
-
|
|
296
|
-
Returns
|
|
297
|
-
-------
|
|
298
|
-
farm_vars: dict
|
|
299
|
-
The foxes farm variables. Key: var name,
|
|
300
|
-
value: numpy.ndarray with values, shape:
|
|
301
|
-
(n_states, n_sel_turbines)
|
|
302
|
-
|
|
303
|
-
"""
|
|
304
|
-
pts, vld = self._geomp.apply_individual(vars_int, vars_float)
|
|
305
|
-
|
|
306
|
-
n_pts = pts.shape[0]
|
|
307
|
-
n_states = self.algo.n_states
|
|
308
|
-
n_turbines = self.farm.n_turbines
|
|
309
|
-
|
|
310
|
-
pmi = np.min(self._geomp._pmin)
|
|
311
|
-
points = np.full((n_states, n_turbines, 2), pmi, dtype=FC.DTYPE)
|
|
312
|
-
if n_pts <= n_turbines:
|
|
313
|
-
points[:, :n_pts] = pts[None, :, :]
|
|
314
|
-
else:
|
|
315
|
-
points[:] = pts[None, :n_turbines, :]
|
|
316
|
-
|
|
317
|
-
valid = np.zeros((n_states, n_turbines), dtype=FC.DTYPE)
|
|
318
|
-
if n_pts <= n_turbines:
|
|
319
|
-
valid[:, :n_pts] = vld[None, :]
|
|
320
|
-
else:
|
|
321
|
-
valid[:] = vld[None, :n_turbines]
|
|
322
|
-
|
|
323
|
-
farm_vars = {FV.X: points[:, :, 0], FV.Y: points[:, :, 1], FC.VALID: valid}
|
|
324
|
-
|
|
325
|
-
return farm_vars
|
|
326
|
-
|
|
327
|
-
def opt2farm_vars_population(self, vars_int, vars_float, n_states):
|
|
328
|
-
"""
|
|
329
|
-
Translates optimization variables to farm variables
|
|
330
|
-
|
|
331
|
-
Parameters
|
|
332
|
-
----------
|
|
333
|
-
vars_int: numpy.ndarray
|
|
334
|
-
The integer optimization variable values,
|
|
335
|
-
shape: (n_pop, n_vars_int)
|
|
336
|
-
vars_float: numpy.ndarray
|
|
337
|
-
The float optimization variable values,
|
|
338
|
-
shape: (n_pop, n_vars_float)
|
|
339
|
-
n_states: int
|
|
340
|
-
The number of original (non-pop) states
|
|
341
|
-
|
|
342
|
-
Returns
|
|
343
|
-
-------
|
|
344
|
-
farm_vars: dict
|
|
345
|
-
The foxes farm variables. Key: var name,
|
|
346
|
-
value: numpy.ndarray with values, shape:
|
|
347
|
-
(n_pop, n_states, n_sel_turbines)
|
|
348
|
-
|
|
349
|
-
"""
|
|
350
|
-
pts, vld = self._geomp.apply_population(vars_int, vars_float)
|
|
351
|
-
|
|
352
|
-
n_pop, n_pts = vld.shape
|
|
353
|
-
n_states = self._org_n_states
|
|
354
|
-
n_turbines = self.farm.n_turbines
|
|
355
|
-
|
|
356
|
-
pmi = np.min(self._geomp._pmin)
|
|
357
|
-
points = np.full((n_pop, n_states, n_turbines, 2), pmi, dtype=FC.DTYPE)
|
|
358
|
-
if n_pts <= n_turbines:
|
|
359
|
-
points[:, :, :n_pts] = pts[:, None, :, :]
|
|
360
|
-
else:
|
|
361
|
-
points[:] = pts[:, None, :n_turbines, :]
|
|
362
|
-
|
|
363
|
-
valid = np.zeros((n_pop, n_states, n_turbines), dtype=FC.DTYPE)
|
|
364
|
-
if n_pts <= n_turbines:
|
|
365
|
-
valid[:, :, :n_pts] = vld[:, None, :]
|
|
366
|
-
else:
|
|
367
|
-
valid[:] = vld[:, None, :n_turbines]
|
|
368
|
-
|
|
369
|
-
farm_vars = {
|
|
370
|
-
FV.X: points[:, :, :, 0],
|
|
371
|
-
FV.Y: points[:, :, :, 1],
|
|
372
|
-
FC.VALID: valid,
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return farm_vars
|
|
376
|
-
|
|
377
|
-
def finalize_individual(self, vars_int, vars_float, verbosity=1):
|
|
378
|
-
"""
|
|
379
|
-
Finalization, given the champion data.
|
|
380
|
-
|
|
381
|
-
Parameters
|
|
382
|
-
----------
|
|
383
|
-
vars_int: np.array
|
|
384
|
-
The optimal integer variable values, shape: (n_vars_int,)
|
|
385
|
-
vars_float: np.array
|
|
386
|
-
The optimal float variable values, shape: (n_vars_float,)
|
|
387
|
-
verbosity: int
|
|
388
|
-
The verbosity level, 0 = silent
|
|
389
|
-
|
|
390
|
-
Returns
|
|
391
|
-
-------
|
|
392
|
-
problem_results: Any
|
|
393
|
-
The results of the variable application
|
|
394
|
-
to the problem
|
|
395
|
-
objs: np.array
|
|
396
|
-
The objective function values, shape: (n_objectives,)
|
|
397
|
-
cons: np.array
|
|
398
|
-
The constraints values, shape: (n_constraints,)
|
|
399
|
-
|
|
400
|
-
"""
|
|
401
|
-
pts, vld = self._geomp.apply_individual(vars_int, vars_float)
|
|
402
|
-
xy = pts[vld]
|
|
403
|
-
n_xy = xy.shape[0]
|
|
404
|
-
|
|
405
|
-
self.farm.turbines = self.farm.turbines[:n_xy]
|
|
406
|
-
for ti, t in enumerate(self.farm.turbines):
|
|
407
|
-
t.xy = xy[ti]
|
|
408
|
-
t.index = ti
|
|
409
|
-
t.name = f"T{ti}"
|
|
410
|
-
t.models = [
|
|
411
|
-
mname for mname in t.models if mname not in [self.name, self._mname]
|
|
412
|
-
]
|
|
413
|
-
self.algo.update_n_turbines()
|
|
414
|
-
|
|
415
|
-
return FarmOptProblem.finalize_individual(
|
|
416
|
-
self, vars_int, vars_float, verbosity=1
|
|
417
|
-
)
|