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
@@ -0,0 +1,134 @@
1
+ import numpy as np
2
+
3
+ from foxes.core import WakeSuperposition
4
+ import foxes.variables as FV
5
+
6
+ class TILinear(WakeSuperposition):
7
+ """
8
+ Linear wake superposition for TI.
9
+
10
+ Attributes
11
+ ----------
12
+ superp_to_amb: str
13
+ The method for combining ambient with wake deltas:
14
+ linear or quadratic
15
+
16
+ :group: models.wake_superpositions
17
+
18
+ """
19
+
20
+ def __init__(self, superp_to_amb="quadratic"):
21
+ """
22
+ Constructor.
23
+
24
+ Parameters
25
+ ----------
26
+ superp_to_amb: str
27
+ The method for combining ambient with wake deltas:
28
+ linear or quadratic
29
+
30
+ """
31
+ super().__init__()
32
+ self.superp_to_amb = superp_to_amb
33
+
34
+ def calc_wakes_plus_wake(
35
+ self,
36
+ algo,
37
+ mdata,
38
+ fdata,
39
+ pdata,
40
+ states_source_turbine,
41
+ sel_sp,
42
+ variable,
43
+ wake_delta,
44
+ wake_model_result,
45
+ ):
46
+ """
47
+ Add a wake delta to previous wake deltas.
48
+
49
+ Parameters
50
+ ----------
51
+ algo: foxes.core.Algorithm
52
+ The calculation algorithm
53
+ mdata: foxes.core.Data
54
+ The model data
55
+ fdata: foxes.core.Data
56
+ The farm data
57
+ pdata: foxes.core.Data
58
+ The evaluation point data
59
+ states_source_turbine: numpy.ndarray
60
+ For each state, one turbine index for the
61
+ wake causing turbine. Shape: (n_states,)
62
+ sel_sp: numpy.ndarray of bool
63
+ The selection of points, shape: (n_states, n_points)
64
+ variable: str
65
+ The variable name for which the wake deltas applies
66
+ wake_delta: numpy.ndarray
67
+ The original wake deltas, shape: (n_states, n_points)
68
+ wake_model_result: numpy.ndarray
69
+ The new wake deltas of the selected points,
70
+ shape: (n_sel_sp,)
71
+
72
+ Returns
73
+ -------
74
+ wdelta: numpy.ndarray
75
+ The updated wake deltas, shape: (n_states, n_points)
76
+
77
+ """
78
+ if variable != FV.TI:
79
+ raise ValueError(f"Superposition '{self.name}': Expecting wake variable {FV.TI}, got {variable}")
80
+
81
+ wake_delta[sel_sp] += wake_model_result
82
+ return wake_delta
83
+
84
+ def calc_final_wake_delta(
85
+ self,
86
+ algo,
87
+ mdata,
88
+ fdata,
89
+ pdata,
90
+ variable,
91
+ amb_results,
92
+ wake_delta,
93
+ ):
94
+ """
95
+ Calculate the final wake delta after adding all
96
+ contributions.
97
+
98
+ Parameters
99
+ ----------
100
+ algo: foxes.core.Algorithm
101
+ The calculation algorithm
102
+ mdata: foxes.core.Data
103
+ The model data
104
+ fdata: foxes.core.Data
105
+ The farm data
106
+ pdata: foxes.core.Data
107
+ The evaluation point data
108
+ variable: str
109
+ The variable name for which the wake deltas applies
110
+ amb_results: numpy.ndarray
111
+ The ambient results, shape: (n_states, n_points)
112
+ wake_delta: numpy.ndarray
113
+ The wake deltas, shape: (n_states, n_points)
114
+
115
+ Returns
116
+ -------
117
+ final_wake_delta: numpy.ndarray
118
+ The final wake delta, which will be added to the ambient
119
+ results by simple plus operation. Shape: (n_states, n_points)
120
+
121
+ """
122
+ # linear superposition to ambient:
123
+ if self.superp_to_amb == "linear":
124
+ return wake_delta
125
+
126
+ # quadratic superposition to ambient:
127
+ elif self.superp_to_amb == "quadratic":
128
+ return np.sqrt(wake_delta**2 + amb_results**2) - amb_results
129
+
130
+ # unknown ti delta:
131
+ else:
132
+ raise ValueError(
133
+ f"Unknown superp_to_amb = '{self.superp_to_amb}', valid choices: linear, quadratic"
134
+ )
@@ -0,0 +1,134 @@
1
+ import numpy as np
2
+
3
+ from foxes.core import WakeSuperposition
4
+ import foxes.variables as FV
5
+
6
+ class TIMax(WakeSuperposition):
7
+ """
8
+ Max wake superposition for TI.
9
+
10
+ Attributes
11
+ ----------
12
+ superp_to_amb: str
13
+ The method for combining ambient with wake deltas:
14
+ linear or quadratic
15
+
16
+ :group: models.wake_superpositions
17
+
18
+ """
19
+
20
+ def __init__(self, superp_to_amb="quadratic"):
21
+ """
22
+ Constructor.
23
+
24
+ Parameters
25
+ ----------
26
+ superp_to_amb: str
27
+ The method for combining ambient with wake deltas:
28
+ linear or quadratic
29
+
30
+ """
31
+ super().__init__()
32
+ self.superp_to_amb = superp_to_amb
33
+
34
+ def calc_wakes_plus_wake(
35
+ self,
36
+ algo,
37
+ mdata,
38
+ fdata,
39
+ pdata,
40
+ states_source_turbine,
41
+ sel_sp,
42
+ variable,
43
+ wake_delta,
44
+ wake_model_result,
45
+ ):
46
+ """
47
+ Add a wake delta to previous wake deltas.
48
+
49
+ Parameters
50
+ ----------
51
+ algo: foxes.core.Algorithm
52
+ The calculation algorithm
53
+ mdata: foxes.core.Data
54
+ The model data
55
+ fdata: foxes.core.Data
56
+ The farm data
57
+ pdata: foxes.core.Data
58
+ The evaluation point data
59
+ states_source_turbine: numpy.ndarray
60
+ For each state, one turbine index for the
61
+ wake causing turbine. Shape: (n_states,)
62
+ sel_sp: numpy.ndarray of bool
63
+ The selection of points, shape: (n_states, n_points)
64
+ variable: str
65
+ The variable name for which the wake deltas applies
66
+ wake_delta: numpy.ndarray
67
+ The original wake deltas, shape: (n_states, n_points)
68
+ wake_model_result: numpy.ndarray
69
+ The new wake deltas of the selected points,
70
+ shape: (n_sel_sp,)
71
+
72
+ Returns
73
+ -------
74
+ wdelta: numpy.ndarray
75
+ The updated wake deltas, shape: (n_states, n_points)
76
+
77
+ """
78
+ if variable != FV.TI:
79
+ raise ValueError(f"Superposition '{self.name}': Expecting wake variable {FV.TI}, got {variable}")
80
+
81
+ wake_delta[sel_sp] = np.maximum(wake_model_result, wake_delta[sel_sp])
82
+ return wake_delta
83
+
84
+ def calc_final_wake_delta(
85
+ self,
86
+ algo,
87
+ mdata,
88
+ fdata,
89
+ pdata,
90
+ variable,
91
+ amb_results,
92
+ wake_delta,
93
+ ):
94
+ """
95
+ Calculate the final wake delta after adding all
96
+ contributions.
97
+
98
+ Parameters
99
+ ----------
100
+ algo: foxes.core.Algorithm
101
+ The calculation algorithm
102
+ mdata: foxes.core.Data
103
+ The model data
104
+ fdata: foxes.core.Data
105
+ The farm data
106
+ pdata: foxes.core.Data
107
+ The evaluation point data
108
+ variable: str
109
+ The variable name for which the wake deltas applies
110
+ amb_results: numpy.ndarray
111
+ The ambient results, shape: (n_states, n_points)
112
+ wake_delta: numpy.ndarray
113
+ The wake deltas, shape: (n_states, n_points)
114
+
115
+ Returns
116
+ -------
117
+ final_wake_delta: numpy.ndarray
118
+ The final wake delta, which will be added to the ambient
119
+ results by simple plus operation. Shape: (n_states, n_points)
120
+
121
+ """
122
+ # linear superposition to ambient:
123
+ if self.superp_to_amb == "linear":
124
+ return wake_delta
125
+
126
+ # quadratic superposition to ambient:
127
+ elif self.superp_to_amb == "quadratic":
128
+ return np.sqrt(wake_delta**2 + amb_results**2) - amb_results
129
+
130
+ # unknown ti delta:
131
+ else:
132
+ raise ValueError(
133
+ f"Unknown superp_to_amb = '{self.superp_to_amb}', valid choices: linear, quadratic"
134
+ )
@@ -1,16 +1,16 @@
1
1
  import numpy as np
