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,802 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
from scipy.spatial.distance import cdist
|
|
3
|
-
from iwopy import Constraint
|
|
4
|
-
|
|
5
|
-
import foxes.constants as FC
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Valid(Constraint):
|
|
9
|
-
"""
|
|
10
|
-
Validity constraint for purely geometrical layouts problems.
|
|
11
|
-
|
|
12
|
-
:group: opt.problems.layout.geom_layouts.constraints
|
|
13
|
-
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
def __init__(self, problem, name="valid", **kwargs):
|
|
17
|
-
"""
|
|
18
|
-
Constructor.
|
|
19
|
-
|
|
20
|
-
Parameters
|
|
21
|
-
----------
|
|
22
|
-
problem: foxes.opt.FarmOptProblem
|
|
23
|
-
The underlying geometrical layout
|
|
24
|
-
optimization problem
|
|
25
|
-
name: str
|
|
26
|
-
The constraint name
|
|
27
|
-
kwargs: dict, optional
|
|
28
|
-
Additioal parameters for the base class
|
|
29
|
-
|
|
30
|
-
"""
|
|
31
|
-
super().__init__(
|
|
32
|
-
problem,
|
|
33
|
-
name,
|
|
34
|
-
vnames_int=problem.var_names_int(),
|
|
35
|
-
vnames_float=problem.var_names_float(),
|
|
36
|
-
**kwargs,
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
def n_components(self):
|
|
40
|
-
"""
|
|
41
|
-
Returns the number of components of the
|
|
42
|
-
function.
|
|
43
|
-
|
|
44
|
-
Returns
|
|
45
|
-
-------
|
|
46
|
-
int:
|
|
47
|
-
The number of components.
|
|
48
|
-
|
|
49
|
-
"""
|
|
50
|
-
return 1
|
|
51
|
-
|
|
52
|
-
def calc_individual(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
53
|
-
"""
|
|
54
|
-
Calculate values for a single individual of the
|
|
55
|
-
underlying problem.
|
|
56
|
-
|
|
57
|
-
Parameters
|
|
58
|
-
----------
|
|
59
|
-
vars_int : np.array
|
|
60
|
-
The integer variable values, shape: (n_vars_int,)
|
|
61
|
-
vars_float : np.array
|
|
62
|
-
The float variable values, shape: (n_vars_float,)
|
|
63
|
-
problem_results : Any
|
|
64
|
-
The results of the variable application
|
|
65
|
-
to the problem
|
|
66
|
-
components : list of int, optional
|
|
67
|
-
The selected components or None for all
|
|
68
|
-
|
|
69
|
-
Returns
|
|
70
|
-
-------
|
|
71
|
-
values : np.array
|
|
72
|
-
The component values, shape: (n_sel_components,)
|
|
73
|
-
|
|
74
|
-
"""
|
|
75
|
-
__, valid = problem_results
|
|
76
|
-
return np.sum(~valid)
|
|
77
|
-
|
|
78
|
-
def calc_population(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
79
|
-
"""
|
|
80
|
-
Calculate values for all individuals of a population.
|
|
81
|
-
|
|
82
|
-
Parameters
|
|
83
|
-
----------
|
|
84
|
-
vars_int : np.array
|
|
85
|
-
The integer variable values, shape: (n_pop, n_vars_int)
|
|
86
|
-
vars_float : np.array
|
|
87
|
-
The float variable values, shape: (n_pop, n_vars_float)
|
|
88
|
-
problem_results : Any
|
|
89
|
-
The results of the variable application
|
|
90
|
-
to the problem
|
|
91
|
-
components : list of int, optional
|
|
92
|
-
The selected components or None for all
|
|
93
|
-
|
|
94
|
-
Returns
|
|
95
|
-
-------
|
|
96
|
-
values : np.array
|
|
97
|
-
The component values, shape: (n_pop, n_sel_components)
|
|
98
|
-
|
|
99
|
-
"""
|
|
100
|
-
__, valid = problem_results
|
|
101
|
-
return np.sum(~valid, axis=1)[:, None]
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
class Boundary(Constraint):
|
|
105
|
-
"""
|
|
106
|
-
Boundary constraint for purely geometrical layouts problems.
|
|
107
|
-
|
|
108
|
-
:group: opt.problems.layout.geom_layouts.constraints
|
|
109
|
-
|
|
110
|
-
"""
|
|
111
|
-
|
|
112
|
-
def __init__(self, problem, n_turbines=None, D=None, name="boundary", **kwargs):
|
|
113
|
-
"""
|
|
114
|
-
Constructor.
|
|
115
|
-
|
|
116
|
-
Parameters
|
|
117
|
-
----------
|
|
118
|
-
problem: foxes.opt.FarmOptProblem
|
|
119
|
-
The underlying geometrical layout
|
|
120
|
-
optimization problem
|
|
121
|
-
n_turbines: int, optional
|
|
122
|
-
The number of turbines
|
|
123
|
-
D: float, optional
|
|
124
|
-
The rotor diameter
|
|
125
|
-
name: str
|
|
126
|
-
The constraint name
|
|
127
|
-
kwargs: dict, optional
|
|
128
|
-
Additioal parameters for the base class
|
|
129
|
-
|
|
130
|
-
"""
|
|
131
|
-
super().__init__(
|
|
132
|
-
problem,
|
|
133
|
-
name,
|
|
134
|
-
vnames_int=problem.var_names_int(),
|
|
135
|
-
vnames_float=problem.var_names_float(),
|
|
136
|
-
**kwargs,
|
|
137
|
-
)
|
|
138
|
-
self.n_turbines = problem.n_turbines if n_turbines is None else n_turbines
|
|
139
|
-
self.D = problem.D if D is None else D
|
|
140
|
-
|
|
141
|
-
def n_components(self):
|
|
142
|
-
"""
|
|
143
|
-
Returns the number of components of the
|
|
144
|
-
function.
|
|
145
|
-
|
|
146
|
-
Returns
|
|
147
|
-
-------
|
|
148
|
-
int:
|
|
149
|
-
The number of components.
|
|
150
|
-
|
|
151
|
-
"""
|
|
152
|
-
return self.n_turbines
|
|
153
|
-
|
|
154
|
-
def calc_individual(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
155
|
-
"""
|
|
156
|
-
Calculate values for a single individual of the
|
|
157
|
-
underlying problem.
|
|
158
|
-
|
|
159
|
-
Parameters
|
|
160
|
-
----------
|
|
161
|
-
vars_int : np.array
|
|
162
|
-
The integer variable values, shape: (n_vars_int,)
|
|
163
|
-
vars_float : np.array
|
|
164
|
-
The float variable values, shape: (n_vars_float,)
|
|
165
|
-
problem_results : Any
|
|
166
|
-
The results of the variable application
|
|
167
|
-
to the problem
|
|
168
|
-
components : list of int, optional
|
|
169
|
-
The selected components or None for all
|
|
170
|
-
|
|
171
|
-
Returns
|
|
172
|
-
-------
|
|
173
|
-
values : np.array
|
|
174
|
-
The component values, shape: (n_sel_components,)
|
|
175
|
-
|
|
176
|
-
"""
|
|
177
|
-
xy, __ = problem_results
|
|
178
|
-
|
|
179
|
-
dists = self.problem.boundary.points_distance(xy)
|
|
180
|
-
dists[self.problem.boundary.points_inside(xy)] *= -1
|
|
181
|
-
|
|
182
|
-
if self.D is not None:
|
|
183
|
-
dists += self.D / 2
|
|
184
|
-
|
|
185
|
-
return dists
|
|
186
|
-
|
|
187
|
-
def calc_population(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
188
|
-
"""
|
|
189
|
-
Calculate values for all individuals of a population.
|
|
190
|
-
|
|
191
|
-
Parameters
|
|
192
|
-
----------
|
|
193
|
-
vars_int : np.array
|
|
194
|
-
The integer variable values, shape: (n_pop, n_vars_int)
|
|
195
|
-
vars_float : np.array
|
|
196
|
-
The float variable values, shape: (n_pop, n_vars_float)
|
|
197
|
-
problem_results : Any
|
|
198
|
-
The results of the variable application
|
|
199
|
-
to the problem
|
|
200
|
-
components : list of int, optional
|
|
201
|
-
The selected components or None for all
|
|
202
|
-
|
|
203
|
-
Returns
|
|
204
|
-
-------
|
|
205
|
-
values : np.array
|
|
206
|
-
The component values, shape: (n_pop, n_sel_components)
|
|
207
|
-
|
|
208
|
-
"""
|
|
209
|
-
xy, __ = problem_results
|
|
210
|
-
n_pop, n_xy = xy.shape[:2]
|
|
211
|
-
|
|
212
|
-
xy = xy.reshape(n_pop * n_xy, 2)
|
|
213
|
-
dists = self.problem.boundary.points_distance(xy)
|
|
214
|
-
dists[self.problem.boundary.points_inside(xy)] *= -1
|
|
215
|
-
dists = dists.reshape(n_pop, n_xy)
|
|
216
|
-
|
|
217
|
-
if self.D is not None:
|
|
218
|
-
dists += self.D / 2
|
|
219
|
-
|
|
220
|
-
return dists
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
class MinDist(Constraint):
|
|
224
|
-
"""
|
|
225
|
-
Minimal distance constraint for purely geometrical layouts problems.
|
|
226
|
-
|
|
227
|
-
:group: opt.problems.layout.geom_layouts.constraints
|
|
228
|
-
|
|
229
|
-
"""
|
|
230
|
-
|
|
231
|
-
def __init__(
|
|
232
|
-
self, problem, min_dist=None, n_turbines=None, name="min_dist", **kwargs
|
|
233
|
-
):
|
|
234
|
-
"""
|
|
235
|
-
Constructor.
|
|
236
|
-
|
|
237
|
-
Parameters
|
|
238
|
-
----------
|
|
239
|
-
problem: foxes.opt.FarmOptProblem
|
|
240
|
-
The underlying geometrical layout
|
|
241
|
-
optimization problem
|
|
242
|
-
min_dist: float, optional
|
|
243
|
-
The minimal distance between turbines
|
|
244
|
-
n_turbines: int, optional
|
|
245
|
-
The number of turbines
|
|
246
|
-
name: str
|
|
247
|
-
The constraint name
|
|
248
|
-
kwargs: dict, optional
|
|
249
|
-
Additioal parameters for the base class
|
|
250
|
-
|
|
251
|
-
"""
|
|
252
|
-
super().__init__(
|
|
253
|
-
problem,
|
|
254
|
-
name,
|
|
255
|
-
vnames_int=problem.var_names_int(),
|
|
256
|
-
vnames_float=problem.var_names_float(),
|
|
257
|
-
**kwargs,
|
|
258
|
-
)
|
|
259
|
-
self.min_dist = problem.min_dist if min_dist is None else min_dist
|
|
260
|
-
self.n_turbines = problem.n_turbines if n_turbines is None else n_turbines
|
|
261
|
-
|
|
262
|
-
def initialize(self, verbosity=0):
|
|
263
|
-
"""
|
|
264
|
-
Initialize the constaint.
|
|
265
|
-
|
|
266
|
-
Parameters
|
|
267
|
-
----------
|
|
268
|
-
verbosity: int
|
|
269
|
-
The verbosity level, 0 = silent
|
|
270
|
-
|
|
271
|
-
"""
|
|
272
|
-
N = self.n_turbines
|
|
273
|
-
self._i2t = [] # i --> (ti, tj)
|
|
274
|
-
self._t2i = np.full([N, N], -1) # (ti, tj) --> i
|
|
275
|
-
i = 0
|
|
276
|
-
for ti in range(N):
|
|
277
|
-
for tj in range(N):
|
|
278
|
-
if ti != tj and self._t2i[ti, tj] < 0:
|
|
279
|
-
self._i2t.append([ti, tj])
|
|
280
|
-
self._t2i[ti, tj] = i
|
|
281
|
-
self._t2i[tj, ti] = i
|
|
282
|
-
i += 1
|
|
283
|
-
self._i2t = np.array(self._i2t)
|
|
284
|
-
self._cnames = [f"{self.name}_{ti}_{tj}" for ti, tj in self._i2t]
|
|
285
|
-
super().initialize(verbosity)
|
|
286
|
-
|
|
287
|
-
def n_components(self):
|
|
288
|
-
"""
|
|
289
|
-
Returns the number of components of the
|
|
290
|
-
function.
|
|
291
|
-
|
|
292
|
-
Returns
|
|
293
|
-
-------
|
|
294
|
-
int:
|
|
295
|
-
The number of components.
|
|
296
|
-
|
|
297
|
-
"""
|
|
298
|
-
return len(self._i2t)
|
|
299
|
-
|
|
300
|
-
def calc_individual(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
301
|
-
"""
|
|
302
|
-
Calculate values for a single individual of the
|
|
303
|
-
underlying problem.
|
|
304
|
-
|
|
305
|
-
Parameters
|
|
306
|
-
----------
|
|
307
|
-
vars_int : np.array
|
|
308
|
-
The integer variable values, shape: (n_vars_int,)
|
|
309
|
-
vars_float : np.array
|
|
310
|
-
The float variable values, shape: (n_vars_float,)
|
|
311
|
-
problem_results : Any
|
|
312
|
-
The results of the variable application
|
|
313
|
-
to the problem
|
|
314
|
-
components : list of int, optional
|
|
315
|
-
The selected components or None for all
|
|
316
|
-
|
|
317
|
-
Returns
|
|
318
|
-
-------
|
|
319
|
-
values : np.array
|
|
320
|
-
The component values, shape: (n_sel_components,)
|
|
321
|
-
|
|
322
|
-
"""
|
|
323
|
-
xy, __ = problem_results
|
|
324
|
-
|
|
325
|
-
a = np.take_along_axis(xy, self._i2t[:, 0, None], axis=0)
|
|
326
|
-
b = np.take_along_axis(xy, self._i2t[:, 1, None], axis=0)
|
|
327
|
-
d = np.linalg.norm(a - b, axis=-1)
|
|
328
|
-
|
|
329
|
-
return self.min_dist - d
|
|
330
|
-
|
|
331
|
-
def calc_population(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
332
|
-
"""
|
|
333
|
-
Calculate values for all individuals of a population.
|
|
334
|
-
|
|
335
|
-
Parameters
|
|
336
|
-
----------
|
|
337
|
-
vars_int : np.array
|
|
338
|
-
The integer variable values, shape: (n_pop, n_vars_int)
|
|
339
|
-
vars_float : np.array
|
|
340
|
-
The float variable values, shape: (n_pop, n_vars_float)
|
|
341
|
-
problem_results : Any
|
|
342
|
-
The results of the variable application
|
|
343
|
-
to the problem
|
|
344
|
-
components : list of int, optional
|
|
345
|
-
The selected components or None for all
|
|
346
|
-
|
|
347
|
-
Returns
|
|
348
|
-
-------
|
|
349
|
-
values : np.array
|
|
350
|
-
The component values, shape: (n_pop, n_sel_components)
|
|
351
|
-
|
|
352
|
-
"""
|
|
353
|
-
xy, __ = problem_results
|
|
354
|
-
|
|
355
|
-
a = np.take_along_axis(xy, self._i2t[None, :, 0, None], axis=1)
|
|
356
|
-
b = np.take_along_axis(xy, self._i2t[None, :, 1, None], axis=1)
|
|
357
|
-
d = np.linalg.norm(a - b, axis=-1)
|
|
358
|
-
|
|
359
|
-
return self.min_dist - d
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
class CMinN(Constraint):
|
|
363
|
-
"""
|
|
364
|
-
Minimal number of turbines constraint for purely geometrical layouts problems.
|
|
365
|
-
|
|
366
|
-
:group: opt.problems.layout.geom_layouts.constraints
|
|
367
|
-
|
|
368
|
-
"""
|
|
369
|
-
|
|
370
|
-
def __init__(self, problem, N, name="cminN", **kwargs):
|
|
371
|
-
super().__init__(
|
|
372
|
-
problem,
|
|
373
|
-
name,
|
|
374
|
-
vnames_int=problem.var_names_int(),
|
|
375
|
-
vnames_float=problem.var_names_float(),
|
|
376
|
-
**kwargs,
|
|
377
|
-
)
|
|
378
|
-
"""
|
|
379
|
-
Constructor.
|
|
380
|
-
|
|
381
|
-
Parameters
|
|
382
|
-
----------
|
|
383
|
-
problem: foxes.opt.FarmOptProblem
|
|
384
|
-
The underlying geometrical layout
|
|
385
|
-
optimization problem
|
|
386
|
-
N: int
|
|
387
|
-
The minimal number of turbines
|
|
388
|
-
name: str
|
|
389
|
-
The constraint name
|
|
390
|
-
kwargs: dict, optional
|
|
391
|
-
Additioal parameters for the base class
|
|
392
|
-
|
|
393
|
-
"""
|
|
394
|
-
self.N = N
|
|
395
|
-
|
|
396
|
-
def n_components(self):
|
|
397
|
-
"""
|
|
398
|
-
Returns the number of components of the
|
|
399
|
-
function.
|
|
400
|
-
|
|
401
|
-
Returns
|
|
402
|
-
-------
|
|
403
|
-
int:
|
|
404
|
-
The number of components.
|
|
405
|
-
|
|
406
|
-
"""
|
|
407
|
-
return 1
|
|
408
|
-
|
|
409
|
-
def calc_individual(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
410
|
-
"""
|
|
411
|
-
Calculate values for a single individual of the
|
|
412
|
-
underlying problem.
|
|
413
|
-
|
|
414
|
-
Parameters
|
|
415
|
-
----------
|
|
416
|
-
vars_int : np.array
|
|
417
|
-
The integer variable values, shape: (n_vars_int,)
|
|
418
|
-
vars_float : np.array
|
|
419
|
-
The float variable values, shape: (n_vars_float,)
|
|
420
|
-
problem_results : Any
|
|
421
|
-
The results of the variable application
|
|
422
|
-
to the problem
|
|
423
|
-
components : list of int, optional
|
|
424
|
-
The selected components or None for all
|
|
425
|
-
|
|
426
|
-
Returns
|
|
427
|
-
-------
|
|
428
|
-
values : np.array
|
|
429
|
-
The component values, shape: (n_sel_components,)
|
|
430
|
-
|
|
431
|
-
"""
|
|
432
|
-
__, valid = problem_results
|
|
433
|
-
return self.N - np.sum(valid)
|
|
434
|
-
|
|
435
|
-
def calc_population(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
436
|
-
"""
|
|
437
|
-
Calculate values for all individuals of a population.
|
|
438
|
-
|
|
439
|
-
Parameters
|
|
440
|
-
----------
|
|
441
|
-
vars_int : np.array
|
|
442
|
-
The integer variable values, shape: (n_pop, n_vars_int)
|
|
443
|
-
vars_float : np.array
|
|
444
|
-
The float variable values, shape: (n_pop, n_vars_float)
|
|
445
|
-
problem_results : Any
|
|
446
|
-
The results of the variable application
|
|
447
|
-
to the problem
|
|
448
|
-
components : list of int, optional
|
|
449
|
-
The selected components or None for all
|
|
450
|
-
|
|
451
|
-
Returns
|
|
452
|
-
-------
|
|
453
|
-
values : np.array
|
|
454
|
-
The component values, shape: (n_pop, n_sel_components)
|
|
455
|
-
|
|
456
|
-
"""
|
|
457
|
-
__, valid = problem_results
|
|
458
|
-
return self.N - np.sum(valid, axis=1)[:, None]
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
class CMaxN(Constraint):
|
|
462
|
-
"""
|
|
463
|
-
Maximal number of turbines constraint for purely geometrical layouts problems.
|
|
464
|
-
|
|
465
|
-
:group: opt.problems.layout.geom_layouts.constraints
|
|
466
|
-
|
|
467
|
-
"""
|
|
468
|
-
|
|
469
|
-
def __init__(self, problem, N, name="cmaxN", **kwargs):
|
|
470
|
-
"""
|
|
471
|
-
Constructor.
|
|
472
|
-
|
|
473
|
-
Parameters
|
|
474
|
-
----------
|
|
475
|
-
problem: foxes.opt.FarmOptProblem
|
|
476
|
-
The underlying geometrical layout
|
|
477
|
-
optimization problem
|
|
478
|
-
N: int
|
|
479
|
-
The maximal number of turbines
|
|
480
|
-
name: str
|
|
481
|
-
The constraint name
|
|
482
|
-
kwargs: dict, optional
|
|
483
|
-
Additioal parameters for the base class
|
|
484
|
-
|
|
485
|
-
"""
|
|
486
|
-
super().__init__(
|
|
487
|
-
problem,
|
|
488
|
-
name,
|
|
489
|
-
vnames_int=problem.var_names_int(),
|
|
490
|
-
vnames_float=problem.var_names_float(),
|
|
491
|
-
**kwargs,
|
|
492
|
-
)
|
|
493
|
-
self.N = N
|
|
494
|
-
|
|
495
|
-
def n_components(self):
|
|
496
|
-
"""
|
|
497
|
-
Returns the number of components of the
|
|
498
|
-
function.
|
|
499
|
-
|
|
500
|
-
Returns
|
|
501
|
-
-------
|
|
502
|
-
int:
|
|
503
|
-
The number of components.
|
|
504
|
-
|
|
505
|
-
"""
|
|
506
|
-
return 1
|
|
507
|
-
|
|
508
|
-
def calc_individual(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
509
|
-
"""
|
|
510
|
-
Calculate values for a single individual of the
|
|
511
|
-
underlying problem.
|
|
512
|
-
|
|
513
|
-
Parameters
|
|
514
|
-
----------
|
|
515
|
-
vars_int : np.array
|
|
516
|
-
The integer variable values, shape: (n_vars_int,)
|
|
517
|
-
vars_float : np.array
|
|
518
|
-
The float variable values, shape: (n_vars_float,)
|
|
519
|
-
problem_results : Any
|
|
520
|
-
The results of the variable application
|
|
521
|
-
to the problem
|
|
522
|
-
components : list of int, optional
|
|
523
|
-
The selected components or None for all
|
|
524
|
-
|
|
525
|
-
Returns
|
|
526
|
-
-------
|
|
527
|
-
values : np.array
|
|
528
|
-
The component values, shape: (n_sel_components,)
|
|
529
|
-
|
|
530
|
-
"""
|
|
531
|
-
__, valid = problem_results
|
|
532
|
-
return np.sum(valid) - self.N
|
|
533
|
-
|
|
534
|
-
def calc_population(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
535
|
-
"""
|
|
536
|
-
Calculate values for all individuals of a population.
|
|
537
|
-
|
|
538
|
-
Parameters
|
|
539
|
-
----------
|
|
540
|
-
vars_int : np.array
|
|
541
|
-
The integer variable values, shape: (n_pop, n_vars_int)
|
|
542
|
-
vars_float : np.array
|
|
543
|
-
The float variable values, shape: (n_pop, n_vars_float)
|
|
544
|
-
problem_results : Any
|
|
545
|
-
The results of the variable application
|
|
546
|
-
to the problem
|
|
547
|
-
components : list of int, optional
|
|
548
|
-
The selected components or None for all
|
|
549
|
-
|
|
550
|
-
Returns
|
|
551
|
-
-------
|
|
552
|
-
values : np.array
|
|
553
|
-
The component values, shape: (n_pop, n_sel_components)
|
|
554
|
-
|
|
555
|
-
"""
|
|
556
|
-
__, valid = problem_results
|
|
557
|
-
return np.sum(valid, axis=1)[:, None] - self.N
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
class CFixN(Constraint):
|
|
561
|
-
"""
|
|
562
|
-
Fixed number of turbines constraint for purely geometrical layouts problems.
|
|
563
|
-
|
|
564
|
-
:group: opt.problems.layout.geom_layouts.constraints
|
|
565
|
-
|
|
566
|
-
"""
|
|
567
|
-
|
|
568
|
-
def __init__(self, problem, N, name="cfixN", **kwargs):
|
|
569
|
-
"""
|
|
570
|
-
Constructor.
|
|
571
|
-
|
|
572
|
-
Parameters
|
|
573
|
-
----------
|
|
574
|
-
problem: foxes.opt.FarmOptProblem
|
|
575
|
-
The underlying geometrical layout
|
|
576
|
-
optimization problem
|
|
577
|
-
N: int
|
|
578
|
-
The number of turbines
|
|
579
|
-
name: str
|
|
580
|
-
The constraint name
|
|
581
|
-
kwargs: dict, optional
|
|
582
|
-
Additioal parameters for the base class
|
|
583
|
-
|
|
584
|
-
"""
|
|
585
|
-
super().__init__(
|
|
586
|
-
problem,
|
|
587
|
-
name,
|
|
588
|
-
vnames_int=problem.var_names_int(),
|
|
589
|
-
vnames_float=problem.var_names_float(),
|
|
590
|
-
tol=0.1,
|
|
591
|
-
**kwargs,
|
|
592
|
-
)
|
|
593
|
-
self.N = N
|
|
594
|
-
|
|
595
|
-
def n_components(self):
|
|
596
|
-
"""
|
|
597
|
-
Returns the number of components of the
|
|
598
|
-
function.
|
|
599
|
-
|
|
600
|
-
Returns
|
|
601
|
-
-------
|
|
602
|
-
int:
|
|
603
|
-
The number of components.
|
|
604
|
-
|
|
605
|
-
"""
|
|
606
|
-
return 2
|
|
607
|
-
|
|
608
|
-
def calc_individual(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
609
|
-
"""
|
|
610
|
-
Calculate values for a single individual of the
|
|
611
|
-
underlying problem.
|
|
612
|
-
|
|
613
|
-
Parameters
|
|
614
|
-
----------
|
|
615
|
-
vars_int : np.array
|
|
616
|
-
The integer variable values, shape: (n_vars_int,)
|
|
617
|
-
vars_float : np.array
|
|
618
|
-
The float variable values, shape: (n_vars_float,)
|
|
619
|
-
problem_results : Any
|
|
620
|
-
The results of the variable application
|
|
621
|
-
to the problem
|
|
622
|
-
components : list of int, optional
|
|
623
|
-
The selected components or None for all
|
|
624
|
-
|
|
625
|
-
Returns
|
|
626
|
-
-------
|
|
627
|
-
values : np.array
|
|
628
|
-
The component values, shape: (n_sel_components,)
|
|
629
|
-
|
|
630
|
-
"""
|
|
631
|
-
__, valid = problem_results
|
|
632
|
-
vld = np.sum(valid)
|
|
633
|
-
return np.array([self.N - vld, vld - self.N])
|
|
634
|
-
|
|
635
|
-
def calc_population(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
636
|
-
"""
|
|
637
|
-
Calculate values for all individuals of a population.
|
|
638
|
-
|
|
639
|
-
Parameters
|
|
640
|
-
----------
|
|
641
|
-
vars_int : np.array
|
|
642
|
-
The integer variable values, shape: (n_pop, n_vars_int)
|
|
643
|
-
vars_float : np.array
|
|
644
|
-
The float variable values, shape: (n_pop, n_vars_float)
|
|
645
|
-
problem_results : Any
|
|
646
|
-
The results of the variable application
|
|
647
|
-
to the problem
|
|
648
|
-
components : list of int, optional
|
|
649
|
-
The selected components or None for all
|
|
650
|
-
|
|
651
|
-
Returns
|
|
652
|
-
-------
|
|
653
|
-
values : np.array
|
|
654
|
-
The component values, shape: (n_pop, n_sel_components)
|
|
655
|
-
|
|
656
|
-
"""
|
|
657
|
-
__, valid = problem_results
|
|
658
|
-
vld = np.sum(valid, axis=1)
|
|
659
|
-
return np.stack([self.N - vld, vld - self.N], axis=-1)
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
class CMinDensity(Constraint):
|
|
663
|
-
"""
|
|
664
|
-
Minimal turbine density constraint for purely geometrical layouts problems.
|
|
665
|
-
|
|
666
|
-
:group: opt.problems.layout.geom_layouts.constraints
|
|
667
|
-
|
|
668
|
-
"""
|
|
669
|
-
|
|
670
|
-
def __init__(self, problem, min_value, dfactor=1, name="min_density"):
|
|
671
|
-
"""
|
|
672
|
-
Constructor.
|
|
673
|
-
|
|
674
|
-
Parameters
|
|
675
|
-
----------
|
|
676
|
-
problem: foxes.opt.FarmOptProblem
|
|
677
|
-
The underlying geometrical layout
|
|
678
|
-
optimization problem
|
|
679
|
-
min_value: float
|
|
680
|
-
The minimal turbine density
|
|
681
|
-
dfactor: float
|
|
682
|
-
Delta factor for grid spacing
|
|
683
|
-
name: str
|
|
684
|
-
The constraint name
|
|
685
|
-
kwargs: dict, optional
|
|
686
|
-
Additioal parameters for the base class
|
|
687
|
-
|
|
688
|
-
"""
|
|
689
|
-
super().__init__(
|
|
690
|
-
problem,
|
|
691
|
-
name,
|
|
692
|
-
vnames_int=problem.var_names_int(),
|
|
693
|
-
vnames_float=problem.var_names_float(),
|
|
694
|
-
)
|
|
695
|
-
self.min_value = min_value
|
|
696
|
-
self.dfactor = dfactor
|
|
697
|
-
|
|
698
|
-
def n_components(self):
|
|
699
|
-
"""
|
|
700
|
-
Returns the number of components of the
|
|
701
|
-
function.
|
|
702
|
-
|
|
703
|
-
Returns
|
|
704
|
-
-------
|
|
705
|
-
int:
|
|
706
|
-
The number of components.
|
|
707
|
-
|
|
708
|
-
"""
|
|
709
|
-
return 1
|
|
710
|
-
|
|
711
|
-
def initialize(self, verbosity):
|
|
712
|
-
"""
|
|
713
|
-
Initialize the object.
|
|
714
|
-
|
|
715
|
-
Parameters
|
|
716
|
-
----------
|
|
717
|
-
verbosity: int
|
|
718
|
-
The verbosity level, 0 = silent
|
|
719
|
-
|
|
720
|
-
"""
|
|
721
|
-
super().initialize(verbosity)
|
|
722
|
-
|
|
723
|
-
# define regular grid of probe points:
|
|
724
|
-
geom = self.problem.boundary
|
|
725
|
-
pmin = geom.p_min()
|
|
726
|
-
pmax = geom.p_max()
|
|
727
|
-
detlta = self.problem.min_dist / self.dfactor
|
|
728
|
-
self._probes = np.stack(
|
|
729
|
-
np.meshgrid(
|
|
730
|
-
np.arange(pmin[0] - detlta, pmax[0] + 2 * detlta, detlta),
|
|
731
|
-
np.arange(pmin[1] - detlta, pmax[1] + 2 * detlta, detlta),
|
|
732
|
-
indexing="ij",
|
|
733
|
-
),
|
|
734
|
-
axis=-1,
|
|
735
|
-
)
|
|
736
|
-
nx, ny = self._probes.shape[:2]
|
|
737
|
-
n = nx * ny
|
|
738
|
-
self._probes = self._probes.reshape(n, 2)
|
|
739
|
-
|
|
740
|
-
# reduce to points within geometry:
|
|
741
|
-
valid = geom.points_inside(self._probes)
|
|
742
|
-
self._probes = self._probes[valid]
|
|
743
|
-
|
|
744
|
-
def calc_individual(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
745
|
-
"""
|
|
746
|
-
Calculate values for a single individual of the
|
|
747
|
-
underlying problem.
|
|
748
|
-
|
|
749
|
-
Parameters
|
|
750
|
-
----------
|
|
751
|
-
vars_int : np.array
|
|
752
|
-
The integer variable values, shape: (n_vars_int,)
|
|
753
|
-
vars_float : np.array
|
|
754
|
-
The float variable values, shape: (n_vars_float,)
|
|
755
|
-
problem_results : Any
|
|
756
|
-
The results of the variable application
|
|
757
|
-
to the problem
|
|
758
|
-
components : list of int, optional
|
|
759
|
-
The selected components or None for all
|
|
760
|
-
|
|
761
|
-
Returns
|
|
762
|
-
-------
|
|
763
|
-
values : np.array
|
|
764
|
-
The component values, shape: (n_sel_components,)
|
|
765
|
-
|
|
766
|
-
"""
|
|
767
|
-
xy, valid = problem_results
|
|
768
|
-
xy = xy[valid]
|
|
769
|
-
dists = cdist(self._probes, xy)
|
|
770
|
-
return np.nanmax(np.nanmin(dists, axis=1)) - self.min_value
|
|
771
|
-
|
|
772
|
-
def calc_population(self, vars_int, vars_float, problem_results, cmpnts=None):
|
|
773
|
-
"""
|
|
774
|
-
Calculate values for all individuals of a population.
|
|
775
|
-
|
|
776
|
-
Parameters
|
|
777
|
-
----------
|
|
778
|
-
vars_int : np.array
|
|
779
|
-
The integer variable values, shape: (n_pop, n_vars_int)
|
|
780
|
-
vars_float : np.array
|
|
781
|
-
The float variable values, shape: (n_pop, n_vars_float)
|
|
782
|
-
problem_results : Any
|
|
783
|
-
The results of the variable application
|
|
784
|
-
to the problem
|
|
785
|
-
components : list of int, optional
|
|
786
|
-
The selected components or None for all
|
|
787
|
-
|
|
788
|
-
Returns
|
|
789
|
-
-------
|
|
790
|
-
values : np.array
|
|
791
|
-
The component values, shape: (n_pop, n_sel_components)
|
|
792
|
-
|
|
793
|
-
"""
|
|
794
|
-
n_pop = vars_float.shape[0]
|
|
795
|
-
xy, valid = problem_results
|
|
796
|
-
out = np.full(n_pop, 1e20, dtype=FC.DTYPE)
|
|
797
|
-
for pi in range(n_pop):
|
|
798
|
-
if np.any(valid[pi]):
|
|
799
|
-
hxy = xy[pi][valid[pi]]
|
|
800
|
-
dists = cdist(self._probes, hxy)
|
|
801
|
-
out[pi] = np.nanmax(np.nanmin(dists, axis=1)) - self.min_value
|
|
802
|
-
return out[:, None]
|