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.

Files changed (33) hide show
  1. foxes/VERSION +1 -1
  2. {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/METADATA +20 -116
  3. {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/RECORD +7 -33
  4. foxes/opt/__init__.py +0 -9
  5. foxes/opt/constraints/__init__.py +0 -6
  6. foxes/opt/constraints/area_geometry.py +0 -214
  7. foxes/opt/constraints/min_dist.py +0 -239
  8. foxes/opt/core/__init__.py +0 -9
  9. foxes/opt/core/farm_constraint.py +0 -96
  10. foxes/opt/core/farm_objective.py +0 -97
  11. foxes/opt/core/farm_opt_problem.py +0 -346
  12. foxes/opt/core/farm_vars_problem.py +0 -219
  13. foxes/opt/core/pop_states.py +0 -206
  14. foxes/opt/objectives/__init__.py +0 -6
  15. foxes/opt/objectives/farm_vars.py +0 -323
  16. foxes/opt/objectives/max_n_turbines.py +0 -142
  17. foxes/opt/problems/__init__.py +0 -7
  18. foxes/opt/problems/layout/__init__.py +0 -9
  19. foxes/opt/problems/layout/farm_layout.py +0 -137
  20. foxes/opt/problems/layout/geom_layouts/__init__.py +0 -10
  21. foxes/opt/problems/layout/geom_layouts/constraints.py +0 -802
  22. foxes/opt/problems/layout/geom_layouts/geom_layout.py +0 -290
  23. foxes/opt/problems/layout/geom_layouts/geom_layout_gridded.py +0 -276
  24. foxes/opt/problems/layout/geom_layouts/geom_reggrid.py +0 -351
  25. foxes/opt/problems/layout/geom_layouts/geom_reggrids.py +0 -482
  26. foxes/opt/problems/layout/geom_layouts/objectives.py +0 -666
  27. foxes/opt/problems/layout/reggrids_layout.py +0 -417
  28. foxes/opt/problems/layout/regular_layout.py +0 -350
  29. foxes/opt/problems/opt_farm_vars.py +0 -586
  30. {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/LICENSE +0 -0
  31. {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/WHEEL +0 -0
  32. {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/top_level.txt +0 -0
  33. {foxes-0.7.4.25.dist-info → foxes-0.8.1.dist-info}/zip-safe +0 -0
@@ -1,351 +0,0 @@
1
- import numpy as np
2
- import matplotlib.pyplot as plt
3
- from scipy.spatial.distance import cdist
4
- from iwopy import Problem
5
-
6
- import foxes.constants as FC
7
-
8
-
9
- class GeomRegGrid(Problem):
10
- """
11
- A regular grid within a boundary geometry.
12
-
13
- This optimization problem does not involve
14
- wind farms.
15
-
16
- Attributes
17
- ----------
18
- boundary: foxes.utils.geom2d.AreaGeometry
19
- The boundary geometry
20
- n_turbines: int
21
- The number of turbines in the layout
22
- min_dist: float
23
- The minimal distance between points
24
- max_dist: float
25
- The maximal distance between points
26
- D: float
27
- The diameter of circle fully within boundary
28
-
29
- :group: opt.problems.layout.geom_layouts
30
-
31
- """
32
-
33
- def __init__(
34
- self,
35
- boundary,
36
- n_turbines,
37
- min_dist,
38
- max_dist=None,
39
- D=None,
40
- ):
41
- """
42
- Constructor.
43
-
44
- Parameters
45
- ----------
46
- boundary: foxes.utils.geom2d.AreaGeometry
47
- The boundary geometry
48
- n_turbines: int
49
- The number of turbines in the layout
50
- min_dist: float
51
- The minimal distance between points
52
- max_dist: float, optional
53
- The maximal distance between points
54
- D: float, optional
55
- The diameter of circle fully within boundary
56
-
57
- """
58
- super().__init__(name="geom_reg_grid")
59
-
60
- self.boundary = boundary
61
- self.n_turbines = n_turbines
62
- self.min_dist = float(min_dist)
63
- self.max_dist = float(max_dist) if max_dist is not None else max_dist
64
- self.D = D
65
-
66
- self._SX = "sx"
67
- self._SY = "sy"
68
- self._DX = "dx"
69
- self._DY = "dy"
70
- self._ALPHA = "alpha"
71
-
72
- def initialize(self, verbosity=1):
73
- """
74
- Initialize the object.
75
-
76
- Parameters
77
- ----------
78
- verbosity: int
79
- The verbosity level, 0 = silent
80
-
81
- """
82
- super().initialize(verbosity)
83
-
84
- pmin = self.boundary.p_min()
85
- pmax = self.boundary.p_max()
86
- self._pc = 0.5 * (pmin + pmax)
87
- self._diag = np.linalg.norm(pmax - pmin)
88
- self.max_dist = self._diag if self.max_dist is None else self.max_dist
89
- self._nrow = (
90
- int(np.maximum(self._diag / self.min_dist, np.sqrt(self.n_turbines) + 0.5))
91
- + 3
92
- )
93
-
94
- if verbosity > 0:
95
- print(f"Grid data:")
96
- print(f" pmin = {pmin}")
97
- print(f" pmax = {pmax}")
98
- print(f" min dist = {self.min_dist}")
99
- print(f" max dist = {self.max_dist}")
100
- print(f" n row max = {self._nrow}")
101
- print(f" n max = {self._nrow**2}")
102
-
103
- self.apply_individual(self.initial_values_int(), self.initial_values_float())
104
-
105
- def var_names_float(self):
106
- """
107
- The names of float variables.
108
-
109
- Returns
110
- -------
111
- names: list of str
112
- The names of the float variables
113
-
114
- """
115
- return list(np.array([self._SX, self._SY, self._DX, self._DY, self._ALPHA]))
116
-
117
- def initial_values_float(self):
118
- """
119
- The initial values of the float variables.
120
-
121
- Returns
122
- -------
123
- values: numpy.ndarray
124
- Initial float values, shape: (n_vars_float,)
125
-
126
- """
127
- vals = np.zeros(5, dtype=FC.DTYPE)
128
- vals[2:4] = self.min_dist
129
- return vals
130
-
131
- def min_values_float(self):
132
- """
133
- The minimal values of the float variables.
134
-
135
- Use -numpy.inf for unbounded.
136
-
137
- Returns
138
- -------
139
- values: numpy.ndarray
140
- Minimal float values, shape: (n_vars_float,)
141
-
142
- """
143
- vals = np.zeros(5, dtype=FC.DTYPE)
144
- vals[:2] = -0.5
145
- vals[2:4] = self.min_dist
146
- return vals
147
-
148
- def max_values_float(self):
149
- """
150
- The maximal values of the float variables.
151
-
152
- Use numpy.inf for unbounded.
153
-
154
- Returns
155
- -------
156
- values: numpy.ndarray
157
- Maximal float values, shape: (n_vars_float,)
158
-
159
- """
160
- vals = np.zeros(5, dtype=FC.DTYPE)
161
- vals[:2] = 0.5
162
- vals[2:4] = self.max_dist
163
- vals[4] = 90.0
164
- return vals
165
-
166
- def apply_individual(self, vars_int, vars_float):
167
- """
168
- Apply new variables to the problem.
169
-
170
- Parameters
171
- ----------
172
- vars_int: np.array
173
- The integer variable values, shape: (n_vars_int,)
174
- vars_float: np.array
175
- The float variable values, shape: (n_vars_float,)
176
-
177
- Returns
178
- -------
179
- problem_results: Any
180
- The results of the variable application
181
- to the problem
182
-
183
- """
184
- sx, sy, dx, dy, alpha = vars_float
185
-
186
- a = np.deg2rad(alpha)
187
- nax = np.stack([np.cos(a), np.sin(a)], axis=-1)
188
- nay = np.stack([-np.sin(a), np.cos(a)], axis=-1)
189
-
190
- pts = (
191
- self._pc[None, None, :]
192
- + (np.arange(self._nrow)[:, None, None] - (self._nrow - 1) / 2 + sx)
193
- * dx
194
- * nax[None, None, :]
195
- + (np.arange(self._nrow)[None, :, None] - (self._nrow - 1) / 2 + sy)
196
- * dy
197
- * nay[None, None, :]
198
- )
199
- pts = pts.reshape(self._nrow**2, 2)
200
-
201
- if self.D is None:
202
- valid = self.boundary.points_inside(pts)
203
- else:
204
- valid = self.boundary.points_inside(pts) & (
205
- self.boundary.points_distance(pts) >= self.D / 2
206
- )
207
-
208
- nvl = np.sum(valid)
209
- if nvl >= self.n_turbines:
210
- return pts[valid][: self.n_turbines], np.ones(self.n_turbines, dtype=bool)
211
- else:
212
- qts = np.append(pts[valid], pts[~valid][: (self.n_turbines - nvl)], axis=0)
213
- vld = np.zeros(self.n_turbines, dtype=bool)
214
- vld[:nvl] = True
215
- return qts, vld
216
-
217
- def apply_population(self, vars_int, vars_float):
218
- """
219
- Apply new variables to the problem,
220
- for a whole population.
221
-
222
- Parameters
223
- ----------
224
- vars_int: np.array
225
- The integer variable values, shape: (n_pop, n_vars_int)
226
- vars_float: np.array
227
- The float variable values, shape: (n_pop, n_vars_float)
228
-
229
- Returns
230
- -------
231
- problem_results: Any
232
- The results of the variable application
233
- to the problem
234
-
235
- """
236
- n_pop = vars_float.shape[0]
237
- sx = vars_float[:, 0]
238
- sy = vars_float[:, 1]
239
- dx = vars_float[:, 2]
240
- dy = vars_float[:, 3]
241
- alpha = vars_float[:, 4]
242
-
243
- a = np.deg2rad(alpha)
244
- nax = np.stack([np.cos(a), np.sin(a)], axis=-1)
245
- nay = np.stack([-np.sin(a), np.cos(a)], axis=-1)
246
-
247
- pts = (
248
- self._pc[None, None, None, :]
249
- + (
250
- np.arange(self._nrow)[None, :, None, None]
251
- - (self._nrow - 1) / 2
252
- + sx[:, None, None, None]
253
- )
254
- * dx[:, None, None, None]
255
- * nax[:, None, None, :]
256
- + (
257
- np.arange(self._nrow)[None, None, :, None]
258
- - (self._nrow - 1) / 2
259
- + sy[:, None, None, None]
260
- )
261
- * dy[:, None, None, None]
262
- * nay[:, None, None, :]
263
- )
264
- pts = pts.reshape(n_pop * self._nrow**2, 2)
265
-
266
- if self.D is None:
267
- valid = self.boundary.points_inside(pts)
268
- else:
269
- valid = self.boundary.points_inside(pts) & (
270
- self.boundary.points_distance(pts) >= self.D / 2
271
- )
272
- valid = valid.reshape(n_pop, self._nrow**2)
273
- pts = pts.reshape(n_pop, self._nrow**2, 2)
274
-
275
- nvl = np.sum(valid, axis=1)
276
- qts = np.zeros((n_pop, self.n_turbines, 2), dtype=FC.DTYPE)
277
- vld = np.zeros((n_pop, self.n_turbines), dtype=bool)
278
- for pi in range(n_pop):
279
- if nvl[pi] >= self.n_turbines:
280
- qts[pi] = pts[pi, valid[pi]][: self.n_turbines]
281
- vld[pi] = np.ones(self.n_turbines, dtype=bool)
282
- else:
283
- qts[pi] = np.append(
284
- pts[pi, valid[pi]],
285
- pts[pi, ~valid[pi]][: (self.n_turbines - nvl[pi])],
286
- axis=0,
287
- )
288
- vld[pi, : nvl[pi]] = True
289
-
290
- return qts, vld
291
-
292
- def get_fig(
293
- self, xy=None, valid=None, ax=None, title=None, true_circle=True, **bargs
294
- ):
295
- """
296
- Return plotly figure axis.
297
-
298
- Parameters
299
- ----------
300
- xy: numpy.ndarary, optional
301
- The xy coordinate array, shape: (n_points, 2)
302
- valid: numpy.ndarray, optional
303
- Boolean array of validity, shape: (n_points,)
304
- ax: pyplot.Axis, optional
305
- The figure axis
306
- title: str, optional
307
- The figure title
308
- true_circle: bool
309
- Draw points as circles with diameter self.D
310
- bars: dict, optional
311
- The boundary plot arguments
312
-
313
- Returns
314
- -------
315
- ax: pyplot.Axis
316
- The figure axis
317
-
318
- """
319
- if ax is None:
320
- __, ax = plt.subplots()
321
-
322
- hbargs = {"fill_mode": "inside_lightgray"}
323
- hbargs.update(bargs)
324
- self.boundary.add_to_figure(ax, **hbargs)
325
-
326
- if xy is not None:
327
- if valid is not None:
328
- xy = xy[valid]
329
- if not true_circle or self.D is None:
330
- ax.scatter(xy[:, 0], xy[:, 1], color="orange")
331
- else:
332
- for x, y in xy:
333
- ax.add_patch(
334
- plt.Circle((x, y), self.D / 2, color="blue", fill=True)
335
- )
336
-
337
- ax.set_aspect("equal", adjustable="box")
338
- ax.set_xlabel("x [m]")
339
- ax.set_ylabel("y [m]")
340
-
341
- if title is None:
342
- if xy is None:
343
- title = f"Optimization area"
344
- else:
345
- l = len(xy) if xy is not None else 0
346
- dists = cdist(xy, xy)
347
- np.fill_diagonal(dists, 1e20)
348
- title = f"N = {l}, min_dist = {np.min(dists):.1f} m"
349
- ax.set_title(title)
350
-
351
- return ax