2
2
 
3
3
  from foxes.core import WakeSuperposition
4
+ import foxes.variables as FV
4
5
 
5
-
6
- class TISuperposition(WakeSuperposition):
6
+ class TIPow(WakeSuperposition):
7
7
  """
8
- A collection of superpositions for TI.
8
+ Power wake superposition for TI.
9
9
 
10
10
  Attributes
11
11
  ----------
12
- ti_superp: str
13
- The method choice: linear, quadratic, power_N, max
12
+ pow: float
13
+ The power to which to take the wake results
14
14
  superp_to_amb: str
15
15
  The method for combining ambient with wake deltas:
16
16
  linear or quadratic
@@ -19,22 +19,21 @@ class TISuperposition(WakeSuperposition):
19
19
 
20
20
  """
21
21
 
22
- def __init__(self, ti_superp, superp_to_amb="quadratic"):
22
+ def __init__(self, pow, superp_to_amb="quadratic"):
23
23
  """
24
24
  Constructor.
25
25
 
26
26
  Parameters
27
27
  ----------
28
- ti_superp: str
29
- The method choice: linear, quadratic, power_N, max
28
+ pow: float
29
+ The power to which to take the wake results
30
30
  superp_to_amb: str
31
31
  The method for combining ambient with wake deltas:
32
32
  linear or quadratic
33
33
 
34
34
  """
