/home/runner/work/kynema-sgf/kynema-sgf/src/core/vs/quaternion.H Source File

Kynema-SGF API: /home/runner/work/kynema-sgf/kynema-sgf/src/core/vs/quaternion.H Source File
Kynema-SGF API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
quaternion.H
Go to the documentation of this file.
1#ifndef VS_QUATERNION_H
2#define VS_QUATERNION_H
3
6
7#include <cmath>
8
9#include "AMReX.H"
10
11namespace kynema_sgf::vs {
12
13using namespace amrex::literals;
14
17{
18 amrex::Real w{1.0_rt};
19 amrex::Real x{0.0_rt};
20 amrex::Real y{0.0_rt};
21 amrex::Real z{0.0_rt};
22
25
27 [[nodiscard]] Quaternion normalized() const;
28
30 [[nodiscard]] Quaternion conjugate() const;
31};
32
33amrex::Real dot(const Quaternion& a, const Quaternion& b);
34
36Quaternion operator*(const Quaternion& lhs, const Quaternion& rhs);
37
38AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Tensor tensor_unit(const Quaternion& q)
39{
40 return {
41 1.0_rt - (2.0_rt * ((q.y * q.y) + (q.z * q.z))),
42 2.0_rt * ((q.x * q.y) - (q.z * q.w)),
43 2.0_rt * ((q.x * q.z) + (q.y * q.w)),
44 2.0_rt * ((q.x * q.y) + (q.z * q.w)),
45 1.0_rt - (2.0_rt * ((q.x * q.x) + (q.z * q.z))),
46 2.0_rt * ((q.y * q.z) - (q.x * q.w)),
47 2.0_rt * ((q.x * q.z) - (q.y * q.w)),
48 2.0_rt * ((q.y * q.z) + (q.x * q.w)),
49 1.0_rt - (2.0_rt * ((q.x * q.x) + (q.y * q.y)))};
50}
51
52Tensor tensor(const Quaternion& input);
53
54AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Quaternion
55from_axis_angle(const Vector& axis, const amrex::Real angle_degrees)
56{
57 const amrex::Real half_angle = -0.5_rt * utils::radians(angle_degrees);
58 const amrex::Real axis_magnitude = mag(axis);
59 const amrex::Real scale = std::sin(half_angle) / axis_magnitude;
60 return {
61 .w = std::cos(half_angle),
62 .x = scale * axis.x(),
63 .y = scale * axis.y(),
64 .z = scale * axis.z()};
65}
66
68AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Tensor
69quaternion(const Vector& axis, const amrex::Real angle_degrees)
70{
71 // Preserve the original operation sequence used by existing actuator and
72 // sampling models. Although tensor_unit(from_axis_angle(...)) is
73 // algebraically equivalent, it changes floating-point rounding and
74 // therefore existing regression results.
75 const amrex::Real angle = -1.0_rt * utils::radians(angle_degrees);
76 const amrex::Real cval = std::cos(0.5_rt * angle);
77 const amrex::Real sval = std::sin(0.5_rt * angle);
78 const auto axis_magnitude = mag(axis);
79 const amrex::Real q0 = cval;
80 const amrex::Real q1 = sval * axis.x() / axis_magnitude;
81 const amrex::Real q2 = sval * axis.y() / axis_magnitude;
82 const amrex::Real q3 = sval * axis.z() / axis_magnitude;
83
84 Tensor result;
85 result.xx() = (q0 * q0) + (q1 * q1) - (q2 * q2) - (q3 * q3);
86 result.xy() = 2.0_rt * ((q1 * q2) - (q0 * q3));
87 result.xz() = 2.0_rt * ((q0 * q2) + (q1 * q3));
88
89 result.yx() = 2.0_rt * ((q1 * q2) + (q0 * q3));
90 result.yy() = (q0 * q0) - (q1 * q1) + (q2 * q2) - (q3 * q3);
91 result.yz() = 2.0_rt * ((q2 * q3) - (q0 * q1));
92
93 result.zx() = 2.0_rt * ((q1 * q3) - (q0 * q2));
94 result.zy() = 2.0_rt * ((q0 * q1) + (q2 * q3));
95 result.zz() = (q0 * q0) - (q1 * q1) - (q2 * q2) + (q3 * q3);
96
97 return result;
98}
99
101Quaternion from_roll_pitch_yaw(const Vector& angles);
102
103Quaternion slerp(Quaternion a, Quaternion b, amrex::Real fraction);
104
105} // namespace kynema_sgf::vs
106
107#endif
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real radians(const amrex::Real deg_val)
Convert from degrees to radians.
Definition trig_ops.H:32
Definition quaternion.cpp:7
Quaternion from_roll_pitch_yaw(const Vector &angles)
Definition quaternion.cpp:59
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Tensor quaternion(const Vector &axis, const amrex::Real angle_degrees)
Compatibility interface for existing axis-angle tensor rotations.
Definition quaternion.H:69
Tensor tensor(const Quaternion &input)
Definition quaternion.cpp:54
Quaternion slerp(Quaternion a, Quaternion b, const amrex::Real fraction)
Definition quaternion.cpp:80
Quaternion operator*(const Quaternion &lhs, const Quaternion &rhs)
Rotation composition: apply rhs first, followed by lhs.
Definition quaternion.cpp:41
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Tensor tensor_unit(const Quaternion &q)
Definition quaternion.H:38
VectorT< amrex::Real > Vector
Definition vector.H:145
TensorT< amrex::Real > Tensor
Definition tensor.H:158
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Quaternion from_axis_angle(const Vector &axis, const amrex::Real angle_degrees)
Definition quaternion.H:55
amrex::Real dot(const Quaternion &a, const Quaternion &b)
Definition quaternion.cpp:36
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T mag(const TensorT< T > &t)
Definition tensorI.H:181
@ input
Definition BoundaryPlane.H:19
Definition quaternion.H:17
amrex::Real w
Definition quaternion.H:18
Quaternion conjugate() const
Return the quaternion conjugate.
Definition quaternion.cpp:31
amrex::Real x
Definition quaternion.H:19
Quaternion & normalize()
Normalize this quaternion in place.
Definition quaternion.cpp:11
amrex::Real z
Definition quaternion.H:21
amrex::Real y
Definition quaternion.H:20
Quaternion normalized() const
Return a normalized copy without modifying this quaternion.
Definition quaternion.cpp:24
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & yz() &
Definition tensor.H:90
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & xy() &
Definition tensor.H:85
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & xz() &
Definition tensor.H:86
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & zy() &
Definition tensor.H:93
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & zx() &
Definition tensor.H:92
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & xx() &
Definition tensor.H:84
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & zz() &
Definition tensor.H:94
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & yy() &
Definition tensor.H:89
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & yx() &
Definition tensor.H:88
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & y() &
Definition vector.H:98
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & z() &
Definition vector.H:99
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & x() &
Definition vector.H:97