/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#include "AMReX_REAL.H"
8
9using namespace amrex::literals;
10
11namespace amr_wind::actuator {
12
18
19struct FLLCOp
20{
22 {
23 if (!fllc.initialized) {
24 return;
25 }
26 switch (fllc.correction_type) {
28 constant_chord(data, fllc);
29 break;
30 }
32 variable_chord(data, fllc);
33 break;
34 }
35 default:
36 // this should be unreachable
37 throw std::runtime_error("Invalid FLLC type");
38 }
39 }
40
41 static void constant_chord(ComponentView& data, FLLCData& fllc)
42 {
43 namespace interp = ::amr_wind::interp;
44
45 const int npts = static_cast<int>(fllc.correction_velocity.size());
46 auto& du = fllc.correction_velocity;
47
48 auto& u_les = fllc.les_velocity;
49 auto& u_opt = fllc.optimal_velocity;
50 auto& G = fllc.lift;
51 auto& dG = fllc.grad_lift;
52 VecSlice u_force_pnt_slice =
54 vs::Vector* vel_ptr = data.vel.data();
55
60 if (fllc.different_sizes) {
63 u_force_pnt_slice);
64 vel_ptr = u_force_pnt_slice.data();
65 }
66
72 for (int ip = 0; ip < npts; ++ip) {
73 const auto force = data.force[ip];
74 const auto vel = data.vel_rel[ip];
75 const auto dr = fllc.dr[ip];
76 const auto vmag = amrex::max<amrex::Real>(
78 const auto vmag2 = vmag * vmag;
79
80 const auto fv = force & vel;
81
82 G[ip] = (force - vel * fv / vmag2) / dr;
83 }
84
91 dG[0] = G[0];
92 dG[npts - 1] = -1 * G[npts - 1];
93 for (int ip = 1; ip < npts - 1; ++ip) {
94 dG[ip] = 0.5_rt * (G[ip + 1] - G[ip - 1]);
95 }
96
103 for (int ip = 0; ip < npts; ++ip) {
104
105 const auto eps_les = fllc.epsilon;
106 const auto eps_opt = fllc.optimal_epsilon[ip];
107
108 for (int jp = 0; jp < npts; ++jp) {
109
110 if (ip == jp) {
111 continue;
112 }
113
114 const auto r_dis = vs::mag(data.vel_pos[ip] - data.vel_pos[jp]);
115 const auto& vel = data.vel_rel[jp];
116 const auto vmag = amrex::max<amrex::Real>(
118
119 auto coefficient =
120 1.0_rt / (-4.0_rt * amr_wind::utils::pi() * r_dis * vmag);
121 const auto cLes =
122 1.0_rt - std::exp(-r_dis * r_dis / (eps_les * eps_les));
123 const auto cOpt =
124 1.0_rt - std::exp(-r_dis * r_dis / (eps_opt * eps_opt));
125
126 // The sign of the induced velocity depends on which side of the
127 // blade we are on
128 if (ip < jp) {
129 coefficient *= -1;
130 }
131
132 u_les[ip] = u_les[ip] - dG[jp] * coefficient * cLes;
133 u_opt[ip] = u_opt[ip] - dG[jp] * coefficient * cOpt;
134 }
135
136 // Relaxation to compute the induced velocity
137 const auto f = fllc.relaxation_factor;
138 du[ip] = (1.0_rt - f) * du[ip] + f * (u_opt[ip] - u_les[ip]);
139 }
140
146 for (int ip = 0; ip < npts; ++ip) {
147 vel_ptr[ip] = vel_ptr[ip] + du[ip];
148 u_les[ip] *= 0.0_rt;
149 u_opt[ip] *= 0.0_rt;
150 }
151
156 if (fllc.different_sizes) {
158 fllc.span_distance_force, u_force_pnt_slice,
159 fllc.span_distance_vel, data.vel);
160 }
161 }
162
163 static void variable_chord(ComponentView& data, FLLCData& fllc)
164 {
165 namespace interp = ::amr_wind::interp;
166
167 const int npts = static_cast<int>(fllc.correction_velocity.size());
168 auto& du = fllc.correction_velocity;
169
170 auto& nonuniform_r = fllc.nonuniform_r;
171 auto& u_les = fllc.les_velocity;
172 auto& u_opt = fllc.optimal_velocity;
173 auto& G = fllc.lift;
174 auto& nonuniform_G = fllc.nonuniform_lift;
175 VecSlice u_force_pnt_slice =
177 vs::Vector* vel_ptr = data.vel.data();
178
183 if (fllc.different_sizes) {
186 u_force_pnt_slice);
187 vel_ptr = u_force_pnt_slice.data();
188 }
189
194 for (int ip = 0; ip < npts; ++ip) {
195 const auto force = data.force[ip];
196 const auto vel = data.vel_rel[ip];
197 const auto dr = fllc.dr[ip];
198 const auto vmag = amrex::max<amrex::Real>(
200 const auto vmag2 = vmag * vmag;
201 fllc.vel_rel[ip] = vel;
202 const auto fv = force & vel;
203
204 G[ip] = (force - vel * fv / vmag2) / dr;
205 }
206
207 // Get the non-uniform distribution of force
208 if (fllc.nonuniform) {
209 interp::linear(fllc.r, G, nonuniform_r, nonuniform_G);
211 fllc.r, fllc.optimal_epsilon, nonuniform_r,
214 fllc.r, fllc.vel_rel, nonuniform_r, fllc.nonuniform_vel_rel);
215 }
216
217 const auto optimal_epsilon = (fllc.nonuniform)
219 : fllc.optimal_epsilon;
220 const auto dr = (fllc.nonuniform) ? fllc.nonuniform_dr : fllc.dr;
221 const auto vel_rel =
222 (fllc.nonuniform) ? fllc.nonuniform_vel_rel : fllc.vel_rel;
223 const auto G_new = (fllc.nonuniform) ? nonuniform_G : G;
224
229 for (int ip = 0; ip < npts; ++ip) {
230
231 const auto coefficient = 1.0_rt / (2.0_rt * amr_wind::utils::pi());
232
233 for (int jp = 0; jp < dr.size(); ++jp) {
234
235 const auto eps_les = fllc.epsilon;
236 const auto eps_opt = optimal_epsilon[jp];
237 const auto eps_les2 = eps_les * eps_les;
238 const auto eps_opt2 = eps_opt * eps_opt;
239 const auto& vel = vel_rel[jp];
240 const auto vmag = amrex::max<amrex::Real>(
242 auto k_les = 0.0_rt;
243 auto k_opt = 0.0_rt;
244
245 const auto r_dis =
246 (fllc.nonuniform)
247 ? std::abs(fllc.r[ip] - fllc.nonuniform_r[jp])
248 : vs::mag(data.vel_pos[ip] - data.vel_pos[jp]);
249
250 if (r_dis == 0.) {
251
252 k_les = 0.5_rt / (eps_les2);
253 k_opt = 0.5_rt / (eps_opt2);
254
255 }
256
257 else {
258
259 auto exp_les = std::exp(-r_dis * r_dis / eps_les2);
260 auto exp_opt = std::exp(-r_dis * r_dis / eps_opt2);
261
262 k_les = exp_les / eps_les2 + 1.0_rt /
263 (2.0_rt * r_dis * r_dis) *
264 (exp_les - 1.0_rt);
265 k_opt = exp_opt / eps_opt2 + 1.0_rt /
266 (2.0_rt * r_dis * r_dis) *
267 (exp_opt - 1.0_rt);
268 }
269
270 u_les[ip] =
271 u_les[ip] + coefficient * G_new[jp] / vmag * k_les * dr[jp];
272 u_opt[ip] =
273 u_opt[ip] + coefficient * G_new[jp] / vmag * k_opt * dr[jp];
274 }
275
276 // Relaxation to compute the induced velocity
277 const auto f = fllc.relaxation_factor;
278 du[ip] = (1.0_rt - f) * du[ip] + f * (u_opt[ip] - u_les[ip]);
279 }
280
285 for (int ip = 0; ip < npts; ++ip) {
286 vel_ptr[ip] = vel_ptr[ip] + du[ip];
287 u_les[ip] *= 0.0_rt;
288 u_opt[ip] *= 0.0_rt;
289 }
290
295 if (fllc.different_sizes) {
297 fllc.span_distance_force, u_force_pnt_slice,
298 fllc.span_distance_vel, data.vel);
299 }
300 }
301};
302
303} // namespace amr_wind::actuator
304
305#endif /* FLLCOP_H */
Definition ActParser.H:6
::amr_wind::utils::Slice< amr_wind::vs::Vector > VecSlice
Definition actuator_types.H:66
@ ConstantChord
Definition FLLC.H:12
@ VariableChord
Definition FLLC.H:12
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:129
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:18
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T mag(const TensorT< T > &t)
Definition tensorI.H:182
VectorT< amrex::Real > Vector
Definition vector.H:148
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:19
RealList span_distance_force
Definition FLLC.H:39
amrex::Real epsilon
Definition FLLC.H:22
RealList nonuniform_r
Definition FLLC.H:44
VecList vel_rel
Definition FLLC.H:46
bool initialized
Definition FLLC.H:36
amrex::Real relaxation_factor
Definition FLLC.H:23
RealList dr
Definition FLLC.H:26
RealList nonuniform_optimal_epsilon
Definition FLLC.H:48
RealList optimal_epsilon
Definition FLLC.H:27
VecList optimal_velocity
Definition FLLC.H:32
bool different_sizes
Definition FLLC.H:37
RealList nonuniform_dr
Definition FLLC.H:45
VecList correction_velocity
Definition FLLC.H:33
bool nonuniform
Definition FLLC.H:42
VecList nonuniform_vel_rel
Definition FLLC.H:47
VecList force_point_velocity
Definition FLLC.H:30
FLLCType correction_type
Definition FLLC.H:21
VecList les_velocity
Definition FLLC.H:31
VecList nonuniform_lift
Definition FLLC.H:49
VecList grad_lift
Definition FLLC.H:35
RealList span_distance_vel
Definition FLLC.H:38
RealList r
Definition FLLC.H:25
VecList lift
Definition FLLC.H:34
This struct will operate on a blade/wing. The velocity from the simulation is corrected using the Fil...
Definition FLLCOp.H:20
static void variable_chord(ComponentView &data, FLLCData &fllc)
Definition FLLCOp.H:163
void operator()(ComponentView &data, FLLCData &fllc)
Definition FLLCOp.H:21
static void constant_chord(ComponentView &data, FLLCData &fllc)
Definition FLLCOp.H:41
AMREX_GPU_HOST_DEVICE pointer data()
Definition Slice.H:54
Definition vstraits.H:10