/home/runner/work/kynema/kynema/kynema/src/model/node.hpp Source File

Kynema API: /home/runner/work/kynema/kynema/kynema/src/model/node.hpp Source File
Kynema API
A flexible multibody structural dynamics code for wind turbines
Loading...
Searching...
No Matches
node.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace kynema {
6
26struct Node {
27 size_t id; //< Node identifier
28 std::array<double, 7> x0; //< Initial node positions and orientations
29 std::array<double, 7> u; //< Node displacement
30 std::array<double, 6> v; //< Node velocity
31 std::array<double, 6> vd; //< Node acceleration
32 double s; //< Position of node in element on range [0, 1]
33
35 explicit Node(size_t node_id)
36 : id(node_id),
37 x0(std::array<double, 7>{0., 0., 0., 1., 0., 0., 0.}),
38 u(std::array<double, 7>{0., 0., 0., 1., 0., 0., 0.}),
39 v(std::array<double, 6>{0., 0., 0., 0., 0., 0.}),
40 vd(std::array<double, 6>{0., 0., 0., 0., 0., 0.}),
41 s(0.) {}
42
46 size_t node_id, std::array<double, 7> position,
47 std::array<double, 7> displacement = std::array<double, 7>{0., 0., 0., 1., 0., 0., 0.},
48 std::array<double, 6> velocity = std::array<double, 6>{0., 0., 0., 0., 0., 0.},
49 std::array<double, 6> acceleration = std::array<double, 6>{0., 0., 0., 0., 0., 0.}
50 )
51 : id(node_id), x0(position), u(displacement), v(velocity), vd(acceleration), s(0.) {}
52
53 //--------------------------------------------------------------------------
54 // Compute displaced/current position
55 //--------------------------------------------------------------------------
56
57 /*
58 * @brief Get the displaced position (initial position + displacement)
59 * @return std::array<double, 7> containing displaced position and orientation
60 */
61 [[nodiscard]] std::array<double, 7> DisplacedPosition() const {
62 auto displaced_position = std::array{0., 0., 0., 1., 0., 0., 0.};
63
64 // Add translational components (x, y, z)
65 displaced_position[0] = this->x0[0] + this->u[0];
66 displaced_position[1] = this->x0[1] + this->u[1];
67 displaced_position[2] = this->x0[2] + this->u[2];
68
69 // Compose quaternions for orientation (w, i, j, k)
70 auto q_displaced = math::QuaternionCompose(
71 {this->x0[3], this->x0[4], this->x0[5], this->x0[6]}, // initial orientation
72 {this->u[3], this->u[4], this->u[5], this->u[6]} // displacement orientation
73 );
74 displaced_position[3] = q_displaced[0];
75 displaced_position[4] = q_displaced[1];
76 displaced_position[5] = q_displaced[2];
77 displaced_position[6] = q_displaced[3];
78
79 return displaced_position;
80 }
81
82 //--------------------------------------------------------------------------
83 // Modify node position (x)
84 //--------------------------------------------------------------------------
85
87 Node& Translate(const std::array<double, 3>& displacement) {
88 //----------------------------------------------------
89 // Position, x(0:2)
90 //----------------------------------------------------
91 this->x0[0] += displacement[0];
92 this->x0[1] += displacement[1];
93 this->x0[2] += displacement[2];
94
95 // No change to orientation
96 return *this;
97 }
98
100 Node& RotateAboutPoint(const std::array<double, 4>& q, const std::array<double, 3>& point) {
101 //----------------------------------------------------
102 // Position, x(0:2)
103 //----------------------------------------------------
104 // Get vector from reference point to initial node position
105 const auto r =
106 std::array{this->x0[0] - point[0], this->x0[1] - point[1], this->x0[2] - point[2]};
107
108 // Rotate the vector r using the provided quaternion q
109 const auto rotated_r = math::RotateVectorByQuaternion(q, r);
110
111 // Update the position by adding the rotated vector to the reference point
112 this->x0[0] = rotated_r[0] + point[0];
113 this->x0[1] = rotated_r[1] + point[1];
114 this->x0[2] = rotated_r[2] + point[2];
115
116 //----------------------------------------------------
117 // Orientation, x(3:6)
118 //----------------------------------------------------
119 // Compose q with initial orientation to get rotated orientation
120 auto q_new =
121 math::QuaternionCompose(q, {this->x0[3], this->x0[4], this->x0[5], this->x0[6]});
122
123 // Update the orientation
124 this->x0[3] = q_new[0];
125 this->x0[4] = q_new[1];
126 this->x0[5] = q_new[2];
127 this->x0[6] = q_new[3];
128
129 return *this;
130 }
131
133 Node& RotateAboutPoint(const std::array<double, 3>& rv, const std::array<double, 3>& point) {
134 const auto q = math::RotationVectorToQuaternion(rv);
135 this->RotateAboutPoint(q, point);
136 return *this;
137 }
138
139 //--------------------------------------------------------------------------
140 // Modify node displacement (u)
141 //--------------------------------------------------------------------------
142
144 Node& TranslateDisplacement(const std::array<double, 3>& displacement) {
145 this->u[0] += displacement[0];
146 this->u[1] += displacement[1];
147 this->u[2] += displacement[2];
148 return *this;
149 }
150
153 const std::array<double, 4>& q, const std::array<double, 3>& point
154 ) {
155 //----------------------------------------------------
156 // Displacement position, u(0:2)
157 //----------------------------------------------------
158 // Get vector from reference point to displaced node position
159 const auto displaced_position = this->DisplacedPosition();
160 const std::array<double, 3> r{
161 displaced_position[0] - point[0], displaced_position[1] - point[1],
162 displaced_position[2] - point[2]
163 };
164
165 // Rotate the vector r using the provided quaternion q
166 const auto rotated_r = math::RotateVectorByQuaternion(q, r);
167
168 // Update the displacement position by adding the rotated vector to the reference point
169 // and subtracting the initial position
170 this->u[0] = rotated_r[0] + point[0] - this->x0[0];
171 this->u[1] = rotated_r[1] + point[1] - this->x0[1];
172 this->u[2] = rotated_r[2] + point[2] - this->x0[2];
173
174 //----------------------------------------------------
175 // Displacement orientation, u(3:6)
176 //----------------------------------------------------
177 // Compose q with initial displacement orientation to get rotated displacement orientation
178 auto q_new = math::QuaternionCompose(q, {this->u[3], this->u[4], this->u[5], this->u[6]});
179
180 // Update the displacement orientation
181 this->u[3] = q_new[0];
182 this->u[4] = q_new[1];
183 this->u[5] = q_new[2];
184 this->u[6] = q_new[3];
185
186 return *this;
187 }
188
191 const std::array<double, 3>& rv, const std::array<double, 3>& point
192 ) {
193 const auto q = math::RotationVectorToQuaternion(rv);
194 this->RotateDisplacementAboutPoint(q, point);
195 return *this;
196 }
197
198 //--------------------------------------------------------------------------
199 // Modify node velocity (v)
200 //--------------------------------------------------------------------------
201
204 const std::array<double, 6>& velocity, const std::array<double, 3>& point
205 ) {
206 // Get vector from reference point to displaced node position
207 const auto displaced_position = this->DisplacedPosition();
208 const auto r = std::array{
209 displaced_position[0] - point[0], displaced_position[1] - point[1],
210 displaced_position[2] - point[2]
211 };
212
213 // Calculate velocity contribution from angular velocity
214 const auto omega = std::array{velocity[3], velocity[4], velocity[5]};
215 const auto omega_cross_r = math::CrossProduct(omega, r);
216
217 // Set node translational velocity
218 this->v[0] = velocity[0] + omega_cross_r[0];
219 this->v[1] = velocity[1] + omega_cross_r[1];
220 this->v[2] = velocity[2] + omega_cross_r[2];
221
222 // Set node angular velocity
223 this->v[3] = velocity[3];
224 this->v[4] = velocity[4];
225 this->v[5] = velocity[5];
226 }
227
228 //--------------------------------------------------------------------------
229 // Modify node acceleration (vd)
230 //--------------------------------------------------------------------------
231
234 const std::array<double, 6>& acceleration, const std::array<double, 3>& omega,
235 const std::array<double, 3>& point
236 ) {
237 // Get vector from reference point to displaced node position
238 const auto displaced_position = this->DisplacedPosition();
239 const auto r = std::array{
240 displaced_position[0] - point[0], displaced_position[1] - point[1],
241 displaced_position[2] - point[2]
242 };
243
244 // Calculate translational acceleration contribution from angular velocity
245 const auto alpha = std::array{acceleration[3], acceleration[4], acceleration[5]};
246 const auto alpha_cross_r = math::CrossProduct(alpha, r);
247 const auto omega_cross_omega_cross_r =
248 math::CrossProduct(omega, math::CrossProduct(omega, r));
249
250 // Set node translational acceleration
251 this->vd[0] = acceleration[0] + alpha_cross_r[0] + omega_cross_omega_cross_r[0];
252 this->vd[1] = acceleration[1] + alpha_cross_r[1] + omega_cross_omega_cross_r[1];
253 this->vd[2] = acceleration[2] + alpha_cross_r[2] + omega_cross_omega_cross_r[2];
254
255 // Set node angular acceleration
256 this->vd[3] = alpha[0];
257 this->vd[4] = alpha[1];
258 this->vd[5] = alpha[2];
259 }
260};
261
283public:
284 explicit NodeBuilder(Node& n) : node(n) {}
285 ~NodeBuilder() = default;
286 NodeBuilder(const NodeBuilder&) = delete;
290
291 //--------------------------------------------------------------------------
292 // Set position
293 //--------------------------------------------------------------------------
294
295 /*
296 * @brief Sets the node position from a 7 x 1 vector
297 * @param p -> 7 x 1 vector (x, y, z, w, i, j, k)
298 */
299 NodeBuilder& SetPosition(const std::array<double, 7>& p) {
300 this->node.x0 = p;
301 return *this;
302 }
303
304 /*
305 * @brief Sets the node position from position and orientation components
306 * @param x position X component
307 * @param y position Y component
308 * @param z position Z component
309 * @param w quaternion w component (scalar part)
310 * @param i quaternion i component (x vector part)
311 * @param j quaternion j component (y vector part)
312 * @param k quaternion k component (z vector part)
313 */
314 NodeBuilder& SetPosition(double x, double y, double z, double w, double i, double j, double k) {
315 return this->SetPosition(std::array{x, y, z, w, i, j, k});
316 }
317
318 /*
319 * @brief Sets the node position from translational components
320 * @param x X position component
321 * @param y Y position component
322 * @param z Z position component
323 */
324 NodeBuilder& SetPosition(const std::array<double, 3>& p) {
325 this->node.x0[0] = p[0];
326 this->node.x0[1] = p[1];
327 this->node.x0[2] = p[2];
328 return *this;
329 }
330
331 /*
332 * @brief Sets the node position from translational components
333 * @param x X position component
334 * @param y Y position component
335 * @param z Z position component
336 */
337 NodeBuilder& SetPosition(double x, double y, double z) {
338 return this->SetPosition(std::array{x, y, z});
339 }
340
341 //--------------------------------------------------------------------------
342 // Set orientation
343 //--------------------------------------------------------------------------
344
345 /*
346 * @brief Sets the node orientation from quaternion
347 * @param p quaternion (w,i,j,k)
348 */
349 NodeBuilder& SetOrientation(const std::array<double, 4>& p) {
350 this->node.x0[3] = p[0];
351 this->node.x0[4] = p[1];
352 this->node.x0[5] = p[2];
353 this->node.x0[6] = p[3];
354 return *this;
355 }
356
357 /*
358 * @brief Sets the node orientation from quaternion components
359 * @param w quaternion w component (scalar part)
360 * @param i quaternion i component (x vector part)
361 * @param j quaternion j component (y vector part)
362 * @param k quaternion k component (z vector part)
363 */
364 NodeBuilder& SetOrientation(double w, double i, double j, double k) {
365 return this->SetOrientation(std::array{w, i, j, k});
366 }
367
368 //--------------------------------------------------------------------------
369 // Set displacement
370 //--------------------------------------------------------------------------
371
372 /*
373 * @brief Sets the node displacement from a 7 x 1 vector
374 * @param p -> 7 x 1 vector (x, y, z, w, i, j, k)
375 */
376 NodeBuilder& SetDisplacement(const std::array<double, 7>& p) {
377 this->node.u = p;
378 return *this;
379 }
380
381 /*
382 * @brief Sets the node displacement from displacement components
383 * @param x displacement X component
384 * @param y displacement Y component
385 * @param z displacement Z component
386 * @param w quaternion w component (scalar part)
387 * @param i quaternion i component (x vector part)
388 * @param j quaternion j component (y vector part)
389 * @param k quaternion k component (z vector part)
390 */
392 double x, double y, double z, double w, double i, double j, double k
393 ) {
394 return this->SetDisplacement(std::array{x, y, z, w, i, j, k});
395 }
396
397 /*
398 * @brief Sets the node displacement from translational components
399 * @param x displacement X component
400 * @param y displacement Y component
401 * @param z displacement Z component
402 */
403 NodeBuilder& SetDisplacement(const std::array<double, 3>& p) {
404 this->node.u[0] = p[0];
405 this->node.u[1] = p[1];
406 this->node.u[2] = p[2];
407 return *this;
408 }
409
410 /*
411 * @brief Sets the node displacement from translational components
412 * @param x displacement X component
413 * @param y displacement Y component
414 * @param z displacement Z component
415 */
416 NodeBuilder& SetDisplacement(double x, double y, double z) {
417 return this->SetDisplacement(std::array{x, y, z});
418 }
419
420 //--------------------------------------------------------------------------
421 // Set velocity
422 //--------------------------------------------------------------------------
423
424 /*
425 * @brief Sets the node velocity from 6 vector components
426 * @param x x-component of translational velocity
427 * @param y y-component of translational velocity
428 * @param z z-component of translational velocity
429 * @param rx x-component of rotational velocity
430 * @param ry y-component of rotational velocity
431 * @param rz z-component of rotational velocity
432 */
433 NodeBuilder& SetVelocity(double x, double y, double z, double rx, double ry, double rz) {
434 this->node.v = {x, y, z, rx, ry, rz};
435 return *this;
436 }
437
438 /*
439 * @brief Sets the node velocity from a vector
440 * @param v -> 6 x 1 vector (x, y, z, rx, ry, rz)
441 */
442 NodeBuilder& SetVelocity(const std::array<double, 6>& v) {
443 return this->SetVelocity(v[0], v[1], v[2], v[3], v[4], v[5]);
444 }
445
446 /*
447 * @brief Sets the node velocity from 3 vector components
448 * @param x x-component of translational velocity
449 * @param y y-component of translational velocity
450 * @param z z-component of translational velocity
451 */
452 NodeBuilder& SetVelocity(double x, double y, double z) {
453 this->node.v[0] = x;
454 this->node.v[1] = y;
455 this->node.v[2] = z;
456 return *this;
457 }
458
459 /*
460 * @brief Sets the node velocity from a 3 x 1 vector
461 * @param v -> 3D vector (x, y, z)
462 */
463 NodeBuilder& SetVelocity(const std::array<double, 3>& v) {
464 return this->SetVelocity(v[0], v[1], v[2]);
465 }
466
467 //--------------------------------------------------------------------------
468 // Set acceleration
469 //--------------------------------------------------------------------------
470
471 /*
472 * @brief Sets the node acceleration from 6 vector components
473 * @param x x-component of translational acceleration
474 * @param y y-component of translational acceleration
475 * @param z z-component of translational acceleration
476 * @param rx x-component of rotational acceleration
477 * @param ry y-component of rotational acceleration
478 * @param rz z-component of rotational acceleration
479 */
480 NodeBuilder& SetAcceleration(double x, double y, double z, double rx, double ry, double rz) {
481 this->node.vd = {x, y, z, rx, ry, rz};
482 return *this;
483 }
484
485 /*
486 * @brief Sets the node acceleration from a vector
487 * @param v -> 6 x 1 vector (x, y, z, rx, ry, rz)
488 */
489 NodeBuilder& SetAcceleration(const std::array<double, 6>& v) {
490 return this->SetAcceleration(v[0], v[1], v[2], v[3], v[4], v[5]);
491 }
492
493 /*
494 * @brief Sets the node acceleration from vector components
495 * @param x x-component of acceleration
496 * @param y y-component of acceleration
497 * @param z z-component of acceleration
498 */
499 NodeBuilder& SetAcceleration(double x, double y, double z) {
500 this->node.vd[0] = x;
501 this->node.vd[1] = y;
502 this->node.vd[2] = z;
503 return *this;
504 }
505
506 /*
507 * @brief Sets the node acceleration from a vector
508 * @param v -> 3 x 1 vector (x, y, z)
509 */
510 NodeBuilder& SetAcceleration(const std::array<double, 3>& v) {
511 return this->SetAcceleration(v[0], v[1], v[2]);
512 }
513
514 //--------------------------------------------------------------------------
515 // Element location
516 //--------------------------------------------------------------------------
517
518 /*
519 * @brief Sets the parametric position of the node within the element
520 * @param location -> position within element on range [0, 1]
521 */
522 NodeBuilder& SetElemLocation(double location) {
523 this->node.s = location;
524 return *this;
525 }
526
527 //--------------------------------------------------------------------------
528 // Build
529 //--------------------------------------------------------------------------
530
532 [[nodiscard]] size_t Build() const { return this->node.id; }
533
534private:
535 Node& node;
536};
537
538} // namespace kynema
Builder class for constructing and configuring Node objects.
Definition node.hpp:282
NodeBuilder & SetAcceleration(double x, double y, double z)
Definition node.hpp:499
NodeBuilder(NodeBuilder &&)=delete
NodeBuilder & operator=(const NodeBuilder &)=delete
NodeBuilder & SetDisplacement(double x, double y, double z)
Definition node.hpp:416
NodeBuilder & SetAcceleration(const std::array< double, 3 > &v)
Definition node.hpp:510
NodeBuilder(const NodeBuilder &)=delete
NodeBuilder & SetVelocity(const std::array< double, 3 > &v)
Definition node.hpp:463
NodeBuilder & SetDisplacement(double x, double y, double z, double w, double i, double j, double k)
Definition node.hpp:391
NodeBuilder & SetVelocity(const std::array< double, 6 > &v)
Definition node.hpp:442
NodeBuilder & SetAcceleration(const std::array< double, 6 > &v)
Definition node.hpp:489
NodeBuilder & SetDisplacement(const std::array< double, 3 > &p)
Definition node.hpp:403
NodeBuilder & SetVelocity(double x, double y, double z, double rx, double ry, double rz)
Definition node.hpp:433
NodeBuilder & SetPosition(double x, double y, double z, double w, double i, double j, double k)
Definition node.hpp:314
NodeBuilder & SetElemLocation(double location)
Definition node.hpp:522
NodeBuilder & SetOrientation(double w, double i, double j, double k)
Definition node.hpp:364
NodeBuilder & SetPosition(const std::array< double, 3 > &p)
Definition node.hpp:324
NodeBuilder(Node &n)
Definition node.hpp:284
NodeBuilder & operator=(NodeBuilder &&)=delete
~NodeBuilder()=default
NodeBuilder & SetPosition(const std::array< double, 7 > &p)
Definition node.hpp:299
NodeBuilder & SetPosition(double x, double y, double z)
Definition node.hpp:337
NodeBuilder & SetDisplacement(const std::array< double, 7 > &p)
Definition node.hpp:376
NodeBuilder & SetVelocity(double x, double y, double z)
Definition node.hpp:452
NodeBuilder & SetOrientation(const std::array< double, 4 > &p)
Definition node.hpp:349
NodeBuilder & SetAcceleration(double x, double y, double z, double rx, double ry, double rz)
Definition node.hpp:480
size_t Build() const
Build finalizes construction of node and returns the node's ID.
Definition node.hpp:532
KOKKOS_INLINE_FUNCTION void CrossProduct(const VectorType &a, const VectorType &b, const VectorType &c)
Calculate the cross product between two vector views.
Definition vector_operations.hpp:40
KOKKOS_INLINE_FUNCTION void QuaternionCompose(const Quaternion1 &q1, const Quaternion2 &q2, QuaternionN &qn)
Composes (i.e. multiplies) two quaternions and stores the result in a third quaternion.
Definition quaternion_operations.hpp:204
KOKKOS_INLINE_FUNCTION void RotationVectorToQuaternion(const Vector &phi, const Quaternion &quaternion)
Returns a 4-D quaternion from provided 3-D rotation vector, i.e. the exponential map.
Definition quaternion_operations.hpp:231
KOKKOS_INLINE_FUNCTION void RotateVectorByQuaternion(const Quaternion &q, const View1 &v, const View2 &v_rot)
Rotates provided vector by provided unit quaternion and returns the result.
Definition quaternion_operations.hpp:120
Definition calculate_constraint_output.hpp:8
Represents a node in the finite element model.
Definition node.hpp:26
Node & RotateDisplacementAboutPoint(const std::array< double, 3 > &rv, const std::array< double, 3 > &point)
Rotate node displacement by a rotation vector about the given point.
Definition node.hpp:190
size_t id
Definition node.hpp:27
Node & Translate(const std::array< double, 3 > &displacement)
Translate node by a displacement vector.
Definition node.hpp:87
Node & RotateDisplacementAboutPoint(const std::array< double, 4 > &q, const std::array< double, 3 > &point)
Rotate node displacement by a quaternion about the given point.
Definition node.hpp:152
Node & RotateAboutPoint(const std::array< double, 4 > &q, const std::array< double, 3 > &point)
Rotate node by a quaternion about the given point.
Definition node.hpp:100
std::array< double, 6 > v
Definition node.hpp:30
void SetVelocityAboutPoint(const std::array< double, 6 > &velocity, const std::array< double, 3 > &point)
Set node velocity based on rigid body motion about a reference point.
Definition node.hpp:203
std::array< double, 7 > x0
Definition node.hpp:28
Node(size_t node_id, std::array< double, 7 > position, std::array< double, 7 > displacement=std::array< double, 7 >{0., 0., 0., 1., 0., 0., 0.}, std::array< double, 6 > velocity=std::array< double, 6 >{0., 0., 0., 0., 0., 0.}, std::array< double, 6 > acceleration=std::array< double, 6 >{0., 0., 0., 0., 0., 0.})
Construct a node with an ID, position, displacement, velocity, and acceleration vectors.
Definition node.hpp:45
void SetAccelerationAboutPoint(const std::array< double, 6 > &acceleration, const std::array< double, 3 > &omega, const std::array< double, 3 > &point)
Set node acceleration based on rigid body motion about a reference point.
Definition node.hpp:233
std::array< double, 7 > u
Definition node.hpp:29
Node(size_t node_id)
Construct a node with an ID.
Definition node.hpp:35
Node & RotateAboutPoint(const std::array< double, 3 > &rv, const std::array< double, 3 > &point)
Rotate node by a rotation vector about the given point.
Definition node.hpp:133
double s
Definition node.hpp:32
Node & TranslateDisplacement(const std::array< double, 3 > &displacement)
Add translational displacement to node displacement vector.
Definition node.hpp:144
std::array< double, 6 > vd
Definition node.hpp:31
std::array< double, 7 > DisplacedPosition() const
Definition node.hpp:61