/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 const auto q_displaced = Eigen::Quaternion<double>(x0[3], x0[4], x0[5], x0[6]) *
71 Eigen::Quaternion<double>(u[3], u[4], u[5], u[6]);
72 displaced_position[3] = q_displaced.w();
73 displaced_position[4] = q_displaced.x();
74 displaced_position[5] = q_displaced.y();
75 displaced_position[6] = q_displaced.z();
76
77 return displaced_position;
78 }
79
80 //--------------------------------------------------------------------------
81 // Modify node position (x)
82 //--------------------------------------------------------------------------
83
85 Node& Translate(std::span<const double, 3> displacement) {
86 //----------------------------------------------------
87 // Position, x(0:2)
88 //----------------------------------------------------
89 this->x0[0] += displacement[0];
90 this->x0[1] += displacement[1];
91 this->x0[2] += displacement[2];
92
93 // No change to orientation
94 return *this;
95 }
96
98 Node& RotateAboutPoint(std::span<const double, 4> q, std::span<const double, 3> point) {
99 const auto quaternion = Eigen::Quaternion<double>(q[0], q[1], q[2], q[3]);
100 const auto location = Eigen::Matrix<double, 3, 1>(x0.data());
101 const auto point_location = Eigen::Matrix<double, 3, 1>(point.data());
102
103 //----------------------------------------------------
104 // Position, x(0:2)
105 //----------------------------------------------------
106 // Get vector from reference point to initial node position
107 const auto r = location - point_location;
108
109 // Rotate the vector r using the provided quaternion q
110 const auto rotated_r = quaternion._transformVector(r);
111
112 // Update the position by adding the rotated vector to the reference point
113 const auto x0_new = rotated_r + point_location;
114 this->x0[0] = x0_new(0);
115 this->x0[1] = x0_new(1);
116 this->x0[2] = x0_new(2);
117
118 //----------------------------------------------------
119 // Orientation, x(3:6)
120 //----------------------------------------------------
121 // Compose q with initial orientation to get rotated orientation
122 auto q_new = quaternion * Eigen::Quaternion<double>(x0[3], x0[4], x0[5], x0[6]);
123
124 // Update the orientation
125 this->x0[3] = q_new.w();
126 this->x0[4] = q_new.x();
127 this->x0[5] = q_new.y();
128 this->x0[6] = q_new.z();
129
130 return *this;
131 }
132
133 //--------------------------------------------------------------------------
134 // Modify node displacement (u)
135 //--------------------------------------------------------------------------
136
138 Node& TranslateDisplacement(std::span<const double, 3> displacement) {
139 this->u[0] += displacement[0];
140 this->u[1] += displacement[1];
141 this->u[2] += displacement[2];
142 return *this;
143 }
144
147 std::span<const double, 4> q, std::span<const double, 3> point
148 ) {
149 const auto quaternion = Eigen::Quaternion<double>(q[0], q[1], q[2], q[3]);
150 const auto point_location = Eigen::Matrix<double, 3, 1>(point.data());
151 const auto dp = this->DisplacedPosition();
152 const auto displaced_position = Eigen::Matrix<double, 3, 1>(dp.data());
153 const auto location = Eigen::Matrix<double, 3, 1>(x0.data());
154
155 //----------------------------------------------------
156 // Displacement position, u(0:2)
157 //----------------------------------------------------
158 // Get vector from reference point to displaced node position
159 const auto r = displaced_position - point_location;
160
161 // Rotate the vector r using the provided quaternion q
162 const auto rotated_r = quaternion._transformVector(r);
163
164 // Update the displacement position by adding the rotated vector to the reference point
165 // and subtracting the initial position
166 const auto u_new = rotated_r + point_location - location;
167 this->u[0] = u_new(0);
168 this->u[1] = u_new(1);
169 this->u[2] = u_new(2);
170
171 //----------------------------------------------------
172 // Displacement orientation, u(3:6)
173 //----------------------------------------------------
174 // Compose q with initial displacement orientation to get rotated displacement orientation
175 const auto q_new = quaternion * Eigen::Quaternion<double>(u[3], u[4], u[5], u[6]);
176
177 // Update the displacement orientation
178 this->u[3] = q_new.w();
179 this->u[4] = q_new.x();
180 this->u[5] = q_new.y();
181 this->u[6] = q_new.z();
182
183 return *this;
184 }
185
186 //--------------------------------------------------------------------------
187 // Modify node velocity (v)
188 //--------------------------------------------------------------------------
189
192 std::span<const double, 6> velocity, std::span<const double, 3> point
193 ) {
194 // Get vector from reference point to displaced node position
195 const auto displaced_position = this->DisplacedPosition();
196 const auto dp = Eigen::Matrix<double, 3, 1>(displaced_position.data());
197 const auto p = Eigen::Matrix<double, 3, 1>(point.data());
198 const auto r = dp - p;
199
200 // Calculate velocity contribution from angular velocity
201 const auto omega = Eigen::Matrix<double, 3, 1>(&velocity[3]);
202 const auto omega_cross_r = omega.cross(r);
203
204 // Set node translational velocity
205 this->v[0] = velocity[0] + omega_cross_r(0);
206 this->v[1] = velocity[1] + omega_cross_r(1);
207 this->v[2] = velocity[2] + omega_cross_r(2);
208
209 // Set node angular velocity
210 this->v[3] = velocity[3];
211 this->v[4] = velocity[4];
212 this->v[5] = velocity[5];
213 }
214
215 //--------------------------------------------------------------------------
216 // Modify node acceleration (vd)
217 //--------------------------------------------------------------------------
218
221 std::span<const double, 6> acceleration, std::span<const double, 3> omega,
222 std::span<const double, 3> point
223 ) {
224 const auto omega_vec = Eigen::Matrix<double, 3, 1>(omega.data());
225 // Get vector from reference point to displaced node position
226 const auto displaced_position = this->DisplacedPosition();
227 const auto dp = Eigen::Matrix<double, 3, 1>(displaced_position.data());
228 const auto p = Eigen::Matrix<double, 3, 1>(point.data());
229 const auto r = dp - p;
230
231 // Calculate translational acceleration contribution from angular velocity
232 const auto alpha = Eigen::Matrix<double, 3, 1>(&acceleration[3]);
233 const auto alpha_cross_r = alpha.cross(r);
234 const auto omega_cross_omega_cross_r = omega_vec.cross(omega_vec.cross(r));
235 const auto angular_contribution = alpha_cross_r + omega_cross_omega_cross_r;
236
237 // Set node translational acceleration
238 this->vd[0] = acceleration[0] + angular_contribution(0);
239 this->vd[1] = acceleration[1] + angular_contribution(1);
240 this->vd[2] = acceleration[2] + angular_contribution(2);
241
242 // Set node angular acceleration
243 this->vd[3] = alpha[0];
244 this->vd[4] = alpha[1];
245 this->vd[5] = alpha[2];
246 }
247};
248
270public:
271 explicit NodeBuilder(Node& n) : node(n) {}
272 ~NodeBuilder() = default;
273 NodeBuilder(const NodeBuilder&) = delete;
277
278 //--------------------------------------------------------------------------
279 // Set position
280 //--------------------------------------------------------------------------
281
282 /*
283 * @brief Sets the node position from a 7 x 1 vector
284 * @param p -> 7 x 1 vector (x, y, z, w, i, j, k)
285 */
286 NodeBuilder& SetPosition(std::span<const double, 7> p) {
287 std::ranges::copy(p, std::begin(node.x0));
288 return *this;
289 }
290
291 /*
292 * @brief Sets the node position from position and orientation components
293 * @param x position X component
294 * @param y position Y component
295 * @param z position Z component
296 * @param w quaternion w component (scalar part)
297 * @param i quaternion i component (x vector part)
298 * @param j quaternion j component (y vector part)
299 * @param k quaternion k component (z vector part)
300 */
301 NodeBuilder& SetPosition(double x, double y, double z, double w, double i, double j, double k) {
302 return this->SetPosition(std::array{x, y, z, w, i, j, k});
303 }
304
305 //--------------------------------------------------------------------------
306 // Set displacement
307 //--------------------------------------------------------------------------
308
309 /*
310 * @brief Sets the node displacement from a 7 x 1 vector
311 * @param p -> 7 x 1 vector (x, y, z, w, i, j, k)
312 */
313 NodeBuilder& SetDisplacement(std::span<const double, 7> p) {
314 std::ranges::copy(p, std::begin(node.u));
315 return *this;
316 }
317
318 /*
319 * @brief Sets the node displacement from displacement components
320 * @param x displacement X component
321 * @param y displacement Y component
322 * @param z displacement Z component
323 * @param w quaternion w component (scalar part)
324 * @param i quaternion i component (x vector part)
325 * @param j quaternion j component (y vector part)
326 * @param k quaternion k component (z vector part)
327 */
329 double x, double y, double z, double w, double i, double j, double k
330 ) {
331 return this->SetDisplacement(std::array{x, y, z, w, i, j, k});
332 }
333
334 //--------------------------------------------------------------------------
335 // Set velocity
336 //--------------------------------------------------------------------------
337
338 /*
339 * @brief Sets the node velocity from 6 vector components
340 * @param x x-component of translational velocity
341 * @param y y-component of translational velocity
342 * @param z z-component of translational velocity
343 * @param rx x-component of rotational velocity
344 * @param ry y-component of rotational velocity
345 * @param rz z-component of rotational velocity
346 */
347 NodeBuilder& SetVelocity(double x, double y, double z, double rx, double ry, double rz) {
348 SetVelocity(std::array{x, y, z, rx, ry, rz});
349 return *this;
350 }
351
352 /*
353 * @brief Sets the node velocity from a vector
354 * @param v -> 6 x 1 vector (x, y, z, rx, ry, rz)
355 */
356 NodeBuilder& SetVelocity(std::span<const double, 6> v) {
357 std::ranges::copy(v, std::begin(node.v));
358 return *this;
359 }
360
361 //--------------------------------------------------------------------------
362 // Set acceleration
363 //--------------------------------------------------------------------------
364
365 /*
366 * @brief Sets the node acceleration from 6 vector components
367 * @param x x-component of translational acceleration
368 * @param y y-component of translational acceleration
369 * @param z z-component of translational acceleration
370 * @param rx x-component of rotational acceleration
371 * @param ry y-component of rotational acceleration
372 * @param rz z-component of rotational acceleration
373 */
374 NodeBuilder& SetAcceleration(double x, double y, double z, double rx, double ry, double rz) {
375 SetAcceleration(std::array{x, y, z, rx, ry, rz});
376 return *this;
377 }
378
379 /*
380 * @brief Sets the node acceleration from a vector
381 * @param v -> 6 x 1 vector (x, y, z, rx, ry, rz)
382 */
383 NodeBuilder& SetAcceleration(std::span<const double, 6> v) {
384 std::ranges::copy(v, std::begin(node.vd));
385 return *this;
386 }
387
388 //--------------------------------------------------------------------------
389 // Element location
390 //--------------------------------------------------------------------------
391
392 /*
393 * @brief Sets the parametric position of the node within the element
394 * @param location -> position within element on range [0, 1]
395 */
396 NodeBuilder& SetElemLocation(double location) {
397 this->node.s = location;
398 return *this;
399 }
400
401 //--------------------------------------------------------------------------
402 // Build
403 //--------------------------------------------------------------------------
404
406 [[nodiscard]] size_t Build() const { return this->node.id; }
407
408private:
409 Node& node;
410};
411
412} // namespace kynema
Builder class for constructing and configuring Node objects.
Definition node.hpp:269
NodeBuilder & SetPosition(std::span< const double, 7 > p)
Definition node.hpp:286
NodeBuilder & SetVelocity(std::span< const double, 6 > v)
Definition node.hpp:356
NodeBuilder(NodeBuilder &&)=delete
NodeBuilder & operator=(const NodeBuilder &)=delete
NodeBuilder(const NodeBuilder &)=delete
NodeBuilder & SetDisplacement(double x, double y, double z, double w, double i, double j, double k)
Definition node.hpp:328
NodeBuilder & SetAcceleration(std::span< const double, 6 > v)
Definition node.hpp:383
NodeBuilder & SetVelocity(double x, double y, double z, double rx, double ry, double rz)
Definition node.hpp:347
NodeBuilder & SetPosition(double x, double y, double z, double w, double i, double j, double k)
Definition node.hpp:301
NodeBuilder & SetElemLocation(double location)
Definition node.hpp:396
NodeBuilder & SetDisplacement(std::span< const double, 7 > p)
Definition node.hpp:313
NodeBuilder(Node &n)
Definition node.hpp:271
NodeBuilder & operator=(NodeBuilder &&)=delete
~NodeBuilder()=default
NodeBuilder & SetAcceleration(double x, double y, double z, double rx, double ry, double rz)
Definition node.hpp:374
size_t Build() const
Build finalizes construction of node and returns the node's ID.
Definition node.hpp:406
Definition calculate_constraint_output.hpp:8
Represents a node in the finite element model.
Definition node.hpp:26
Node & Translate(std::span< const double, 3 > displacement)
Translate node by a displacement vector.
Definition node.hpp:85
size_t id
Definition node.hpp:27
Node & RotateDisplacementAboutPoint(std::span< const double, 4 > q, std::span< const double, 3 > point)
Rotate node displacement by a quaternion about the given point.
Definition node.hpp:146
std::array< double, 6 > v
Definition node.hpp:30
Node & RotateAboutPoint(std::span< const double, 4 > q, std::span< const double, 3 > point)
Rotate node by a quaternion about the given point.
Definition node.hpp:98
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 SetVelocityAboutPoint(std::span< const double, 6 > velocity, std::span< const double, 3 > point)
Set node velocity based on rigid body motion about a reference point.
Definition node.hpp:191
void SetAccelerationAboutPoint(std::span< const double, 6 > acceleration, std::span< const double, 3 > omega, std::span< const double, 3 > point)
Set node acceleration based on rigid body motion about a reference point.
Definition node.hpp:220
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 & TranslateDisplacement(std::span< const double, 3 > displacement)
Add translational displacement to node displacement vector.
Definition node.hpp:138
double s
Definition node.hpp:32
std::array< double, 6 > vd
Definition node.hpp:31
std::array< double, 7 > DisplacedPosition() const
Definition node.hpp:61