/home/runner/work/amr-wind/amr-wind/amr-wind/wind_energy/actuator/FLLCOp.H Source File

AMR-Wind API: /home/runner/work/amr-wind/amr-wind/amr-wind/wind_energy/actuator/FLLCOp.H Source File
AMR-Wind API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
FLLCOp.H
Go to the documentation of this file.
1#ifndef FLLCOP_H
2#define FLLCOP_H
3
4#include <numbers>
8#include "AMReX_REAL.H"
9
10using namespace amrex::literals;
11
12namespace amr_wind::actuator {
13
19
20struct FLLCOp
21{
23 {
24 if (!fllc.initialized) {
25 return;
26 }
27 switch (fllc.correction_type) {
29 constant_chord(data, fllc);
30 break;
31 }
33 variable_chord(data, fllc);
34 break;
35 }
36 default:
37 // this should be unreachable
38 throw std::runtime_error("Invalid FLLC type");
39 }
40 }
41
42 static void constant_chord(ComponentView& data, FLLCData& fllc)
43 {
44 namespace interp = ::amr_wind::interp;
45
46 const int npts = static_cast<int>(fllc.correction_velocity.size());
47 auto& du = fllc.correction_velocity;
48
49 auto& u_les = fllc.les_velocity;
50 auto& u_opt = fllc.optimal_velocity;
51 auto& G = fllc.lift;
52 auto& dG = fllc.grad_lift;
53 VecSlice u_force_pnt_slice =
55 vs::Vector* vel_ptr = data.vel.data();
56
61 if (fllc.different_sizes) {
64 u_force_pnt_slice);
65 vel_ptr = u_force_pnt_slice.data();
66 }
67
73 for (int ip = 0; ip < npts; ++ip) {
74 const auto force = data.force[ip];
75 const auto vel = data.vel_rel[ip];
76 const auto dr = fllc.dr[ip];
77 const auto vmag = amrex::max<amrex::Real>(
79 const auto vmag2 = vmag * vmag;
80
81 const auto fv = force & vel;
82
83 G[ip] = (force - vel * fv / vmag2) / dr;
84 }
85
92 dG[0] = G[0];
93 dG[npts - 1] = -1 * G[npts - 1];
94 for (int ip = 1; ip < npts - 1; ++ip) {
95 dG[ip] = 0.5_rt * (G[ip + 1] - G[ip - 1]);
96 }
97
104 for (int ip = 0; ip < npts; ++ip) {
105
106 const auto eps_les = fllc.epsilon;
107 const auto eps_opt = fllc.optimal_epsilon[ip];
108
109 for (int jp = 0; jp < npts; ++jp) {
110
111 if (ip == jp) {
112 continue;
113 }
114
115 const auto r_dis = vs::mag(data.vel_pos[ip] - data.vel_pos[jp]);
116 const auto& vel = data.vel_rel[jp];
117 const auto vmag = amrex::max<amrex::Real>(
119
120 auto coefficient =
121 1.0_rt /
122 (-4.0_rt * std::numbers::pi_v<amrex::Real> * r_dis * vmag);
123 const auto cLes =
124 1.0_rt - std::exp(-r_dis * r_dis / (eps_les * eps_les));
125 const auto cOpt =
126 1.0_rt - std::exp(-r_dis * r_dis / (eps_opt * eps_opt));
127
128 // The sign of the induced velocity depends on which side of the
129 // blade we are on
130 if (ip < jp) {
131 coefficient *= -1.0_rt;
132 }
133
134 u_les[ip] = u_les[ip] - dG[jp] * coefficient * cLes;
135 u_opt[ip] = u_opt[ip] - dG[jp] * coefficient * cOpt;
136 }
137
138 // Relaxation to compute the induced velocity
139 const auto f = fllc.relaxation_factor;
140 du[ip] = (1.0_rt - f) * du[ip] + f * (u_opt[ip] - u_les[ip]);
141 }
142
148 for (int ip = 0; ip < npts; ++ip) {
149 vel_ptr[ip] = vel_ptr[ip] + du[ip];
150 u_les[ip] *= 0.0_rt;
151 u_opt[ip] *= 0.0_rt;
152 }
153
158 if (fllc.different_sizes) {
160 fllc.span_distance_force, u_force_pnt_slice,
161 fllc.span_distance_vel, data.vel);
162 }
163 }
164
165 static void variable_chord(ComponentView& data, FLLCData& fllc)
166 {
167 namespace interp = ::amr_wind::interp;
168
169 const int npts = static_cast<int>(fllc.correction_velocity.size());
170 auto& du = fllc.correction_velocity;
171
172 auto& nonuniform_r = fllc.nonuniform_r;
173 auto& u_les = fllc.les_velocity;
174 auto& u_opt = fllc.optimal_velocity;
175 auto& G = fllc.lift;
176 auto& nonuniform_G = fllc.nonuniform_lift;
177 VecSlice u_force_pnt_slice =
179 vs::Vector* vel_ptr = data.vel.data();
180
185 if (fllc.different_sizes) {
188 u_force_pnt_slice);
189 vel_ptr = u_force_pnt_slice.data();
190 }
191
196 for (int ip = 0; ip < npts; ++ip) {
197 const auto force = data.force[ip];
198 const auto vel = data.vel_rel[ip];
199 const auto dr = fllc.dr[ip];
200 const auto vmag = amrex::max<amrex::Real>(
202 const auto vmag2 = vmag * vmag;
203 fllc.vel_rel[ip] = vel;
204 const auto fv = force & vel;
205
206 G[ip] = (force - vel * fv / vmag2) / dr;
207 }
208
209 // Get the non-uniform distribution of force
210 if (fllc.nonuniform) {
211 interp::linear(fllc.r, G, nonuniform_r, nonuniform_G);
213 fllc.r, fllc.optimal_epsilon, nonuniform_r,
216 fllc.r, fllc.vel_rel, nonuniform_r, fllc.nonuniform_vel_rel);
217 }
218
219 const auto optimal_epsilon = (fllc.nonuniform)
221 : fllc.optimal_epsilon;
222 const auto dr = (fllc.nonuniform) ? fllc.nonuniform_dr : fllc.dr;
223 const auto vel_rel =
224 (fllc.nonuniform) ? fllc.nonuniform_vel_rel : fllc.vel_rel;
225 const auto G_new = (fllc.nonuniform) ? nonuniform_G : G;
226
231 for (int ip = 0; ip < npts; ++ip) {
232
233 const auto coefficient =
234 1.0_rt / (2.0_rt * std::numbers::pi_v<amrex::Real>);
235
236 for (int jp = 0; jp < dr.size(); ++jp) {
237
238 const auto eps_les = fllc.epsilon;
239 const auto eps_opt = optimal_epsilon[jp];
240 const auto eps_les2 = eps_les * eps_les;
241 const auto eps_opt2 = eps_opt * eps_opt;
242 const auto& vel = vel_rel[jp];
243 const auto vmag = amrex::max<amrex::Real>(
245 auto k_les = 0.0_rt;
246 auto k_opt = 0.0_rt;
247
248 const auto r_dis =
249 (fllc.nonuniform)
250 ? std::abs(fllc.r[ip] - fllc.nonuniform_r[jp])
251 : vs::mag(data.vel_pos[ip] - data.vel_pos[jp]);
252
253 if (r_dis == 0.) {
254
255 k_les = 0.5_rt / (eps_les2);
256 k_opt = 0.5_rt / (eps_opt2);
257
258 }
259
260 else {
261
262 auto exp_les = std::exp(-r_dis * r_dis / eps_les2);
263 auto exp_opt = std::exp(-r_dis * r_dis / eps_opt2);
264
265 k_les = (exp_les / eps_les2) +
266 (1.0_rt / (2.0_rt * r_dis * r_dis) *
267 (exp_les - 1.0_rt));
268 k_opt = (exp_opt / eps_opt2) +
269 (1.0_rt / (2.0_rt * r_dis * r_dis) *
270 (exp_opt - 1.0_rt));
271 }
272
273 u_les[ip] =
274 u_les[ip] + coefficient * G_new[jp] / vmag * k_les * dr[jp];
275 u_opt[ip] =
276 u_opt[ip] + coefficient * G_new[jp] / vmag * k_opt * dr[jp];
277 }
278
279 // Relaxation to compute the induced velocity
280 const auto f = fllc.relaxation_factor;
281 du[ip] = (1.0_rt - f) * du[ip] + f * (u_opt[ip] - u_les[ip]);
282 }
283
288 for (int ip = 0; ip < npts; ++ip) {
289 vel_ptr[ip] = vel_ptr[ip] + du[ip];
290 u_les[ip] *= 0.0_rt;
291 u_opt[ip] *= 0.0_rt;
292 }
293
298 if (fllc.different_sizes) {
300 fllc.span_distance_force, u_force_pnt_slice,
301 fllc.span_distance_vel, data.vel);
302 }
303 }
304};
305
306} // namespace amr_wind::actuator
307
308#endif /* FLLCOP_H */
Definition ActParser.H:6
@ ConstantChord
Definition FLLC.H:13
@ VariableChord
Definition FLLC.H:13
::amr_wind::utils::Slice< amr_wind::vs::Vector > VecSlice
Definition actuator_types.H:66
Definition linear_interpolation.H:10
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::iterator_traits< C2 >::value_type linear(const C1 xbegin, const C1 xend, const C2 yinp, const typename std::iterator_traits< C1 >::value_type &xout, const int ncomp=1, const int comp=0)
Definition linear_interpolation.H:130
Slice< T > slice(std::vector< T > &vec, const size_t start, const size_t count)
Definition Slice.H:71
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T mag(const TensorT< T > &t)
Definition tensorI.H:182
VectorT< amrex::Real > Vector
Definition vector.H:145
Definition actuator_types.H:129
VecSlice vel
Definition actuator_types.H:136
VecSlice vel_rel
Definition actuator_types.H:137
VecSlice force
Definition actuator_types.H:131
VecSlice vel_pos
Definition actuator_types.H:135
Definition FLLC.H:20
RealList span_distance_force
Definition FLLC.H:40
amrex::Real epsilon
Definition FLLC.H:23
RealList nonuniform_r
Definition FLLC.H:45
VecList vel_rel
Definition FLLC.H:47
bool initialized
Definition FLLC.H:37
amrex::Real relaxation_factor
Definition FLLC.H:24
RealList dr
Definition FLLC.H:27
RealList nonuniform_optimal_epsilon
Definition FLLC.H:49
RealList optimal_epsilon
Definition FLLC.H:28
VecList optimal_velocity
Definition FLLC.H:33
bool different_sizes
Definition FLLC.H:38
RealList nonuniform_dr
Definition FLLC.H:46
VecList correction_velocity
Definition FLLC.H:34
bool nonuniform
Definition FLLC.H:43
VecList nonuniform_vel_rel
Definition FLLC.H:48
VecList force_point_velocity
Definition FLLC.H:31
FLLCType correction_type
Definition FLLC.H:22
VecList les_velocity
Definition FLLC.H:32
VecList nonuniform_lift
Definition FLLC.H:50
VecList grad_lift
Definition FLLC.H:36
RealList span_distance_vel
Definition FLLC.H:39
RealList r
Definition FLLC.H:26
VecList lift
Definition FLLC.H:35
This struct will operate on a blade/wing. The velocity from the simulation is corrected using the Fil...
Definition FLLCOp.H:21
static void variable_chord(ComponentView &data, FLLCData &fllc)
Definition FLLCOp.H:165
void operator()(ComponentView &data, FLLCData &fllc)
Definition FLLCOp.H:22
static void constant_chord(ComponentView &data, FLLCData &fllc)
Definition FLLCOp.H:42
AMREX_GPU_HOST_DEVICE pointer data()
Definition Slice.H:55
Definition vstraits.H:10