ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
quaternion.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef SRC_UTILS_INCLUDE_UTILS_QUATERNION_HPP
20#define SRC_UTILS_INCLUDE_UTILS_QUATERNION_HPP
21
22/**
23 * @file
24 *
25 * @brief Quaternion implementation and trait types
26 * for boost qvm interoperability.
27 */
28
29#include <boost/qvm/deduce_quat.hpp>
30#include <boost/qvm/deduce_scalar.hpp>
31#include <boost/qvm/deduce_vec.hpp>
32#include <boost/qvm/quat.hpp>
33#include <boost/qvm/quat_access.hpp>
34#include <boost/qvm/quat_operations.hpp>
35#include <boost/qvm/quat_traits.hpp>
36#include <boost/qvm/quat_vec_operations.hpp>
37
38#include <boost/serialization/array.hpp>
39#include <boost/serialization/is_bitwise_serializable.hpp>
40#include <boost/serialization/level.hpp>
41
42#include "utils/Array.hpp"
43#include "utils/Vector.hpp"
44#include "utils/matrix.hpp"
45
46#include <cassert>
47#include <cstddef>
48#include <type_traits>
49
50namespace Utils {
51
52/**
53 * Quaternion representation.
54 * @tparam T Element data type.
55 */
56template <typename T> struct Quaternion {
57 using container = typename Utils::Array<T, 4>;
59 using pointer = typename container::pointer;
60 using const_pointer = typename container::const_pointer;
61 using value_type = typename container::value_type;
62 using reference = typename container::reference;
63
64private:
66 template <class Archive> void serialize(Archive &ar, const unsigned int) {
67 ar & m_data;
68 }
69
70public:
71 /**
72 * @brief Normalize the quaternion in place.
73 */
74 void normalize() { boost::qvm::normalize(*this); }
75
76 /**
77 * @brief Retrieve a normalized copy of the quaternion.
78 * @return Normalized quaternion.
79 */
80 Quaternion<T> normalized() const { return boost::qvm::normalized(*this); }
81
82 /**
83 * @brief Element access (const).
84 * @param i Element index.
85 * @return Value of element @p i.
86 */
87 value_type operator[](std::size_t i) const { return m_data[i]; }
88 /**
89 * @brief Element access (non const).
90 * @param i Element index.
91 * @return Value of element @p i.
92 */
93 reference operator[](std::size_t i) { return m_data[i]; }
94
95 /**
96 * @brief Retrieve the norm of the quaternion.
97 * @return The norm.
98 */
99 value_type norm() const { return boost::qvm::mag(*this); }
100 /**
101 * @brief Retrieve the square of the norm of the quaternion.
102 * @return The squared norm.
103 */
104 value_type norm2() const { return boost::qvm::mag_sqr(*this); }
105
106 /**
107 * @brief Construct an identity quaternion.
108 * @return Identity quaternion.
109 */
110 static Quaternion<T> identity() { return boost::qvm::identity_quat<T>(); }
111
112 /**
113 * @brief Construct a zero quaternion.
114 * @return Quaternion with all elements set to zero.
115 */
116 static Quaternion<T> zero() { return boost::qvm::zero_quat<T>(); }
117
118 /**
119 * @brief Access to the underlying data (non const).
120 * @return Pointer to the first data member.
121 */
122 constexpr pointer data() { return m_data.data(); }
123
124 /**
125 * @brief Access to the underlying data (const).
126 * @return Pointer to the first data member.
127 */
128 constexpr const_pointer data() const noexcept { return m_data.data(); }
129};
130
131/**
132 * @brief Product quaternion and arithmetic type.
133 * @tparam T Data type of quaternion @p a.
134 * @tparam U Type of multiplier @p b.
135 * @param b Quaternion.
136 * @param a Multiplier.
137 * @return Multiplied quaternion.
138 */
139template <typename T, typename U,
140 std::enable_if_t<std::is_arithmetic_v<U>, bool> = true>
141Quaternion<T> operator*(const U &b, const Quaternion<T> &a) {
142 return boost::qvm::operator*(a, b);
143}
144
145/**
146 * @brief Convert quaternion to rotation matrix.
147 * @tparam T Data type of quaternion.
148 * @param q Quaternion.
149 * @return Rotation matrix.
150 */
151template <typename T> Matrix<T, 3, 3> rotation_matrix(Quaternion<T> const &q) {
152 auto const normed_q = q.normalized();
153 auto const id_mat = Utils::identity_mat<double, 3, 3>();
154 auto const v1 = normed_q * id_mat.col<0>();
155 auto const v2 = normed_q * id_mat.col<1>();
156 auto const v3 = normed_q * id_mat.col<2>();
157 return {{v1[0], v2[0], v3[0]}, {v1[1], v2[1], v3[1]}, {v1[2], v2[2], v3[2]}};
158}
159
160using boost::qvm::operator*;
161using boost::qvm::operator*=;
162using boost::qvm::operator==;
163using boost::qvm::dot;
164using boost::qvm::operator/;
165using boost::qvm::operator/=;
166using boost::qvm::operator+;
167using boost::qvm::operator+=;
168using boost::qvm::operator-;
169using boost::qvm::operator-=;
170
171} // namespace Utils
172
173namespace boost {
174
175namespace qvm {
176
177template <class T> struct quat_traits<Utils::Quaternion<T>> {
179 using scalar_type = T;
180
181 template <std::size_t I>
182 static constexpr inline scalar_type &write_element(quat_type &q) {
183 static_assert(I < 4, "Invalid index into quaternion.");
184 return q[I];
185 }
186
187 template <std::size_t I>
188 static constexpr inline scalar_type read_element(quat_type const &q) {
189 static_assert(I < 4, "Invalid index into quaternion.");
190 return q[I];
191 }
192
193 static inline scalar_type read_element_idx(std::size_t i,
194 quat_type const &q) {
195 assert(i < 4);
196 return q[i];
197 }
198
199 static inline scalar_type &write_element_idx(std::size_t i, quat_type &q) {
200 assert(i < 4);
201 return q[i];
202 }
203};
204
205template <typename T, typename U>
206struct deduce_scalar<Utils::Quaternion<T>, Utils::Quaternion<U>> {
207 using type = std::common_type_t<T, U>;
208};
209
210template <typename T, typename U, std::size_t N>
211struct deduce_scalar<Utils::Quaternion<T>, Utils::Vector<U, N>> {
212 using type = std::common_type_t<T, U>;
213};
214
215template <typename T, typename U>
216struct deduce_vec2<Utils::Quaternion<T>, Utils::Vector<U, 3>, 3> {
218};
219
220template <typename T> struct deduce_quat<Utils::Quaternion<T>> {
221 using type = typename Utils::Quaternion<T>;
222};
223
224template <typename T, typename U>
225struct deduce_quat2<Utils::Quaternion<T>, Utils::Quaternion<U>> {
227};
228
229} // namespace qvm
230
231} // namespace boost
232
234UTILS_ARRAY_BOOST_BIT_S(Utils::Quaternion, 0)
235UTILS_ARRAY_BOOST_CLASS(Utils::Quaternion, 0, object_serializable)
236UTILS_ARRAY_BOOST_TRACK(Utils::Quaternion, 0, track_never)
237
238#endif // SRC_UTILS_INCLUDE_UTILS_QUATERNION_HPP
Array implementation with CUDA support.
Vector implementation and trait types for boost qvm interoperability.
#define UTILS_ARRAY_BOOST_MPI_T(Container, N)
Mark array types as MPI data types.
Definition array.hpp:50
#define UTILS_ARRAY_BOOST_BIT_S(Container, N)
Mark array types as MPI bitwise serializable.
Definition array.hpp:63
#define UTILS_ARRAY_BOOST_CLASS(Container, N, ImplementationLevel)
Redefinition of BOOST_CLASS_IMPLEMENTATION for array types.
Definition array.hpp:78
#define UTILS_ARRAY_BOOST_TRACK(Container, N, TrackingLevel)
Redefinition of BOOST_CLASS_TRACKING for array types.
Definition array.hpp:97
Matrix implementation and trait types for boost qvm interoperability.
Quaternion< T > operator*(const U &b, const Quaternion< T > &a)
Product quaternion and arithmetic type.
Matrix< T, 3, 3 > rotation_matrix(Quaternion< T > const &q)
Convert quaternion to rotation matrix.
Matrix representation with static size.
Definition matrix.hpp:65
Quaternion representation.
typename container::const_pointer const_pointer
constexpr pointer data()
Access to the underlying data (non const).
typename container::pointer pointer
typename Utils::Array< T, 4 > container
static Quaternion< T > zero()
Construct a zero quaternion.
static Quaternion< T > identity()
Construct an identity quaternion.
value_type norm2() const
Retrieve the square of the norm of the quaternion.
Quaternion< T > normalized() const
Retrieve a normalized copy of the quaternion.
reference operator[](std::size_t i)
Element access (non const).
typename container::reference reference
value_type operator[](std::size_t i) const
Element access (const).
void normalize()
Normalize the quaternion in place.
typename container::value_type value_type
friend class boost::serialization::access
constexpr const_pointer data() const noexcept
Access to the underlying data (const).
value_type norm() const
Retrieve the norm of the quaternion.
typename Utils::Quaternion< std::common_type_t< T, U > > type
typename Utils::Vector< std::common_type_t< T, U >, 3 > type
static scalar_type read_element_idx(std::size_t i, quat_type const &q)
static scalar_type & write_element_idx(std::size_t i, quat_type &q)
static constexpr scalar_type & write_element(quat_type &q)
static constexpr scalar_type read_element(quat_type const &q)