/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
7
8namespace amr_wind::actuator {
9
16struct FLLCOp
17{
19 {
20 if (!fllc.initialized) {
21 return;
22 }
23 switch (fllc.correction_type) {
25 constant_chord(data, fllc);
26 break;
27 }
29 variable_chord(data, fllc);
30 break;
31 }
32 default:
33 // this should be unreachable
34 throw std::runtime_error("Invalid FLLC type");
35 }
36 }
37
38 static void constant_chord(ComponentView& data, FLLCData& fllc)
39 {
40 namespace interp = ::amr_wind::interp;
41
42 const int npts = static_cast<int>(fllc.correction_velocity.size());
43 auto& du = fllc.correction_velocity;
44
45 auto& u_les = fllc.les_velocity;
46 auto& u_opt = fllc.optimal_velocity;
47 auto& G = fllc.lift;
48 auto& dG = fllc.grad_lift;
49 VecSlice u_force_pnt_slice =
51 vs::Vector* vel_ptr = data.vel.data();
52
57 if (fllc.different_sizes) {
60 u_force_pnt_slice);
61 vel_ptr = u_force_pnt_slice.data();
62 }
63
69 for (int ip = 0; ip < npts; ++ip) {
70 const auto force = data.force[ip];
71 const auto vel = data.vel_rel[ip];
72 const auto dr = fllc.dr[ip];
73 const auto vmag =
74 std::max(vs::mag(vel), vs::DTraits<amrex::Real>::eps());
75 const auto vmag2 = vmag * vmag;
76
77 const auto fv = force & vel;
78
79 G[ip] = (force - vel * fv / vmag2) / dr;
80 }
81
87 dG[0] = G[0];
88 dG[npts - 1] = -1 * G[npts - 1];
89 for (int ip = 1; ip < npts - 1; ++ip) {
90 dG[ip] = 0.5 * (G[ip + 1] - G[ip - 1]);
91 }
92
98 for (int ip = 0; ip < npts; ++ip) {
99
100 const auto eps_les = fllc.epsilon;
101 const auto eps_opt = fllc.optimal_epsilon[ip];
102
103 for (int jp = 0; jp < npts; ++jp) {
104
105 if (ip == jp) {
106 continue;
107 }
108
109 const auto r_dis = vs::mag(data.vel_pos[ip] - data.vel_pos[jp]);
110 const auto& vel = data.vel_rel[jp];
111 const auto vmag =
112 std::max(vs::mag(vel), vs::DTraits<amrex::Real>::eps());
113
114 auto coefficient =
115 1.0 / (-4.0 * amr_wind::utils::pi() * r_dis * vmag);
116 const auto cLes =
117 1.0 - std::exp(-r_dis * r_dis / (eps_les * eps_les));
118 const auto cOpt =
119 1.0 - std::exp(-r_dis * r_dis / (eps_opt * eps_opt));
120
121 // The sign of the induced velocity depends on which side of the
122 // blade we are on
123 if (ip < jp) {
124 coefficient *= -1;
125 }
126
127 u_les[ip] = u_les[ip] - dG[jp] * coefficient * cLes;
128 u_opt[ip] = u_opt[ip] - dG[jp] * coefficient * cOpt;
129 }
130
131 // Relaxation to compute the induced velocity
132 const auto f = fllc.relaxation_factor;
133 du[ip] = (1. - f) * du[ip] + f * (u_opt[ip] - u_les[ip]);
134 }
135
141 for (int ip = 0; ip < npts; ++ip) {
142 vel_ptr[ip] = vel_ptr[ip] + du[ip];
143 u_les[ip] *= 0.0;
144 u_opt[ip] *= 0.0;
145 }
146
151 if (fllc.different_sizes) {
153 fllc.span_distance_force, u_force_pnt_slice,
154 fllc.span_distance_vel, data.vel);
155 }
156 }
157
158 static void variable_chord(ComponentView& data, FLLCData& fllc)
159 {
160 namespace interp = ::amr_wind::interp;
161
162 const int npts = static_cast<int>(fllc.correction_velocity.size());
163 auto& du = fllc.correction_velocity;
164
165 auto& nonuniform_r = fllc.nonuniform_r;
166 auto& u_les = fllc.les_velocity;
167 auto& u_opt = fllc.optimal_velocity;
168 auto& G = fllc.lift;
169 auto& nonuniform_G = fllc.nonuniform_lift;
170 VecSlice u_force_pnt_slice =
172 vs::Vector* vel_ptr = data.vel.data();
173
178 if (fllc.different_sizes) {
181 u_force_pnt_slice);
182 vel_ptr = u_force_pnt_slice.data();
183 }
184
189 for (int ip = 0; ip < npts; ++ip) {
190 const auto force = data.force[ip];
191 const auto vel = data.vel_rel[ip];
192 const auto dr = fllc.dr[ip];
193 const auto vmag =
194 std::max(vs::mag(vel), vs::DTraits<amrex::Real>::eps());
195 const auto vmag2 = vmag * vmag;
196 fllc.vel_rel[ip] = vel;
197 const auto fv = force & vel;
198
199 G[ip] = (force - vel * fv / vmag2) / dr;
200 }
201
202 // Get the non-uniform distribution of force
203 if (fllc.nonuniform) {
204 interp::linear(fllc.r, G, nonuniform_r, nonuniform_G);
206 fllc.r, fllc.optimal_epsilon, nonuniform_r,
209 fllc.r, fllc.vel_rel, nonuniform_r, fllc.nonuniform_vel_rel);
210 }
211
212 const auto optimal_epsilon = (fllc.nonuniform)
214 : fllc.optimal_epsilon;
215 const auto dr = (fllc.nonuniform) ? fllc.nonuniform_dr : fllc.dr;
216 const auto vel_rel =
217 (fllc.nonuniform) ? fllc.nonuniform_vel_rel : fllc.vel_rel;
218 const auto G_new = (fllc.nonuniform) ? nonuniform_G : G;
219
224 for (int ip = 0; ip < npts; ++ip) {
225
226 const auto coefficient = 1.0 / (2.0 * amr_wind::utils::pi());
227
228 for (int jp = 0; jp < dr.size(); ++jp) {
229
230 const auto eps_les = fllc.epsilon;
231 const auto eps_opt = optimal_epsilon[jp];
232 const auto eps_les2 = eps_les * eps_les;
233 const auto eps_opt2 = eps_opt * eps_opt;
234 const auto& vel = vel_rel[jp];
235 const auto vmag =
236 std::max(vs::mag(vel), vs::DTraits<amrex::Real>::eps());
237 auto k_les = 0.;
238 auto k_opt = 0.;
239
240 const auto r_dis =
241 (fllc.nonuniform)
242 ? std::abs(fllc.r[ip] - fllc.nonuniform_r[jp])
243 : vs::mag(data.vel_pos[ip] - data.vel_pos[jp]);
244
245 if (r_dis == 0.) {
246
247 k_les = .5 / (eps_les2);
248 k_opt = .5 / (eps_opt2);
249
250 }
251
252 else {
253
254 auto exp_les = std::exp(-r_dis * r_dis / eps_les2);
255 auto exp_opt = std::exp(-r_dis * r_dis / eps_opt2);
256
257 k_les = exp_les / eps_les2 +
258 1. / (2. * r_dis * r_dis) * (exp_les - 1.);
259 k_opt = exp_opt / eps_opt2 +
260 1. / (2. * r_dis * r_dis) * (exp_opt - 1.);
261 }
262
263 u_les[ip] =
264 u_les[ip] + coefficient * G_new[jp] / vmag * k_les * dr[jp];
265 u_opt[ip] =
266 u_opt[ip] + coefficient * G_new[jp] / vmag * k_opt * dr[jp];
267 }
268
269 // Relaxation to compute the induced velocity
270 const auto f = fllc.relaxation_factor;
271 du[ip] = (1. - f) * du[ip] + f * (u_opt[ip] - u_les[ip]);
272 }
273
278 for (int ip = 0; ip < npts; ++ip) {
279 vel_ptr[ip] = vel_ptr[ip] + du[ip];
280 u_les[ip] *= 0.0;
281 u_opt[ip] *= 0.0;
282 }
283
288 if (fllc.different_sizes) {
290 fllc.span_distance_force, u_force_pnt_slice,
291 fllc.span_distance_vel, data.vel);
292 }
293 }
294};
295
296} // namespace amr_wind::actuator
297
298#endif /* FLLCOP_H */
Definition ActParser.H:6
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:126
Slice< T > slice(std::vector< T > &vec, const size_t start, const size_t count)
Definition Slice.H:66
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr amrex::Real pi()
Return as an amrex::Real.
Definition trig_ops.H:16
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T mag(const TensorT< T > &t)
Definition tensorI.H:182
Definition actuator_types.H:126
VecSlice vel
Definition actuator_types.H:133
VecSlice vel_rel
Definition actuator_types.H:134
VecSlice force
Definition actuator_types.H:128
VecSlice vel_pos
Definition actuator_types.H:132
Definition FLLC.H:16
RealList span_distance_force
Definition FLLC.H:36
amrex::Real epsilon
Definition FLLC.H:19
RealList nonuniform_r
Definition FLLC.H:41
VecList vel_rel
Definition FLLC.H:43
bool initialized
Definition FLLC.H:33
amrex::Real relaxation_factor
Definition FLLC.H:20
RealList dr
Definition FLLC.H:23
RealList nonuniform_optimal_epsilon
Definition FLLC.H:45
RealList optimal_epsilon
Definition FLLC.H:24
VecList optimal_velocity
Definition FLLC.H:29
bool different_sizes
Definition FLLC.H:34
RealList nonuniform_dr
Definition FLLC.H:42
VecList correction_velocity
Definition FLLC.H:30
bool nonuniform
Definition FLLC.H:39
VecList nonuniform_vel_rel
Definition FLLC.H:44
VecList force_point_velocity
Definition FLLC.H:27
FLLCType correction_type
Definition FLLC.H:18
VecList les_velocity
Definition FLLC.H:28
VecList nonuniform_lift
Definition FLLC.H:46
VecList grad_lift
Definition FLLC.H:32
RealList span_distance_vel
Definition FLLC.H:35
RealList r
Definition FLLC.H:22
VecList lift
Definition FLLC.H:31
This struct will operate on a blade/wing. The velocity from the simulation is corrected using the Fil...
Definition FLLCOp.H:17
static void variable_chord(ComponentView &data, FLLCData &fllc)
Definition FLLCOp.H:158
void operator()(ComponentView &data, FLLCData &fllc)
Definition FLLCOp.H:18
static void constant_chord(ComponentView &data, FLLCData &fllc)
Definition FLLCOp.H:38
AMREX_GPU_HOST_DEVICE pointer data()
Definition Slice.H:54
Definition vstraits.H:11
Definition vector.H:13