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,206 +0,0 @@
1
- import numpy as np
2
-
3
- from foxes.core import States, Data
4
- import foxes.constants as FC
5
- import foxes.variables as FV
6
-
7
-
8
- class PopStates(States):
9
- """
10
- Helper class for vectorized opt population
11
- calculation, via artificial states of length
12
- n_pop times n_states.
13
-
14
- Attributes
15
- ----------
16
- states: foxes.core.States
17
- The original states
18
- n_pop: int
19
- The population size
20
-
21
- :group: opt.core
22
-
23
- """
24
-
25
- def __init__(self, states, n_pop):
26
- """
27
- Constructor.
28
-
29
- Parameters
30
- ----------
31
- states: foxes.core.States
32
- The original states
33
- n_pop: int
34
- The population size
35
-
36
- """
37
- super().__init__()
38
- self.states = states
39
- self.n_pop = n_pop
40
-
41
- def load_data(self, algo, verbosity=0):
42
- """
43
- Load and/or create all model data that is subject to chunking.
44
-
45
- Such data should not be stored under self, for memory reasons. The
46
- data returned here will automatically be chunked and then provided
47
- as part of the mdata object during calculations.
48
-
49
- Parameters
50
- ----------
51
- algo: foxes.core.Algorithm
52
- The calculation algorithm
53
- verbosity: int
54
- The verbosity level, 0 = silent
55
-
56
- Returns
57
- -------
58
- idata: dict
59
- The dict has exactly two entries: `data_vars`,
60
- a dict with entries `name_str -> (dim_tuple, data_ndarray)`;
61
- and `coords`, a dict with entries `dim_name_str -> dim_array`
62
-
63
- """
64
- self.STATE0 = self.var(FC.STATE + "0")
65
- self.SMAP = self.var("SMAP")
66
-
67
- idata = super().load_data(algo, verbosity)
68
- idata0 = algo.get_model_data(self.states)
69
- for cname, coord in idata0["coords"].items():
70
- if cname != FC.STATE:
71
- idata["coords"][cname] = coord
72
- else:
73
- idata["coords"][self.STATE0] = coord
74
-
75
- for dname, (dims0, data0) in idata0["data_vars"].items():
76
- if dname != FV.WEIGHT:
77
- hdims = tuple([d if d != FC.STATE else self.STATE0 for d in dims0])
78
- idata["data_vars"][dname] = (hdims, data0)
79
-
80
- smap = np.zeros((self.n_pop, self.states.size()), dtype=np.int32)
81
- smap[:] = np.arange(self.states.size())[None, :]
82
- smap = smap.reshape(self.size())
83
- idata["data_vars"][self.SMAP] = ((FC.STATE,), smap)
84
-
85
- found = False
86
- for dname, (dims0, data0) in idata["data_vars"].items():
87
- if self.STATE0 in dims0:
88
- found = True
89
- break
90
- if not found:
91
- del idata["coords"][self.STATE0]
92
-
93
- return idata
94
-
95
- def initialize(self, algo, verbosity=0):
96
- """
97
- Initializes the model.
98
-
99
- Parameters
100
- ----------
101
- algo: foxes.core.Algorithm
102
- The calculation algorithm
103
- verbosity: int
104
- The verbosity level, 0 = silent
105
-
106
- """
107
- if not self.states.initialized:
108
- self.states.initialize(algo, verbosity)
109
- super().initialize(algo, verbosity)
110
-
111
- def size(self):
112
- """
113
- The total number of states.
114
-
115
- Returns
116
- -------
117
- int:
118
- The total number of states
119
-
120
- """
121
- return self.states.size() * self.n_pop
122
-
123
- def weights(self, algo):
124
- """
125
- The statistical weights of all states.
126
-
127
- Parameters
128
- ----------
129
- algo: foxes.core.Algorithm
130
- The calculation algorithm
131
-
132
- Returns
133
- -------
134
- weights: numpy.ndarray
135
- The weights, shape: (n_states, n_turbines)
136
-
137
- """
138
- weights = np.zeros(
139
- (self.n_pop, self.states.size(), algo.n_turbines), dtype=FC.DTYPE
140
- )
141
- weights[:] = self.states.weights(algo)[None, :, :] / self.n_pop
142
- return weights.reshape(self.size(), algo.n_turbines)
143
-
144
- def output_point_vars(self, algo):
145
- """
146
- The variables which are being modified by the model.
147
-
148
- Parameters
149
- ----------
150
- algo: foxes.core.Algorithm
151
- The calculation algorithm
152
-
153
- Returns
154
- -------
155
- output_vars: list of str
156
- The output variable names
157
-
158
- """
159
- return self.states.output_point_vars(algo)
160
-
161
- def calculate(self, algo, mdata, fdata, pdata):
162
- """ "
163
- The main model calculation.
164
-
165
- This function is executed on a single chunk of data,
166
- all computations should be based on numpy arrays.
167
-
168
- Parameters
169
- ----------
170
- algo: foxes.core.Algorithm
171
- The calculation algorithm
172
- mdata: foxes.core.Data
173
- The model data
174
- fdata: foxes.core.Data
175
- The farm data
176
- pdata: foxes.core.Data
177
- The point data
178
-
179
- Returns
180
- -------
181
- results: dict
182
- The resulting data, keys: output variable str.
183
- Values: numpy.ndarray with shape (n_states, n_points)
184
-
185
- """
186
-
187
- hdata = {}
188
- hdims = {}
189
- smap = mdata[self.SMAP]
190
- for dname, data in mdata.items():
191
- dms = mdata.dims[dname]
192
- if dname == self.SMAP or dname == self.STATE0:
193
- pass
194
- elif dms[0] == self.STATE0:
195
- hdata[dname] = data[smap]
196
- hdims[dname] = tuple([FC.STATE] + list(dms)[1:])
197
- elif self.STATE0 in dms:
198
- raise ValueError(
199
- f"States '{self.name}': Found states variable not at dimension 0 for mdata entry '{dname}': {dms}"
200
- )
201
- else:
202
- hdata[dname] = data
203
- hdims[dname] = dms
204
- hmdata = Data(hdata, hdims, mdata.loop_dims)
205
-
206
- return self.states.calculate(algo, hmdata, fdata, pdata)
@@ -1,6 +0,0 @@
1
- """
2
- Wind farm optimization objectives.
3
- """
4
-
5
- from .farm_vars import FarmVarObjective, MaxFarmPower, MinimalMaxTI
6
- from .max_n_turbines import MaxNTurbines
@@ -1,323 +0,0 @@
1
- import numpy as np
2
- import xarray as xr
3
-
4
- from foxes.opt.core.farm_objective import FarmObjective
5
- from foxes import variables as FV
6
- import foxes.constants as FC
7
-
8
-
9
- class FarmVarObjective(FarmObjective):
10
- """
11
- Objectives based on farm variables.
12
-
13
- Attributes
14
- ----------
15
- variable: str
16
- The variable name
17
- minimize: bool
18
- Switch for maximizing or minimizing
19
- deps: list of str
20
- The foxes variables on which the variable depends,
21
- or None for all
22
- rules: dict
23
- Contraction rules. Key: coordinate name str, value
24
- is str: min, max, sum, mean
25
- scale: float
26
- The scaling factor
27
-
28
- :group: opt.objectives
29
-
30
- """
31
-
32
- def __init__(
33
- self,
34
- problem,
35
- name,
36
- variable,
37
- contract_states,
38
- contract_turbines,
39
- minimize,
40
- deps=None,
41
- scale=1.0,
42
- **kwargs,
43
- ):
44
- """
45
- Constructor.
46
-
47
- Parameters
48
- ----------
49
- problem: foxes.opt.FarmOptProblem
50
- The underlying optimization problem
51
- name: str
52
- The name of the objective function
53
- variable: str
54
- The foxes variable name
55
- contract_states: str
56
- Contraction rule for states: min, max, sum, mean
57
- contract_turbines: str
58
- Contraction rule for turbines: min, max, sum, mean
59
- minimize: bool
60
- Switch for maximizing or minimizing
61
- deps: list of str
62
- The foxes variables on which the variable depends,
63
- or None for all
64
- scale: float
65
- The scaling factor
66
- kwargs: dict, optional
67
- Additional parameters for `FarmObjective`
68
-
69
- """
70
- super().__init__(problem, name, **kwargs)
71
- self.variable = variable
72
- self.minimize = minimize
73
- self.deps = deps
74
- self.scale = scale
75
- self.rules = {FC.STATE: contract_states, FC.TURBINE: contract_turbines}
76
-
77
- def initialize(self, verbosity=0):
78
- """
79
- Initialize the object.
80
-
81
- Parameters
82
- ----------
83
- verbosity: int
84
- The verbosity level, 0 = silent
85
-
86
- """
87
- super().initialize(verbosity)
88
-
89
- def n_components(self):
90
- """
91
- Returns the number of components of the
92
- function.
93
-
94
- Returns
95
- -------
96
- int:
97
- The number of components.
98
-
99
- """
100
- return 1
101
-
102
- def maximize(self):
103
- """
104
- Returns flag for maximization of each component.
105
-
106
- Returns
107
- -------
108
- flags: np.array
109
- Bool array for component maximization,
110
- shape: (n_components,)
111
-
112
- """
113
- return [not self.minimize]
114
-
115
- def vardeps_float(self):
116
- """
117
- Gets the dependencies of all components
118
- on the function float variables
119
-
120
- Returns
121
- -------
122
- deps: numpy.ndarray of bool
123
- The dependencies of components on function
124
- variables, shape: (n_components, n_vars_float)
125
-
126
- """
127
- if self.deps is None:
128
- return super().vardeps_float()
129
-
130
- out = np.zeros((self.n_components(), self.n_vars_float), dtype=bool)
131
- for i, tvr in enumerate(self.var_names_float):
132
- v, ti = self.problem.parse_tvar(tvr)
133
- if v in self.deps and ti in self.sel_turbines:
134
- out[0, i] = True
135
-
136
- return out
137
-
138
- def _contract(self, data):
139
- """
140
- Helper function for data contraction
141
- """
142
- for dim, rule in self.rules.items():
143
- if rule == "min":
144
- data = data.min(dim=dim)
145
- elif rule == "max":
146
- data = data.max(dim=dim)
147
- elif rule == "sum":
148
- data = data.sum(dim=dim)
149
- elif rule == "mean":
150
- data = data.mean(dim=dim)
151
- else:
152
- raise ValueError(
153
- f"Objective '{self.name}': Unknown contraction for dimension '{dim}': '{rule}'. Choose: min, max, sum, mean"
154
- )
155
- return data
156
-
157
- def calc_individual(self, vars_int, vars_float, problem_results, components=None):
158
- """
159
- Calculate values for a single individual of the
160
- underlying problem.
161
-
162
- Parameters
163
- ----------
164
- vars_int: np.array
165
- The integer variable values, shape: (n_vars_int,)
166
- vars_float: np.array
167
- The float variable values, shape: (n_vars_float,)
168
- problem_results: Any
169
- The results of the variable application
170
- to the problem
171
- components: list of int, optional
172
- The selected components or None for all
173
-
174
- Returns
175
- -------
176
- values: np.array
177
- The component values, shape: (n_sel_components,)
178
-
179
- """
180
- data = problem_results[self.variable]
181
- if self.n_sel_turbines < self.farm.n_turbines:
182
- data = data[:, self.sel_turbines]
183
- data = self._contract(data) / self.scale
184
-
185
- return np.array([data], dtype=np.float64)
186
-
187
- def calc_population(self, vars_int, vars_float, problem_results, components=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
- n_pop = problem_results["n_pop"].values
210
- n_states = problem_results["n_org_states"].values
211
- n_turbines = problem_results.sizes[FC.TURBINE]
212
- data = (
213
- problem_results[self.variable]
214
- .to_numpy()
215
- .reshape(n_pop, n_states, n_turbines)
216
- )
217
- data = xr.DataArray(data, dims=(FC.POP, FC.STATE, FC.TURBINE))
218
-
219
- if self.n_sel_turbines < self.farm.n_turbines:
220
- data = data[:, self.sel_turbines]
221
-
222
- return self._contract(data / self.scale).to_numpy()[:, None]
223
-
224
- def finalize_individual(self, vars_int, vars_float, problem_results, verbosity=1):
225
- """
226
- Finalization, given the champion data.
227
-
228
- Parameters
229
- ----------
230
- vars_int: np.array
231
- The optimal integer variable values, shape: (n_vars_int,)
232
- vars_float: np.array
233
- The optimal float variable values, shape: (n_vars_float,)
234
- problem_results: Any
235
- The results of the variable application
236
- to the problem
237
- verbosity: int
238
- The verbosity level, 0 = silent
239
-
240
- Returns
241
- -------
242
- values: np.array
243
- The component values, shape: (n_components,)
244
-
245
- """
246
- return (
247
- super().finalize_individual(
248
- vars_int, vars_float, problem_results, verbosity
249
- )
250
- * self.scale
251
- )
252
-
253
-
254
- class MaxFarmPower(FarmVarObjective):
255
- """
256
- Maximize the mean wind farm power
257
-
258
- Parameters
259
- ----------
260
- problem: foxes.opt.FarmOptProblem
261
- The underlying optimization problem
262
- name: str
263
- The name of the objective function
264
- kwargs: dict, optional
265
- Additional parameters for `FarmVarObjective`
266
-
267
- :group: opt.objectives
268
-
269
- """
270
-
271
- def __init__(self, problem, name="maximize_power", **kwargs):
272
- if "scale" in kwargs:
273
- scale = kwargs.pop("scale")
274
- else:
275
- scale = 0.0
276
- ttypes = problem.algo.mbook.turbine_types
277
- for t in problem.farm.turbines:
278
- for mname in t.models:
279
- if mname in ttypes:
280
- scale += ttypes[mname].P_nominal
281
- break
282
-
283
- super().__init__(
284
- problem,
285
- name,
286
- variable=FV.P,
287
- contract_states="mean",
288
- contract_turbines="sum",
289
- minimize=False,
290
- scale=scale,
291
- **kwargs,
292
- )
293
-
294
-
295
- class MinimalMaxTI(FarmVarObjective):
296
- """
297
- Minimize the maximal turbine TI
298
-
299
- Parameters
300
- ----------
301
- problem: foxes.opt.FarmOptProblem
302
- The underlying optimization problem
303
- name: str
304
- The name of the objective function
305
- kwargs: dict, optional
306
- Additional parameters for `FarmVarObjective`
307
-
308
- :group: opt.objectives
309
-
310
- """
311
-
312
- def __init__(self, problem, name="minimize_TI", **kwargs):
313
- scale = kwargs.pop("scale") if "scale" in kwargs else 1.0
314
- super().__init__(
315
- problem,
316
- name,
317
- variable=FV.TI,
318
- contract_states="max",
319
- contract_turbines="max",
320
- minimize=True,
321
- scale=scale,
322
- **kwargs,
323
- )
@@ -1,142 +0,0 @@
1
- import numpy as np
2
-
3
- from foxes.opt.core.farm_objective import FarmObjective
4
- import foxes.constants as FC
5
-
6
-
7
- class MaxNTurbines(FarmObjective):
8
- """
9
- Maximizes the number of turrbines.
10
-
11
- Attributes
12
- ----------
13
- check_valid: bool
14
- Check FC.VALID variable before counting
15
-
16
- :group: opt.objectives
17
-
18
- """
19
-
20
- def __init__(
21
- self,
22
- problem,
23
- name="max_n_turbines",
24
- check_valid=True,
25
- **kwargs,
26
- ):
27
- """
28
- Constructor.
29
-
30
- Parameters
31
- ----------
32
- problem: foxes.opt.FarmOptProblem
33
- The underlying optimization problem
34
- name: str
35
- The name of the objective function
36
- check_valid: bool
37
- Check FC.VALID variable before counting
38
- kwargs: dict, optional
39
- Additional parameters for `FarmObjective`
40
-
41
- """
42
- super().__init__(problem, name, **kwargs)
43
- self.check_valid = check_valid
44
-
45
- def n_components(self):
46
- """
47
- Returns the number of components of the
48
- function.
49
-
50
- Returns
51
- -------
52
- int:
53
- The number of components.
54
-
55
- """
56
- return 1
57
-
58
- def maximize(self):
59
- """
60
- Returns flag for maximization of each component.
61
-
62
- Returns
63
- -------
64
- flags: np.array
65
- Bool array for component maximization,
66
- shape: (n_components,)
67
-
68
- """
69
- return [True]
70
-
71
- def calc_individual(self, vars_int, vars_float, problem_results, components=None):
72
- """
73
- Calculate values for a single individual of the
74
- underlying problem.
75
-
76
- Parameters
77
- ----------
78
- vars_int: np.array
79
- The integer variable values, shape: (n_vars_int,)
80
- vars_float: np.array
81
- The float variable values, shape: (n_vars_float,)
82
- problem_results: Any
83
- The results of the variable application
84
- to the problem
85
- components: list of int, optional
86
- The selected components or None for all
87
-
88
- Returns
89
- -------
90
- values: np.array
91
- The component values, shape: (n_sel_components,)
92
-
93
- """
94
- if FC.VALID in problem_results and self.check_valid:
95
- vld = np.sum(problem_results[FC.VALID].to_numpy(), axis=1)
96
- if np.min(vld) != np.max(vld):
97
- raise ValueError(
98
- f"Objective '{self.name}': Number of valid turbines is state dependend, counting impossible"
99
- )
100
- return np.array([vld[0]], dtype=np.float64)
101
- else:
102
- return np.array([self.farm.n_turbines], dtype=np.float64)
103
-
104
- def calc_population(self, vars_int, vars_float, problem_results, components=None):
105
- """
106
- Calculate values for all individuals of a population.
107
-
108
- Parameters
109
- ----------
110
- vars_int: np.array
111
- The integer variable values, shape: (n_pop, n_vars_int)
112
- vars_float: np.array
113
- The float variable values, shape: (n_pop, n_vars_float)
114
- problem_results: Any
115
- The results of the variable application
116
- to the problem
117
- components: list of int, optional
118
- The selected components or None for all
119
-
120
- Returns
121
- -------
122
- values: np.array
123
- The component values, shape: (n_pop, n_sel_components)
124
-
125
- """
126
- n_pop = problem_results["n_pop"].to_numpy()
127
- if self.check_valid:
128
- n_states = problem_results["n_org_states"].to_numpy()
129
- n_turbines = self.farm.n_turbines
130
- vld = (
131
- problem_results[FC.VALID]
132
- .to_numpy()
133
- .reshape(n_pop, n_states, n_turbines)
134
- )
135
- vld = np.sum(vld, axis=2)
136
- if np.any(np.min(vld, axis=1) != np.max(vld, axis=1)):
137
- raise ValueError(
138
- f"Objective '{self.name}': Number of valid turbines is state dependend, counting impossible"
139
- )
140
- return vld[:, 0, None]
141
- else:
142
- return np.full((n_pop, 1), self.farm.n_turbines, dtype=vars_float.dtype)
@@ -1,7 +0,0 @@
1
- """
2
- Wind farm optimization problems.
3
- """
4
-
5
- from .opt_farm_vars import OptFarmVars
6
-
7
- from . import layout
@@ -1,9 +0,0 @@
1
- """
2
- Wind farm layout optimization problems.
3
- """
4
-
5
- from .farm_layout import FarmLayoutOptProblem
6
- from .regular_layout import RegularLayoutOptProblem
7
- from .reggrids_layout import RegGridsLayoutOptProblem
8
-
9
- from . import geom_layouts