35
35
  super().__init__()
36
-
37
- self.ti_superp = ti_superp
36
+ self.pow = pow
38
37
  self.superp_to_amb = superp_to_amb
39
38
 
40
39
  def calc_wakes_plus_wake(
@@ -81,31 +80,10 @@ class TISuperposition(WakeSuperposition):
81
80
  The updated wake deltas, shape: (n_states, n_points)
82
81
 
83
82
  """
84
-
85
- # superposition of every turbines efect at each target point
86
- # linear ti delta:
87
- if self.ti_superp == "linear":
88
- wake_delta[sel_sp] += wake_model_result
89
-
90
- # quadratic ti delta:
91
- elif self.ti_superp == "quadratic":
92
- wake_delta[sel_sp] += wake_model_result**2
93
-
94
- # power_N delta:
95
- elif len(self.ti_superp) > 6 and self.ti_superp[:6] == "power_":
96
- N = int(self.ti_superp[6:])
97
- wake_delta[sel_sp] += wake_model_result**N
98
-
99
- # max ti delta:
100
- elif self.ti_superp == "max":
101
- wake_delta[sel_sp] = np.maximum(wake_model_result, wake_delta[sel_sp])
102
-
103
- # unknown ti delta:
104
- else:
105
- raise ValueError(
106
- f"Unknown ti_superp = '{self.ti_superp}', valid choices: linear, quadratic, power_N, max"
107
- )
108
-
83
+ if variable != FV.TI:
84
+ raise ValueError(f"Superposition '{self.name}': Expecting wake variable {FV.TI}, got {variable}")
85
+
86
+ wake_delta[sel_sp] += wake_model_result**self.pow
109
87
  return wake_delta
110
88
 
111
89
  def calc_final_wake_delta(
@@ -148,31 +126,11 @@ class TISuperposition(WakeSuperposition):
148
126
  """
149
127
  # linear superposition to ambient:
150
128
  if self.superp_to_amb == "linear":
151
- if self.ti_superp == "linear" or self.ti_superp == "max":
152
- return wake_delta
153
- elif self.ti_superp == "quadratic":
154
- return np.sqrt(wake_delta)
155
- elif len(self.ti_superp) > 6 and self.ti_superp[:6] == "power_":
156
- N = int(self.ti_superp[6:])
157
- return wake_delta ** (1 / N)
158
- else:
159
- raise ValueError(
160
- f"Unknown ti_superp = '{self.ti_superp}', valid choices: linear, quadratic, power_N, max"
161
- )
129
+ return wake_delta ** (1/self.pow)
162
130
 
163
131
  # quadratic superposition to ambient:
164
132
  elif self.superp_to_amb == "quadratic":
165
- if self.ti_superp == "linear" or self.ti_superp == "max":
166
- return np.sqrt(wake_delta**2 + amb_results**2) - amb_results
167
- elif self.ti_superp == "quadratic":
168
- return np.sqrt(wake_delta + amb_results**2) - amb_results
169
- elif len(self.ti_superp) > 6 and self.ti_superp[:6] == "power_":
170
- N = int(self.ti_superp[6:])
171
- return np.sqrt(wake_delta ** (2 / N) + amb_results**2) - amb_results
172
- else:
173
- raise ValueError(
174
- f"Unknown ti_superp = '{self.ti_superp}', valid choices: linear, quadratic, power_N, max"
175
- )
133
+ return np.sqrt(wake_delta **(2/self.pow) + amb_results**2) - amb_results
176
134
 
177
135
  # unknown ti delta:
178
136
  else:
@@ -0,0 +1,134 @@
1
+ import numpy as np
2
+
3
+ from foxes.core import WakeSuperposition
4
+ import foxes.variables as FV
5
+
6
+ class TIQuadratic(WakeSuperposition):
7
+ """
8
+ Quadratic wake superposition for TI.
9
+
10
+ Attributes
11
+ ----------
12
+ superp_to_amb: str
13
+ The method for combining ambient with wake deltas:
14
+ linear or quadratic
15
+
16
+ :group: models.wake_superpositions
17
+
18
+ """
19
+
20
+ def __init__(self, superp_to_amb="quadratic"):
21
+ """
22
+ Constructor.
23
+
24
+ Parameters
25
+ ----------
26
+ superp_to_amb: str
27
+ The method for combining ambient with wake deltas:
28
+ linear or quadratic
29
+
30
+ """
31
+ super().__init__()
32
+ self.superp_to_amb = superp_to_amb
33
+
34
+ def calc_wakes_plus_wake(
35
+ self,
36
+ algo,
37
+ mdata,
38
+ fdata,
39
+ pdata,
40
+ states_source_turbine,
41
+ sel_sp,
42
+ variable,
43
+ wake_delta,
44
+ wake_model_result,
45
+ ):
46
+ """
47
+ Add a wake delta to previous wake deltas.
48
+
49
+ Parameters
50
+ ----------
51
+ algo: foxes.core.Algorithm
52
+ The calculation algorithm
53
+ mdata: foxes.core.Data
54
+ The model data
55
+ fdata: foxes.core.Data
56
+ The farm data
57
+ pdata: foxes.core.Data
58
+ The evaluation point data
59
+ states_source_turbine: numpy.ndarray
60
+ For each state, one turbine index for the
61
+ wake causing turbine. Shape: (n_states,)
62
+ sel_sp: numpy.ndarray of bool
63
+ The selection of points, shape: (n_states, n_points)
64
+ variable: str
65
+ The variable name for which the wake deltas applies
66
+ wake_delta: numpy.ndarray
67
+ The original wake deltas, shape: (n_states, n_points)
68
+ wake_model_result: numpy.ndarray
69
+ The new wake deltas of the selected points,
70
+ shape: (n_sel_sp,)
71
+
72
+ Returns
73
+ -------
74
+ wdelta: numpy.ndarray
75
+ The updated wake deltas, shape: (n_states, n_points)
76
+
77
+ """
78
+ if variable != FV.TI:
79
+ raise ValueError(f"Superposition '{self.name}': Expecting wake variable {FV.TI}, got {variable}")
80
+
81
+ wake_delta[sel_sp] += wake_model_result**2
82
+ return wake_delta
83
+
84
+ def calc_final_wake_delta(
85
+ self,
86
+ algo,
87
+ mdata,
88
+ fdata,
89
+ pdata,
90
+ variable,
91
+ amb_results,
92
+ wake_delta,
93
+ ):
94
+ """
95
+ Calculate the final wake delta after adding all
96
+ contributions.
97
+
98
+ Parameters
99
+ ----------
100
+ algo: foxes.core.Algorithm
101
+ The calculation algorithm
102
+ mdata: foxes.core.Data
103
+ The model data
104
+ fdata: foxes.core.Data
105
+ The farm data
106
+ pdata: foxes.core.Data
107
+ The evaluation point data
108
+ variable: str
109
+ The variable name for which the wake deltas applies
110
+ amb_results: numpy.ndarray
111
+ The ambient results, shape: (n_states, n_points)
112
+ wake_delta: numpy.ndarray
113
+ The wake deltas, shape: (n_states, n_points)
114
+
115
+ Returns
116
+ -------
117
+ final_wake_delta: numpy.ndarray
118
+ The final wake delta, which will be added to the ambient
119
+ results by simple plus operation. Shape: (n_states, n_points)
120
+
121
+ """
122
+ # linear superposition to ambient:
123
+ if self.superp_to_amb == "linear":
124
+ return np.sqrt(wake_delta)
125
+
126
+ # quadratic superposition to ambient:
127
+ elif self.superp_to_amb == "quadratic":
128
+ return np.sqrt(wake_delta + amb_results**2) - amb_results
129
+
130
+ # unknown ti delta:
131
+ else:
132
+ raise ValueError(
133
+ f"Unknown superp_to_amb = '{self.superp_to_amb}', valid choices: linear, quadratic"
134
+ )
@@ -0,0 +1,170 @@
1
+ import numpy as np
2
+
3
+ from foxes.core import WakeSuperposition
4
+ import foxes.variables as FV
5
+ import foxes.constants as FC
6
+
7
+ class WSLinear(WakeSuperposition):
8
+ """
9
+ Linear supersposition of wind deficit results
10
+
11
+ Attributes
12
+ ----------
13
+ scale_amb: bool
14
+ Flag for scaling wind deficit with ambient wind speed
15
+ instead of waked wind speed
16
+ lim_low: float
17
+ Lower limit of the final waked wind speed
18
+ lim_high: float
19
+ Upper limit of the final waked wind speed
20
+
21
+ :group: models.wake_superpositions
22
+
23
+ """
24
+
25
+ def __init__(self, scale_amb=False, lim_low=None, lim_high=None):
26
+ """
27
+ Constructor.
28
+
29
+ Parameters
30
+ ----------
31
+ scale_amb: bool
32
+ Flag for scaling wind deficit with ambient wind speed
33
+ instead of waked wind speed
34
+ lim_low: float
35
+ Lower limit of the final waked wind speed
36
+ lim_high: float
37
+ Upper limit of the final waked wind speed
38
+
39
+ """
40
+ super().__init__()
41
+
42
+ self.scale_amb = scale_amb
43
+ self.lim_low = lim_low
44
+ self.lim_high = lim_high
45
+
46
+ def input_farm_vars(self, algo):
47
+ """
48
+ The variables which are needed for running
49
+ the model.
50
+
51
+ Parameters
52
+ ----------
53
+ algo: foxes.core.Algorithm
54
+ The calculation algorithm
55
+
56
+ Returns
57
+ -------
58
+ input_vars: list of str
59
+ The input variable names
60
+
61
+ """
62
+ return [FV.AMB_REWS] if self.scale_amb else [FV.REWS]
63
+
64
+ def calc_wakes_plus_wake(
65
+ self,
66
+ algo,
67
+ mdata,
68
+ fdata,
69
+ pdata,
70
+ states_source_turbine,
71
+ sel_sp,
72
+ variable,
73
+ wake_delta,
74
+ wake_model_result,
75
+ ):
76
+ """
77
+ Add a wake delta to previous wake deltas.
78
+
79
+ Parameters
80
+ ----------
81
+ algo: foxes.core.Algorithm
82
+ The calculation algorithm
83
+ mdata: foxes.core.Data
84
+ The model data
85
+ fdata: foxes.core.Data
86
+ The farm data
87
+ pdata: foxes.core.Data
88
+ The evaluation point data
89
+ states_source_turbine: numpy.ndarray
90
+ For each state, one turbine index for the
91
+ wake causing turbine. Shape: (n_states,)
92
+ sel_sp: numpy.ndarray of bool
93
+ The selection of points, shape: (n_states, n_points)
94
+ variable: str
95
+ The variable name for which the wake deltas applies
96
+ wake_delta: numpy.ndarray
97
+ The original wake deltas, shape: (n_states, n_points)
98
+ wake_model_result: numpy.ndarray
99
+ The new wake deltas of the selected points,
100
+ shape: (n_sel_sp,)
101
+
102
+ Returns
103
+ -------
104
+ wdelta: numpy.ndarray
105
+ The updated wake deltas, shape: (n_states, n_points)
106
+
107
+ """
108
+ if variable not in [FV.REWS, FV.REWS2, FV.REWS3, FV.WS]:
109
+ raise ValueError(f"Superposition '{self.name}': Expecting wind speed variable, got {variable}")
110
+
111
+ if np.any(sel_sp):
112
+ scale = self.get_data(
113
+ FV.AMB_REWS if self.scale_amb else FV.REWS,
114
+ FC.STATE_POINT,
115
+ lookup="w",
116
+ algo=algo,
117
+ fdata=fdata,
118
+ pdata=pdata,
119
+ upcast=True,
120
+ states_source_turbine=states_source_turbine,
121
+ )[sel_sp]
122
+
123
+ wake_delta[sel_sp] += scale * wake_model_result
124
+
125
+ return wake_delta
126
+
127
+ def calc_final_wake_delta(
128
+ self,
129
+ algo,
130
+ mdata,
131
+ fdata,
132
+ pdata,
133
+ variable,
134
+ amb_results,
135
+ wake_delta,
136
+ ):
137
+ """
138
+ Calculate the final wake delta after adding all
139
+ contributions.
140
+
141
+ Parameters
142
+ ----------
143
+ algo: foxes.core.Algorithm
144
+ The calculation algorithm
145
+ mdata: foxes.core.Data
146
+ The model data
147
+ fdata: foxes.core.Data
148
+ The farm data
149
+ pdata: foxes.core.Data
150
+ The evaluation point data
151
+ variable: str
152
+ The variable name for which the wake deltas applies
153
+ amb_results: numpy.ndarray
154
+ The ambient results, shape: (n_states, n_points)
155
+ wake_delta: numpy.ndarray
156
+ The wake deltas, shape: (n_states, n_points)
157
+
158
+ Returns
159
+ -------
160
+ final_wake_delta: numpy.ndarray
161
+ The final wake delta, which will be added to the ambient
162
+ results by simple plus operation. Shape: (n_states, n_points)
163
+
164
+ """
165
+ w = wake_delta
166
+ if self.lim_low is not None:
167
+ w = np.maximum(w, self.lim_low - amb_results)
168
+ if self.lim_high is not None:
169
+ w = np.minimum(w, self.lim_high - amb_results)
170
+ return w