From 018b6cd5ef02173b7bbab88a3e302365da535cbc Mon Sep 17 00:00:00 2001 From: Sebastian Eibl <sebastian.eibl@fau.de> Date: Wed, 7 Nov 2018 14:06:28 +0100 Subject: [PATCH] added Rot3 class and various free functions for vectors --- src/core/math/Quaternion.h | 4 +- src/core/math/Rot3.h | 124 +++++++++++++++++++++++++++++++++++++ src/core/math/Vector3.h | 57 +++++++++++++++++ src/core/mpi/RecvBuffer.h | 2 +- 4 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 src/core/math/Rot3.h diff --git a/src/core/math/Quaternion.h b/src/core/math/Quaternion.h index 4e531ea73..f6822daf3 100644 --- a/src/core/math/Quaternion.h +++ b/src/core/math/Quaternion.h @@ -36,6 +36,7 @@ #include "core/mpi/SendBuffer.h" #include "core/mpi/RecvBuffer.h" +#include <core/logging/Logging.h> #include <boost/type_traits/is_floating_point.hpp> #include <boost/type_traits/is_const.hpp> @@ -406,7 +407,8 @@ inline Type Quaternion<Type>::operator[]( size_t index ) const template< typename Type > // Data type of the quaternion inline Quaternion<Type>& Quaternion<Type>::set( Type r, Type i, Type j, Type k ) { - WALBERLA_CHECK_FLOAT_EQUAL( std::fabs( r*r + i*i + j*j + k*k ), Type(1), "Invalid quaternion parameters" ); + WALBERLA_CHECK_FLOAT_EQUAL( std::fabs( r*r + i*i + j*j + k*k ), Type(1), + "Invalid quaternion parameters: " << r << ", "<< i << ", "<< j << ", "<< k ); v_[0] = r; v_[1] = i; v_[2] = j; diff --git a/src/core/math/Rot3.h b/src/core/math/Rot3.h new file mode 100644 index 000000000..30b4952d6 --- /dev/null +++ b/src/core/math/Rot3.h @@ -0,0 +1,124 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file Rot3.h +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#pragma once + +#include <core/math/Matrix3.h> +#include <core/math/Quaternion.h> + +#include <type_traits> + +namespace walberla { +namespace math { + +/** + * Rotation class which merges quaternion and matrix representation. + * + * For numerical reasons the representation of a rotation via a quaternion + * is favourable. However application of the rotation to vectors and matrices + * is numerical more efficient with matrices. Therefore this class combines both + * representations and takes care that both are in sync. + */ +template <typename Type> // floating point type +class Rot3 +{ + //**Compile time checks************************************************************************* + /*! \cond internal */ + static_assert(std::is_floating_point<Type>::value, "T has to be floating point!"); + static_assert(!std::is_const<Type>::value, "T has to be non const!"); + static_assert(!std::is_volatile<Type>::value, "T has to be non volatile!"); + /*! \endcond */ + //********************************************************************************************** +public: + Rot3(const Quaternion<Type>& q); + + const Quaternion<Type>& getQuaternion() const { return quat_; } + const Matrix3<Type>& getMatrix() const { return mat_; } + + void rotate(const Quaternion<Type>& q); +private: + Quaternion<Type> quat_; + Matrix3<Type> mat_; +}; + +template< typename Type > // floating point type +inline Rot3<Type>::Rot3(const Quaternion<Type>& q) + : quat_(q) + , mat_ (q.toRotationMatrix()) +{ + WALBERLA_ASSERT_FLOAT_EQUAL( mat_.getDeterminant(), real_t(1), "Corrupted rotation matrix determinant" ); +} + +template< typename Type > // floating point type +inline void Rot3<Type>::rotate(const Quaternion<Type>& q) +{ + quat_ = q * quat_; + mat_ = quat_.toRotationMatrix(); + WALBERLA_ASSERT_FLOAT_EQUAL( mat_.getDeterminant(), real_t(1), "Corrupted rotation matrix determinant" ); +} + +template< typename Type > // floating point type +inline std::ostream& operator<<( std::ostream& os, const Rot3<Type>& r ) +{ + os << r.getMatrix(); + return os; +} + +} // math +} // walberla + +//====================================================================================================================== +// +// Send/Recv Buffer Serialization Specialization +// +//====================================================================================================================== + +namespace walberla { +namespace mpi { + +template< typename T, // Element type of SendBuffer + typename G, // Growth policy of SendBuffer + typename V > // value type +mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, const math::Rot3<V>& obj ) +{ + buf.addDebugMarker( "ro" ); + buf << obj.getQuaternion(); + return buf; +} + +template< typename T, // Element type of RecvBuffer + typename V > // value type +mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, math::Rot3<V>& objparam ) +{ + math::Quaternion<V> q; + buf.readDebugMarker( "ro" ); + buf >> q; + objparam = math::Rot3<V>(q); + return buf; +} + +template< typename V > // value type +struct BufferSizeTrait< math::Rot3<V> > { + static const bool constantSize = true; + static const uint_t size = BufferSizeTrait< math::Quaternion<V> >::size + mpi::BUFFER_DEBUG_OVERHEAD; +}; + +} // mpi +} // walberla diff --git a/src/core/math/Vector3.h b/src/core/math/Vector3.h index da90e4cfd..24485fef5 100644 --- a/src/core/math/Vector3.h +++ b/src/core/math/Vector3.h @@ -593,6 +593,21 @@ inline Vector3<HIGH> Vector3<Type>::operator%( const Vector3<Other>& rhs ) const //********************************************************************************************************************** +//********************************************************************************************************************** +/*!\brief Cross product (outer product) of two vectors (\f$ \vec{a}=\vec{b}\times\vec{c} \f$). +// +// \param lhs The left-hand-side vector for the cross product. +// \param rhs The right-hand-side vector for the cross product. +// \return The cross product. +*/ +template< typename Type > +inline Vector3<Type> cross( const Vector3<Type>& lhs, const Vector3<Type>& rhs ) +{ + return lhs % rhs; +} +//********************************************************************************************************************** + + //********************************************************************************************************************** /*!\fn Vector3<HIGH> Vector3<Type>::operator+( const Vector3<Other>& rhs ) const // \brief Addition operator for the addition of two vectors (\f$ \vec{a}=\vec{b}+\vec{c} \f$). @@ -699,6 +714,13 @@ inline Vector3<HIGH> Vector3<Type>::operator/( Other rhs ) const } //********************************************************************************************************************** +template< typename Type, typename Other > +inline Vector3<HIGH> operator/( Other lhs, const Vector3<Type>& rhs ) +{ + return Vector3<HIGH>( lhs/rhs[0], lhs/rhs[1], lhs/rhs[2] ); +} +//********************************************************************************************************************** + //====================================================================================================================== // @@ -1743,6 +1765,41 @@ Vector3<T> & normalize( Vector3<T> & v ) } //********************************************************************************************************************** +//********************************************************************************************************************** +/** +// \brief Length of the vector. +// +// \return Length of the vector. +*/ +template<typename T> +real_t length( const Vector3<T> & v ) +{ + return v.length(); +} +//********************************************************************************************************************** +//********************************************************************************************************************** +/** +// \brief Length of the vector squared. +// +// \return Length of the vector squared. +*/ +template<typename T> +real_t sqrLength( const Vector3<T> & v ) +{ + return v.sqrLength(); +} +//********************************************************************************************************************** +//********************************************************************************************************************** +/** +// \brief Dot product of two vectors. +*/ +template<typename T> +real_t dot( const Vector3<T> & v1, const Vector3<T> & v2 ) +{ + return v1*v2; +} +//********************************************************************************************************************** + //********************************************************************************************************************** /** diff --git a/src/core/mpi/RecvBuffer.h b/src/core/mpi/RecvBuffer.h index 3caa764b7..19d45825e 100644 --- a/src/core/mpi/RecvBuffer.h +++ b/src/core/mpi/RecvBuffer.h @@ -655,7 +655,7 @@ inline void GenericRecvBuffer<T>::readDebugMarker( const char * expectedMarker ) valid = false; } - WALBERLA_ASSERT( valid , "Packed and unpacked datatype do not match." ); + WALBERLA_ASSERT( valid , "Packed and unpacked (" << expectedMarker << ") datatype do not match." ); } #else -- GitLab