/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 {1.0_rt - 2.0_rt * (q.y * q.y + q.z * q.z),
41 2.0_rt * (q.x * q.y - q.z * q.w),
42 2.0_rt * (q.x * q.z + q.y * q.w),
43 2.0_rt * (q.x * q.y + q.z * q.w),
44 1.0_rt - 2.0_rt * (q.x * q.x + q.z * q.z),
45 2.0_rt * (q.y * q.z - q.x * q.w),
46 2.0_rt * (q.x * q.z - q.y * q.w),
47 2.0_rt * (q.y * q.z + q.x * q.w),
48 1.0_rt - 2.0_rt * (q.x * q.x + q.y * q.y)};
49}
50
51Tensor tensor(const Quaternion& input);
52
53AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Quaternion
54from_axis_angle(const Vector& axis, const amrex::Real angle_degrees)
55{
56 const amrex::Real half_angle = -0.5_rt * utils::radians(angle_degrees);
57 const amrex::Real axis_magnitude = mag(axis);
58 const amrex::Real scale = std::sin(half_angle) / axis_magnitude;
59 return {
60 std::cos(half_angle), scale * axis.x(), scale * axis.y(),
61 scale * axis.z()};
62}
63
65AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Tensor
66quaternion(const Vector& axis, const amrex::Real angle_degrees)
67{
68 // Preserve the original operation sequence used by existing actuator and
69 // sampling models. Although tensor_unit(from_axis_angle(...)) is
70 // algebraically equivalent, it changes floating-point rounding and
71 // therefore existing regression results.
72 const amrex::Real angle = -1.0_rt * utils::radians(angle_degrees);
73 const amrex::Real cval = std::cos(0.5_rt * angle);
74 const amrex::Real sval = std::sin(0.5_rt * angle);
75 const auto axis_magnitude = mag(axis);
76 const amrex::Real q0 = cval;
77 const amrex::Real q1 = sval * axis.x() / axis_magnitude;
78 const amrex::Real q2 = sval * axis.y() / axis_magnitude;
79 const amrex::Real q3 = sval * axis.z() / axis_magnitude;
80
81 Tensor result;
82 result.xx() = (q0 * q0) + (q1 * q1) - (q2 * q2) - (q3 * q3);
83 result.xy() = 2.0_rt * (q1 * q2 - q0 * q3);
84 result.xz() = 2.0_rt * (q0 * q2 + q1 * q3);
85
86 result.yx() = 2.0_rt * (q1 * q2 + q0 * q3);
87 result.yy() = (q0 * q0) - (q1 * q1) + (q2 * q2) - (q3 * q3);
88 result.yz() = 2.0_rt * (q2 * q3 - q0 * q1);
89
90 result.zx() = 2.0_rt * (q1 * q3 - q0 * q2);
91 result.zy() = 2.0_rt * (q0 * q1 + q2 * q3);
92 result.zz() = (q0 * q0) - (q1 * q1) - (q2 * q2) + (q3 * q3);
93
94 return result;
95}
96
98Quaternion from_roll_pitch_yaw(const Vector& angles);
99
100Quaternion slerp(Quaternion a, Quaternion b, amrex::Real fraction);
101
102} // namespace kynema_sgf::vs
103
104#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:52
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:66
Tensor tensor(const Quaternion &input)
Definition quaternion.cpp:47
Quaternion slerp(Quaternion a, Quaternion b, const amrex::Real fraction)
Definition quaternion.cpp:71
Quaternion operator*(const Quaternion &lhs, const Quaternion &rhs)
Rotation composition: apply rhs first, followed by lhs.
Definition quaternion.cpp:38
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:54
amrex::Real dot(const Quaternion &a, const Quaternion &b)
Definition quaternion.cpp:33
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T mag(const TensorT< T > &t)
Definition tensorI.H:182
@ 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