/home/runner/work/amr-wind/amr-wind/amr-wind/wind_energy/actuator/turbine/kynema/kynema_types.H Source File

AMR-Wind API: /home/runner/work/amr-wind/amr-wind/amr-wind/wind_energy/actuator/turbine/kynema/kynema_types.H Source File
AMR-Wind API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
kynema_types.H
Go to the documentation of this file.
1#ifndef KYNEMA_TYPES_H
2#define KYNEMA_TYPES_H
3
6
7#include <string>
8
9namespace ext_turb {
10
14{
17 std::unique_ptr<kynema::interfaces::TurbineInterface> interface;
18
19 // Need buffers to make data contiguous to fit into coupling
47
49 {
50 // Get hub information for nacelle force
51 // Chord is not used, set it to zero
52 buffer_cf[0] = 0.;
53 // Force is calculated by AMR-Wind, passed to Kynema
54 // Get position directly from node information
55 buffer_pf[0] = interface->Turbine().hub_node.position[0];
56 buffer_pf[length_force(0)] = interface->Turbine().hub_node.position[1];
57 buffer_pf[2 * length_force(0)] =
58 interface->Turbine().hub_node.position[2];
59 buffer_pv[0] = buffer_pf[0];
62 // Get solid velocity as well, not used at the moment though
63 buffer_sv[0] = interface->Turbine().hub_node.velocity[0];
64 buffer_sv[length_force(0)] = interface->Turbine().hub_node.velocity[1];
65 buffer_sv[2 * length_force(0)] =
66 interface->Turbine().hub_node.velocity[2];
67
68 // Get blade information
69 int idx = 0;
70 for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
71 // Skip hub node
72 ++idx;
73 // Fluid velocity (fv) is not populated here, it comes from the
74 // CFD solver. Need to add step to pass it from buffer to Kynema
75 for (int n = 1; n < length_force(0); ++n) {
76 if (dir == 0) {
77 buffer_cf[n] = (float)interface->Aerodynamics()
78 .bodies[body_index(n)]
79 .chord[node_index(n)];
80 }
81 buffer_f[idx] = (float)interface->Aerodynamics()
82 .bodies[body_index(n)]
83 .loads[node_index(n)][dir];
84 buffer_pf[idx] = (float)interface->Aerodynamics()
85 .bodies[body_index(n)]
86 .x_motion[node_index(n)][dir];
87 buffer_pv[idx] = buffer_pf[idx];
88 buffer_sv[idx] = (float)interface->Aerodynamics()
89 .bodies[body_index(n)]
90 .v_motion[node_index(n)][dir];
91 ++idx;
92 }
93 }
94 // Orientation stores a 3x3 tensor (9 elements) for every point
95 std::array<float, 4> q;
96 for (int n = 0; n < length_force(0); ++n) {
97 // convert quaternions to rotation matrix
98 for (int iq = 0; iq < 4; ++iq) {
99 if (n == 0) {
100 q[iq] =
101 (float)interface->Turbine().hub_node.position[iq + 3];
102 } else {
103 q[iq] = (float)interface->Aerodynamics()
104 .bodies[body_index(n)]
105 .qqr_motion_map[node_index(n)][iq];
106 }
107 }
108 const int idx = n * 9;
109 buffer_ori[idx + 0] =
110 q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3];
111 buffer_ori[idx + 1] = 2. * (q[1] * q[2] - q[0] * q[3]);
112 buffer_ori[idx + 2] = 2. * (q[1] * q[3] + q[0] * q[2]);
113 buffer_ori[idx + 3] = 2. * (q[1] * q[2] + q[0] * q[3]);
114 buffer_ori[idx + 4] =
115 (q[0] * q[0] - q[1] * q[1] + q[2] * q[2] - q[3] * q[3]);
116 buffer_ori[idx + 5] = 2. * (q[2] * q[3] - q[0] * q[1]);
117 buffer_ori[idx + 6] = 2. * (q[1] * q[3] - q[0] * q[2]);
118 buffer_ori[idx + 7] = 2. * (q[2] * q[3] + q[0] * q[1]);
119 buffer_ori[idx + 8] =
120 (q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);
121 }
122 }
123
125 {
126 // Fluid velocity at hub does not need to be passed, loads computed
127 // internally in AMR-Wind
128 int idx = 0;
129 for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
130 // Skip hub node
131 ++idx;
132 for (int n = 1; n < length_fluid_velocity(0); ++n) {
133 interface->Aerodynamics()
134 .bodies[body_index(n)]
135 .v_inflow[node_index(n)][dir] = buffer_fv[idx];
136 ++idx;
137 }
138 }
139 // Hub load (also called nacelle_force) does need to be passed
140 interface->Turbine().hub_node.loads[0] = buffer_f[0];
141 interface->Turbine().hub_node.loads[1] = buffer_f[length_force(0)];
142 interface->Turbine().hub_node.loads[2] =
144 // Fluid velocity at hub is passed separately for the sake of controller
145 std::array<double, 3> hub_inflow{
148 interface->SetHubInflow(hub_inflow);
149 }
150
152 int body_index(int id) const
153 {
154 // Considering hub, which is 1 node, subtract
155 id -= 1;
156 int b_id = 0;
157 int id_diff = id;
158 for (int b = 0; b < (int)interface->Aerodynamics().bodies.size(); ++b) {
159 id_diff -= static_cast<int>(
160 interface->Aerodynamics().bodies[b].loads.size());
161 if (id_diff < 0) {
162 b_id = b;
163 break;
164 }
165 }
166 return b_id;
167 }
168
169 int node_index(int id) const
170 {
171 // Considering hub, which is 1 node, subtract
172 id -= 1;
173 int n_id = 0;
174 int id_diff = id;
175 for (int b = 0; b < (int)interface->Aerodynamics().bodies.size(); ++b) {
176 id_diff -= (int)interface->Aerodynamics().bodies[b].loads.size();
177 if (id_diff < 0) {
178 n_id = id_diff +
179 (int)interface->Aerodynamics().bodies[b].loads.size();
180 break;
181 }
182 }
183 return n_id;
184 }
185
187
188 float* position_at_vel(int dir) const override
189 {
190 return ptr_pv + dir * length_fluid_velocity(0);
191 }
192
193 float* solid_velocity(int dir) const override
194 {
195 return ptr_sv + dir * length_fluid_velocity(0);
196 }
197
198 float* fluid_velocity(int dir) const override
199 {
200 return ptr_fv + dir * length_fluid_velocity(0);
201 }
202
203 float* force(int dir) const override
204 {
205 return ptr_f + dir * length_force(0);
206 }
207
208 float* position_at_force(int dir) const override
209 {
210 return ptr_pf + dir * length_position_at_force(0);
211 }
212
213 float* chord_at_force() const override { return ptr_cf; }
214
215 float* orientation() const override { return ptr_ori; }
216
217 int length_fluid_velocity(int dir) const override
218 {
219 return length_force(dir);
220 }
221
222 int length_force(int dir) const override
223 {
224 unsigned int n_sect{1};
225 for (unsigned int n = 0; n < interface->Aerodynamics().bodies.size();
226 ++n) {
227 n_sect += interface->Aerodynamics().bodies[n].loads.size();
228 }
229 return static_cast<int>(n_sect);
230 }
231
232 int length_position_at_force(int dir) const override
233 {
234 return length_force(dir);
235 }
236
237 int length_orientation() const override
238 {
239 return length_force(0) * AMREX_SPACEDIM * AMREX_SPACEDIM;
240 }
241
242 int num_vel_pts_blade() const override { return num_pts_blade; }
243
244 double fluid_density{1.};
246 double yaw{0.};
248
250 std::string controller_input_file{""};
251
252 std::vector<float> buffer_cf;
253 std::vector<float> buffer_pv;
254 std::vector<float> buffer_sv;
255 std::vector<float> buffer_fv;
256 std::vector<float> buffer_f;
257 std::vector<float> buffer_pf;
258 std::vector<float> buffer_ori;
259 float* ptr_cf{nullptr};
260 float* ptr_pv{nullptr};
261 float* ptr_sv{nullptr};
262 float* ptr_fv{nullptr};
263 float* ptr_f{nullptr};
264 float* ptr_pf{nullptr};
265 float* ptr_ori{nullptr};
266};
267
269{
270 std::string output_dir{"kynema_velocity_data"};
271
272 double damping_factor{0.};
273 int nl_iter_max{12};
274 double abs_err_tol{1e-7};
275 double rel_err_tol{1e-6};
276 amrex::Vector<amrex::Real> gravity{0.0, 0.0, -9.81};
277};
278
279} // namespace ext_turb
280
281#endif /* KYNEMA_TYPES_H */
Definition external_base_types.H:6
Definition external_base_types.H:20
int num_pts_blade
Number of actuator points per blade.
Definition external_base_types.H:33
Definition kynema_types.H:269
double damping_factor
Definition kynema_types.H:272
double rel_err_tol
Definition kynema_types.H:275
amrex::Vector< amrex::Real > gravity
Definition kynema_types.H:276
double abs_err_tol
Definition kynema_types.H:274
int nl_iter_max
Definition kynema_types.H:273
std::string output_dir
Definition kynema_types.H:270
Definition kynema_types.H:14
float * position_at_vel(int dir) const override
Definition kynema_types.H:188
std::vector< float > buffer_ori
Definition kynema_types.H:258
float * ptr_pf
Definition kynema_types.H:264
float * orientation() const override
Definition kynema_types.H:215
std::vector< float > buffer_fv
Definition kynema_types.H:255
float * ptr_sv
Definition kynema_types.H:261
double rotational_speed
Definition kynema_types.H:245
float * ptr_fv
Definition kynema_types.H:262
int node_index(int id) const
Definition kynema_types.H:169
int length_fluid_velocity(int dir) const override
Definition kynema_types.H:217
double yaw
Definition kynema_types.H:246
std::vector< float > buffer_f
Definition kynema_types.H:256
float * position_at_force(int dir) const override
Definition kynema_types.H:208
float * solid_velocity(int dir) const override
Definition kynema_types.H:193
std::vector< float > buffer_cf
Definition kynema_types.H:252
double fluid_density
Definition kynema_types.H:244
std::string controller_input_file
Definition kynema_types.H:250
float * ptr_pv
Definition kynema_types.H:260
float * chord_at_force() const override
Definition kynema_types.H:213
std::string controller_shared_lib_path
Definition kynema_types.H:249
int body_index(int id) const
Definition kynema_types.H:152
float * ptr_f
Definition kynema_types.H:263
void pass_fluid_velocity_and_hub_load()
Definition kynema_types.H:124
void allocate_buffers()
Definition kynema_types.H:20
int substep_counter
Definition kynema_types.H:247
float * ptr_cf
Definition kynema_types.H:259
int length_force(int dir) const override
Definition kynema_types.H:222
std::unique_ptr< kynema::interfaces::TurbineInterface > interface
Definition kynema_types.H:17
int num_vel_pts_blade() const override
Definition kynema_types.H:242
void populate_buffers()
Definition kynema_types.H:48
int length_orientation() const override
Definition kynema_types.H:237
std::vector< float > buffer_pf
Definition kynema_types.H:257
int length_position_at_force(int dir) const override
Definition kynema_types.H:232
float * ptr_ori
Definition kynema_types.H:265
float * force(int dir) const override
Definition kynema_types.H:203
std::vector< float > buffer_pv
Definition kynema_types.H:253
float * fluid_velocity(int dir) const override
Definition kynema_types.H:198
std::vector< float > buffer_sv
Definition kynema_types.H:254