foxes 0.5.1__py3-none-any.whl → 0.5.2__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 (66) hide show
  1. foxes/VERSION +1 -1
  2. foxes/algorithms/downwind/downwind.py +41 -46
  3. foxes/algorithms/downwind/models/point_wakes_calc.py +4 -9
  4. foxes/algorithms/downwind/models/set_amb_point_results.py +5 -22
  5. foxes/core/algorithm.py +1 -1
  6. foxes/core/data_calc_model.py +26 -2
  7. foxes/core/partial_wakes_model.py +1 -1
  8. foxes/core/rotor_model.py +36 -2
  9. foxes/core/turbine_model.py +36 -0
  10. foxes/core/turbine_type.py +35 -1
  11. foxes/core/wake_frame.py +39 -3
  12. foxes/core/wake_model.py +36 -0
  13. foxes/models/model_book.py +132 -85
  14. foxes/models/turbine_models/rotor_centre_calc.py +1 -2
  15. foxes/models/turbine_types/CpCt_file.py +13 -3
  16. foxes/models/turbine_types/CpCt_from_two.py +14 -4
  17. foxes/models/vertical_profiles/abl_log_neutral_ws.py +32 -5
  18. foxes/models/vertical_profiles/abl_log_stable_ws.py +32 -4
  19. foxes/models/vertical_profiles/abl_log_unstable_ws.py +32 -4
  20. foxes/models/vertical_profiles/abl_log_ws.py +50 -18
  21. foxes/models/wake_frames/yawed_wakes.py +15 -9
  22. foxes/models/wake_models/induction/__init__.py +1 -1
  23. foxes/models/wake_models/induction/rankine_half_body.py +33 -7
  24. foxes/models/wake_models/ti/crespo_hernandez.py +6 -1
  25. foxes/models/wake_models/ti/iec_ti.py +5 -3
  26. foxes/models/wake_models/wind/__init__.py +2 -2
  27. foxes/models/wake_models/wind/{bastankhah.py → bastankhah14.py} +11 -14
  28. foxes/models/wake_models/wind/{porte_agel.py → bastankhah16.py} +24 -16
  29. foxes/models/wake_models/wind/turbopark.py +11 -22
  30. foxes/models/wake_superpositions/__init__.py +9 -5
  31. foxes/models/wake_superpositions/ti_linear.py +134 -0
  32. foxes/models/wake_superpositions/ti_max.py +134 -0
  33. foxes/models/wake_superpositions/{ti_superp.py → ti_pow.py} +15 -57
  34. foxes/models/wake_superpositions/ti_quadratic.py +134 -0
  35. foxes/models/wake_superpositions/ws_linear.py +170 -0
  36. foxes/models/wake_superpositions/ws_max.py +173 -0
  37. foxes/models/wake_superpositions/ws_pow.py +175 -0
  38. foxes/models/wake_superpositions/{product.py → ws_product.py} +43 -22
  39. foxes/models/wake_superpositions/ws_quadratic.py +170 -0
  40. foxes/output/__init__.py +4 -0
  41. foxes/output/calc_points.py +143 -0
  42. foxes/output/flow_plots_2d/__init__.py +1 -0
  43. foxes/output/flow_plots_2d/common.py +104 -1
  44. foxes/output/flow_plots_2d/flow_plots.py +237 -569
  45. foxes/output/flow_plots_2d/get_fig.py +183 -0
  46. foxes/output/flow_plots_2d/seq_flow_ani_plugin.py +0 -1
  47. foxes/output/grids.py +705 -0
  48. foxes/output/output.py +58 -11
  49. foxes/output/results_writer.py +101 -17
  50. foxes/output/round.py +10 -0
  51. foxes/output/slice_data.py +900 -0
  52. foxes/utils/__init__.py +5 -3
  53. foxes/utils/exec_python.py +56 -0
  54. foxes/utils/geopandas_utils.py +294 -0
  55. foxes/utils/pandas_utils.py +175 -0
  56. foxes/utils/plotly_utils.py +19 -0
  57. foxes/utils/xarray_utils.py +38 -0
  58. {foxes-0.5.1.dist-info → foxes-0.5.2.dist-info}/METADATA +1 -1
  59. {foxes-0.5.1.dist-info → foxes-0.5.2.dist-info}/RECORD +63 -49
  60. foxes/models/wake_superpositions/linear.py +0 -242
  61. foxes/models/wake_superpositions/max.py +0 -258
  62. foxes/models/wake_superpositions/quadratic.py +0 -252
  63. {foxes-0.5.1.dist-info → foxes-0.5.2.dist-info}/LICENSE +0 -0
  64. {foxes-0.5.1.dist-info → foxes-0.5.2.dist-info}/WHEEL +0 -0
  65. {foxes-0.5.1.dist-info → foxes-0.5.2.dist-info}/top_level.txt +0 -0
  66. {foxes-0.5.1.dist-info → foxes-0.5.2.dist-info}/zip-safe +0 -0
@@ -1,258 +0,0 @@
1
- import numpy as np
2
- import numbers
3
-
4
- from foxes.core import WakeSuperposition
5
- import foxes.variables as FV
6
- import foxes.constants as FC
7
-
8
-
9
- class MaxSuperposition(WakeSuperposition):
10
- """
11
- Maximum supersposition of wake model results,
12
- optionally rescaled.
13
-
14
- Attributes
15
- ----------
16
- scalings: dict or number or str
17
- The scaling rules
18
- svars: list of str
19
- The scaling variables
20
-
21
- :group: models.wake_superpositions
22
-
23
- """
24
-
25
- def __init__(self, scalings, svars=None):
26
- """
27
- Constructor.
28
-
29
- Parameters
30
- ----------
31
- scalings: dict or number or str
32
- Scaling rules. If `dict`, key: variable name str,
33
- value: number or str. If `str`:
34
- - `source_turbine`: Scale by source turbine value of variable
35
- - `source_turbine_amb`: Scale by source turbine ambient value of variable
36
- - `source_turbine_<var>`: Scale by source turbine value of variable <var>
37
- svars: list of str, optional
38
- The scaling variables
39
-
40
- """
41
- super().__init__()
42
- self.scalings = scalings
43
- self.svars = svars
44
-
45
- def input_farm_vars(self, algo):
46
- """
47
- The variables which are needed for running
48
- the model.
49
-
50
- Parameters
51
- ----------
52
- algo: foxes.core.Algorithm
53
- The calculation algorithm
54
-
55
- Returns
56
- -------
57
- input_vars: list of str
58
- The input variable names
59
-
60
- """
61
- if self.svars is not None:
62
- return self.svars
63
- elif isinstance(self.scalings, dict):
64
- return list(self.scalings.keys())
65
- elif (
66
- isinstance(self.scalings, str)
67
- and len(self.scalings) > 15
68
- and self.scalings[:15] == "source_turbine_"
69
- ):
70
- return [self.scalings[15:]]
71
- else:
72
- raise ValueError(
73
- f"{self.name}: Unable to determine scaling variable for scaling = '{self.scalings}'"
74
- )
75
-
76
- def initialize(self, algo, verbosity=0):
77
- """
78
- Initializes the model.
79
-
80
- This includes loading all required data from files. The model
81
- should return all array type data as part of the idata return
82
- dictionary (and not store it under self, for memory reasons). This
83
- data will then be chunked and provided as part of the mdata object
84
- during calculations.
85
-
86
- Parameters
87
- ----------
88
- algo: foxes.core.Algorithm
89
- The calculation algorithm
90
- verbosity: int
91
- The verbosity level, 0 = silent
92
-
93
- Returns
94
- -------
95
- idata: dict
96
- The dict has exactly two entries: `data_vars`,
97
- a dict with entries `name_str -> (dim_tuple, data_ndarray)`;
98
- and `coords`, a dict with entries `dim_name_str -> dim_array`
99
-
100
- """
101
- self.SIGNS = self.var("SIGNS")
102
- return super().initialize(algo, verbosity)
103
-
104
- def calc_wakes_plus_wake(
105
- self,
106
- algo,
107
- mdata,
108
- fdata,
109
- pdata,
110
- states_source_turbine,
111
- sel_sp,
112
- variable,
113
- wake_delta,
114
- wake_model_result,
115
- ):
116
- """
117
- Add a wake delta to previous wake deltas.
118
-
119
- Parameters
120
- ----------
121
- algo: foxes.core.Algorithm
122
- The calculation algorithm
123
- mdata: foxes.core.Data
124
- The model data
125
- fdata: foxes.core.Data
126
- The farm data
127
- pdata: foxes.core.Data
128
- The evaluation point data
129
- states_source_turbine: numpy.ndarray
130
- For each state, one turbine index for the
131
- wake causing turbine. Shape: (n_states,)
132
- sel_sp: numpy.ndarray of bool
133
- The selection of points, shape: (n_states, n_points)
134
- variable: str
135
- The variable name for which the wake deltas applies
136
- wake_delta: numpy.ndarray
137
- The original wake deltas, shape: (n_states, n_points)
138
- wake_model_result: numpy.ndarray
139
- The new wake deltas of the selected points,
140
- shape: (n_sel_sp,)
141
-
142
- Returns
143
- -------
144
- wdelta: numpy.ndarray
145
- The updated wake deltas, shape: (n_states, n_points)
146
-
147
- """
148
-
149
- if np.all(np.max(np.abs(wake_model_result)) < 1e-10):
150
- return wake_delta
151
-
152
- if self.SIGNS not in mdata:
153
- mdata[self.SIGNS] = {}
154
- if variable not in mdata[self.SIGNS]:
155
- mdata[self.SIGNS][variable] = (
156
- -1 if np.all(wake_model_result <= 0.0) else 1.0
157
- )
158
-
159
- if isinstance(self.scalings, dict):
160
- try:
161
- scaling = self.scalings[variable]
162
- except KeyError:
163
- raise KeyError(
164
- f"Model '{self.name}': No scaling found for wake variable '{variable}'"
165
- )
166
- else:
167
- scaling = self.scalings
168
-
169
- wake_model_result = np.abs(wake_model_result)
170
- odelta = wake_delta[sel_sp]
171
-
172
- if scaling is None:
173
- wake_delta[sel_sp] = np.maximum(odelta, wake_model_result)
174
- return wake_delta
175
-
176
- elif isinstance(scaling, numbers.Number):
177
- wake_delta[sel_sp] = np.maximum(odelta, scaling * wake_model_result)
178
- return wake_delta
179
-
180
- elif (
181
- isinstance(scaling, str)
182
- and len(scaling) >= 14
183
- and (
184
- scaling == f"source_turbine"
185
- or scaling == "source_turbine_amb"
186
- or (len(scaling) > 15 and scaling[14] == "_")
187
- )
188
- ):
189
- if scaling == f"source_turbine":
190
- var = variable
191
- elif scaling == "source_turbine_amb":
192
- var = FV.var2amb[variable]
193
- else:
194
- var = scaling[15:]
195
-
196
- scale = self.get_data(
197
- var,
198
- FC.STATE_POINT,
199
- lookup="w",
200
- fdata=fdata,
201
- pdata=pdata,
202
- algo=algo,
203
- states_source_turbine=states_source_turbine,
204
- )[sel_sp]
205
-
206
- wake_delta[sel_sp] = np.maximum(odelta, scale * wake_model_result)
207
-
208
- return wake_delta
209
-
210
- else:
211
- raise ValueError(
212
- f"Model '{self.name}': Invalid scaling choice '{scaling}' for wake variable '{variable}', valid choices: None, <scalar>, 'source_turbine', 'source_turbine_amb', 'source_turbine_<var>'"
213
- )
214
-
215
- def calc_final_wake_delta(
216
- self,
217
- algo,
218
- mdata,
219
- fdata,
220
- pdata,
221
- variable,
222
- amb_results,
223
- wake_delta,
224
- ):
225
- """
226
- Calculate the final wake delta after adding all
227
- contributions.
228
-
229
- Parameters
230
- ----------
231
- algo: foxes.core.Algorithm
232
- The calculation algorithm
233
- mdata: foxes.core.Data
234
- The model data
235
- fdata: foxes.core.Data
236
- The farm data
237
- pdata: foxes.core.Data
238
- The evaluation point data
239
- variable: str
240
- The variable name for which the wake deltas applies
241
- amb_results: numpy.ndarray
242
- The ambient results, shape: (n_states, n_points)
243
- wake_delta: numpy.ndarray
244
- The wake deltas, shape: (n_states, n_points)
245
-
246
- Returns
247
- -------
248
- final_wake_delta: numpy.ndarray
249
- The final wake delta, which will be added to the ambient
250
- results by simple plus operation. Shape: (n_states, n_points)
251
-
252
- """
253
- try:
254
- return mdata[self.SIGNS][variable] * wake_delta
255
- except KeyError as e:
256
- if np.max(np.abs(wake_delta)) < 1e-10:
257
- return wake_delta
258
- raise e
@@ -1,252 +0,0 @@
1
- import numpy as np
2
- import numbers
3
-
4
- from foxes.core import WakeSuperposition
5
- import foxes.variables as FV
6
- import foxes.constants as FC
7
-
8
-
9
- class QuadraticSuperposition(WakeSuperposition):
10
- """
11
- Quadratic supersposition of wake model results,
12
- optionally rescaled.
13
-
14
- Attributes
15
- ----------
16
- scalings: dict or number or str
17
- The scaling rules
18
- svars: list of str
19
- The scaling variables
20
-
21
- :group: models.wake_superpositions
22
-
23
- """
24
-
25
- def __init__(self, scalings, svars=None):
26
- """
27
- Constructor.
28
-
29
- Parameters
30
- ----------
31
- scalings: dict or number or str
32
- Scaling rules. If `dict`, key: variable name str,
33
- value: number or str. If `str`:
34
- - `source_turbine`: Scale by source turbine value of variable
35
- - `source_turbine_amb`: Scale by source turbine ambient value of variable
36
- - `source_turbine_<var>`: Scale by source turbine value of variable <var>
37
- svars: list of str, optional
38
- The scaling variables
39
-
40
- """
41
- super().__init__()
42
- self.scalings = scalings
43
- self.svars = svars
44
-
45
- def input_farm_vars(self, algo):
46
- """
47
- The variables which are needed for running
48
- the model.
49
-
50
- Parameters
51
- ----------
52
- algo: foxes.core.Algorithm
53
- The calculation algorithm
54
-
55
- Returns
56
- -------
57
- input_vars: list of str
58
- The input variable names
59
-
60
- """
61
- if self.svars is not None:
62
- return self.svars
63
- elif isinstance(self.scalings, dict):
64
- return list(self.scalings.keys())
65
- elif (
66
- isinstance(self.scalings, str)
67
- and len(self.scalings) > 15
68
- and self.scalings[:15] == "source_turbine_"
69
- ):
70
- return [self.scalings[15:]]
71
- else:
72
- raise ValueError(
73
- f"{self.name}: Unable to determine scaling variable for scaling = '{self.scalings}'"
74
- )
75
-
76
- def initialize(self, algo, verbosity=0):
77
- """
78
- Initializes the model.
79
-
80
- This includes loading all required data from files. The model
81
- should return all array type data as part of the idata return
82
- dictionary (and not store it under self, for memory reasons). This
83
- data will then be chunked and provided as part of the mdata object
84
- during calculations.
85
-
86
- Parameters
87
- ----------
88
- algo: foxes.core.Algorithm
89
- The calculation algorithm
90
- verbosity: int
91
- The verbosity level, 0 = silent
92
-
93
- Returns
94
- -------
95
- idata: dict
96
- The dict has exactly two entries: `data_vars`,
97
- a dict with entries `name_str -> (dim_tuple, data_ndarray)`;
98
- and `coords`, a dict with entries `dim_name_str -> dim_array`
99
-
100
- """
101
- self.SIGNS = self.var("SIGNS")
102
- return super().initialize(algo, verbosity)
103
-
104
- def calc_wakes_plus_wake(
105
- self,
106
- algo,
107
- mdata,
108
- fdata,
109
- pdata,
110
- states_source_turbine,
111
- sel_sp,
112
- variable,
113
- wake_delta,
114
- wake_model_result,
115
- ):
116
- """
117
- Add a wake delta to previous wake deltas.
118
-
119
- Parameters
120
- ----------
121
- algo: foxes.core.Algorithm
122
- The calculation algorithm
123
- mdata: foxes.core.Data
124
- The model data
125
- fdata: foxes.core.Data
126
- The farm data
127
- pdata: foxes.core.Data
128
- The evaluation point data
129
- states_source_turbine: numpy.ndarray
130
- For each state, one turbine index for the
131
- wake causing turbine. Shape: (n_states,)
132
- sel_sp: numpy.ndarray of bool
133
- The selection of points, shape: (n_states, n_points)
134
- variable: str
135
- The variable name for which the wake deltas applies
136
- wake_delta: numpy.ndarray
137
- The original wake deltas, shape: (n_states, n_points)
138
- wake_model_result: numpy.ndarray
139
- The new wake deltas of the selected points,
140
- shape: (n_sel_sp,)
141
-
142
- Returns
143
- -------
144
- wdelta: numpy.ndarray
145
- The updated wake deltas, shape: (n_states, n_points)
146
-
147
- """
148
-
149
- if self.SIGNS not in mdata:
150
- mdata[self.SIGNS] = {}
151
- if variable not in mdata[self.SIGNS]:
152
- mdata[self.SIGNS][variable] = (
153
- -1 if np.all(wake_model_result <= 0.0) else 1.0
154
- )
155
-
156
- if isinstance(self.scalings, dict):
157
- try:
158
- scaling = self.scalings[variable]
159
- except KeyError:
160
- raise KeyError(
161
- f"Model '{self.name}': No scaling found for wake variable '{variable}'"
162
- )
163
- else:
164
- scaling = self.scalings
165
-
166
- if scaling is None:
167
- wake_delta[sel_sp] += wake_model_result**2
168
- return wake_delta
169
-
170
- elif isinstance(scaling, numbers.Number):
171
- wake_delta[sel_sp] += (scaling * wake_model_result) ** 2
172
- return wake_delta
173
-
174
- elif (
175
- isinstance(scaling, str)
176
- and len(scaling) >= 14
177
- and (
178
- scaling == f"source_turbine"
179
- or scaling == "source_turbine_amb"
180
- or (len(scaling) > 15 and scaling[14] == "_")
181
- )
182
- ):
183
- if scaling == f"source_turbine":
184
- var = variable
185
- elif scaling == "source_turbine_amb":
186
- var = FV.var2amb[variable]
187
- else:
188
- var = scaling[15:]
189
-
190
- scale = self.get_data(
191
- var,
192
- FC.STATE_POINT,
193
- lookup="w",
194
- fdata=fdata,
195
- pdata=pdata,
196
- algo=algo,
197
- states_source_turbine=states_source_turbine,
198
- )[sel_sp]
199
-
200
- wake_delta[sel_sp] += (scale * wake_model_result) ** 2
201
-
202
- return wake_delta
203
-
204
- else:
205
- raise ValueError(
206
- f"Model '{self.name}': Invalid scaling choice '{scaling}' for wake variable '{variable}', valid choices: None, <scalar>, 'source_turbine', 'source_turbine_amb', 'source_turbine_<var>'"
207
- )
208
-
209
- def calc_final_wake_delta(
210
- self,
211
- algo,
212
- mdata,
213
- fdata,
214
- pdata,
215
- variable,
216
- amb_results,
217
- wake_delta,
218
- ):
219
- """
220
- Calculate the final wake delta after adding all
221
- contributions.
222
-
223
- Parameters
224
- ----------
225
- algo: foxes.core.Algorithm
226
- The calculation algorithm
227
- mdata: foxes.core.Data
228
- The model data
229
- fdata: foxes.core.Data
230
- The farm data
231
- pdata: foxes.core.Data
232
- The evaluation point data
233
- variable: str
234
- The variable name for which the wake deltas applies
235
- amb_results: numpy.ndarray
236
- The ambient results, shape: (n_states, n_points)
237
- wake_delta: numpy.ndarray
238
- The wake deltas, shape: (n_states, n_points)
239
-
240
- Returns
241
- -------
242
- final_wake_delta: numpy.ndarray
243
- The final wake delta, which will be added to the ambient
244
- results by simple plus operation. Shape: (n_states, n_points)
245
-
246
- """
247
- try:
248
- return mdata[self.SIGNS][variable] * np.sqrt(wake_delta)
249
- except KeyError as e:
250
- if np.max(np.abs(wake_delta)) < 1e-10:
251
- return wake_delta
252
- raise e
File without changes
File without changes