diff --git a/src/core/math/Matrix3.h b/src/core/math/Matrix3.h
index 31f129e7db42db8e9e1c2249f265fec8f2d4d105..8706833ae539070102d9258ece6c8faecf1016e1 100644
--- a/src/core/math/Matrix3.h
+++ b/src/core/math/Matrix3.h
@@ -1693,6 +1693,25 @@ inline const Matrix3<Type> fabs( const Matrix3<Type>& m )
 //**********************************************************************************************************************
 
 
+//**********************************************************************************************************************
+/*!\fn bool math::isinf( const Matrix3<Type>& m )
+// \brief Checks the given matrix for infinite elements.
+//
+// \param m The matrix to be checked for infinite elements.
+// \return \a true if at least one element of the matrix is infinite, \a false otherwise.
+*/
+template< typename Type >
+inline bool isinf( const Matrix3<Type>& m )
+{
+   if( math::isinf( m[0] ) || math::isinf( m[1] ) || math::isinf( m[2] ) ||
+       math::isinf( m[3] ) || math::isinf( m[4] ) || math::isinf( m[5] ) ||
+       math::isinf( m[6] ) || math::isinf( m[7] ) || math::isinf( m[8] ) )
+      return true;
+   else return false;
+}
+//**********************************************************************************************************************
+
+
 //**********************************************************************************************************************
 // \brief Calculates the tensor product of two vectors.
 //**********************************************************************************************************************
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp b/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
index a41604b65475396c36708b3dfaa03ff6f5659086..aa6eb1c8a862199bb9e5d9a9321d437cb6cfcfe1 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
@@ -90,14 +90,15 @@ void ConvexPolyhedron::init( const Vec3& gpos, const Vec3& rpos, const Quat& q,
    q_      = q;                      // Setting the orientation
    R_      = q_.toRotationMatrix();  // Setting the rotation matrix
 
-                                     // Calculating the ConvexPolyhedron mass
-   mass_    = getVolume() * Material::getDensity( getMaterial() );
-
-   // Calculating the moment of inertia
-   calcInertia();
-
    setGlobal( global );
-   setMass( infiniteMass ); // sets inverse mass and interatio tensor
+   if (infiniteMass)
+   {
+      setMassAndInertiaToInfinity();
+   } else
+   {
+      // sets inverse mass and interatio tensor
+      setMassAndInertia( getVolume() * Material::getDensity( getMaterial() ), mesh::computeIntertiaTensor( mesh_ ) );
+   }
    setCommunicating( communicating );
    setFinite( true );
 
@@ -159,17 +160,6 @@ void ConvexPolyhedron::calcBoundingBox()
 }
 //*************************************************************************************************
 
-//*************************************************************************************************
-/*!\brief Calculation of the moment of inertia in reference to the body frame of the ConvexPolyhedron.
- *
- * \return void
- */
-void ConvexPolyhedron::calcInertia()
-{
-   I_ = mesh::computeIntertiaTensor( mesh_ );
-}
-//*************************************************************************************************
-
 
 //*************************************************************************************************
 /*!\brief Calculation of the volume of the ConvexPolyhedron.
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedron.h b/src/mesh/pe/rigid_body/ConvexPolyhedron.h
index 33ff28ac9fcaf613a196d7fc90fca7f6f7499f21..46e95afbda14c17c679ec2f34e98b8041387b8fc 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedron.h
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedron.h
@@ -127,7 +127,6 @@ protected:
    /*!\name Utility functions */
    //@{
    virtual void calcBoundingBox();  // Calculation of the axis-aligned bounding box
-           void calcInertia();      // Calculation of the moment of inertia
    virtual TriangleMesh::VertexHandle supportVertex( const TriangleMesh::Normal & d, const TriangleMesh::VertexHandle startVertex ) const;
    //@}
    //**********************************************************************************************
diff --git a/src/pe/cr/HCSITS.impl.h b/src/pe/cr/HCSITS.impl.h
index 45ed1e1ddd7f22c5a3f69ee9a5dbeb6a6bf273d8..a67882dc306140900bc9c02cb840fce0019b5ae9 100644
--- a/src/pe/cr/HCSITS.impl.h
+++ b/src/pe/cr/HCSITS.impl.h
@@ -288,7 +288,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
       for( auto body = globalBodyStorage_->begin(); body != globalBodyStorage_->end(); ++body, ++j ) {
          body->wake(); // BUGFIX: Force awaking of all bodies!
          body->index_ = j;
-         WALBERLA_ASSERT( body->hasInfiniteMass(), "fatal" );
+         WALBERLA_CHECK( body->hasInfiniteMass(), "Global bodies need to have infinite mass as they are not communicated!" );
 
          initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity
 
@@ -347,7 +347,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
       for( auto body = globalBodyStorage_->begin(); body != globalBodyStorage_->end(); ++body, ++j ) {
          body->wake(); // BUGFIX: Force awaking of all bodies!
          body->index_ = j;
-         WALBERLA_ASSERT( body->hasInfiniteMass(), "fatal" );
+         WALBERLA_CHECK( body->hasInfiniteMass(), "Global bodies need to have infinite mass as they are not communicated!" );
 
          initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity
 
diff --git a/src/pe/rigidbody/Box.cpp b/src/pe/rigidbody/Box.cpp
index 417af0f24293989aee22a9f84499cde30f8d8a6e..ffd27fc8ebc5639cf5f6ad794c3e45c22fee8a5a 100644
--- a/src/pe/rigidbody/Box.cpp
+++ b/src/pe/rigidbody/Box.cpp
@@ -75,15 +75,15 @@ Box::Box( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
    q_      = q;                      // Setting the orientation
    R_      = q_.toRotationMatrix();  // Setting the rotation matrix
 
-   // Calculating the sphere mass
-   mass_ = calcMass( lengths, Material::getDensity( material ) );
-   invMass_ = real_c(1) / mass_;
-
-   // Calculating the moment of inertia
-   calcInertia();
-
    setGlobal( global );
-   setMass( infiniteMass );
+   if (infiniteMass)
+   {
+      setMassAndInertiaToInfinity();
+   } else
+   {
+      auto mass = calcMass( lengths, Material::getDensity( material ) );
+      setMassAndInertia( mass, calcInertia( lengths, mass ) );
+   }
    setCommunicating( communicating );
    setFinite( true );
 
@@ -130,8 +130,8 @@ Box::~Box()
 bool Box::containsRelPointImpl( real_t px, real_t py, real_t pz ) const
 {
    return std::fabs(px) <= real_t(0.5)*lengths_[0] &&
-          std::fabs(py) <= real_t(0.5)*lengths_[1] &&
-          std::fabs(pz) <= real_t(0.5)*lengths_[2];
+         std::fabs(py) <= real_t(0.5)*lengths_[1] &&
+         std::fabs(pz) <= real_t(0.5)*lengths_[2];
 }
 //*************************************************************************************************
 
@@ -307,7 +307,7 @@ void Box::calcBoundingBox()
    const real_t ylength( real_t(0.5) * ( fabs(R_[3]*lengths_[0]) + fabs(R_[4]*lengths_[1]) + fabs(R_[5]*lengths_[2]) ) + contactThreshold );
    const real_t zlength( real_t(0.5) * ( fabs(R_[6]*lengths_[0]) + fabs(R_[7]*lengths_[1]) + fabs(R_[8]*lengths_[2]) ) + contactThreshold );
    aabb_ = math::AABB(
-         gpos_[0] - xlength,
+            gpos_[0] - xlength,
          gpos_[1] - ylength,
          gpos_[2] - zlength,
          gpos_[0] + xlength,
@@ -326,12 +326,12 @@ void Box::calcBoundingBox()
  *
  * \return void
  */
-void Box::calcInertia()
+Mat3 Box::calcInertia(const Vec3& length, const real_t mass)
 {
-   I_[0] = mass_/static_cast<real_t>( 12 ) * ( lengths_[1]*lengths_[1] + lengths_[2]*lengths_[2] );
-   I_[4] = mass_/static_cast<real_t>( 12 ) * ( lengths_[0]*lengths_[0] + lengths_[2]*lengths_[2] );
-   I_[8] = mass_/static_cast<real_t>( 12 ) * ( lengths_[0]*lengths_[0] + lengths_[1]*lengths_[1] );
-   Iinv_ = I_.getInverse();
+   return Mat3::makeDiagonalMatrix(
+            mass/static_cast<real_t>( 12 ) * ( length[1]*length[1] + length[2]*length[2] ),
+         mass/static_cast<real_t>( 12 ) * ( length[0]*length[0] + length[2]*length[2] ),
+         mass/static_cast<real_t>( 12 ) * ( length[0]*length[0] + length[1]*length[1] ));
 }
 //*************************************************************************************************
 
diff --git a/src/pe/rigidbody/Box.h b/src/pe/rigidbody/Box.h
index b76ab998319134bdb84faacaade1c192ea4543e0..cd6ab866230a6fc09d0bbb14b49eed97a34e43c3 100644
--- a/src/pe/rigidbody/Box.h
+++ b/src/pe/rigidbody/Box.h
@@ -96,6 +96,7 @@ public:
    static inline real_t calcMass( const Vec3& l, real_t density );
    static inline real_t calcDensity( real_t x, real_t y, real_t z, real_t mass );
    static inline real_t calcDensity( const Vec3& l, real_t mass );
+   static inline Mat3   calcInertia( const Vec3& length, const real_t mass);      // Calculation of the moment of inertia
    //@}
    //**********************************************************************************************
 
@@ -143,7 +144,6 @@ protected:
    /*!\name Utility functions */
    //@{
    virtual void calcBoundingBox();  // Calculation of the axis-aligned bounding box
-           void calcInertia();      // Calculation of the moment of inertia
    //@}
    //**********************************************************************************************
 
diff --git a/src/pe/rigidbody/Capsule.cpp b/src/pe/rigidbody/Capsule.cpp
index 0a99487ef92f44a3b7b25134765727dfc994d501..7b58b0ce64b744bd31657b8cd63e93863fc9603d 100644
--- a/src/pe/rigidbody/Capsule.cpp
+++ b/src/pe/rigidbody/Capsule.cpp
@@ -75,15 +75,15 @@ Capsule::Capsule( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const
    q_      = q;                      // Setting the orientation
    R_      = q_.toRotationMatrix();  // Setting the rotation matrix
 
-   // Calculating the capsule mass
-   mass_ = radius*radius * math::M_PI * ( real_t(4)/real_t(3) * radius + length ) * Material::getDensity( material );
-   invMass_ = real_t(1) / mass_;
-
-   // Calculating the moment of inertia
-   calcInertia();
-
    setGlobal( global );
-   setMass( infiniteMass );
+   if (infiniteMass)
+   {
+      setMassAndInertiaToInfinity();
+   } else
+   {
+      auto mass = calcMass( radius, length, Material::getDensity( material ) );
+      setMassAndInertia( mass, calcInertia( radius, length, Material::getDensity( material )  ) );
+   }
    setCommunicating( communicating );
    setFinite( true );
 
@@ -192,29 +192,25 @@ void Capsule::calcBoundingBox()
  *
  * \return void
  */
-void Capsule::calcInertia()
+Mat3 Capsule::calcInertia( const real_t radius, const real_t length, const real_t density)
 {
-   const real_t  density( calcDensity( radius_, length_, mass_ ) );
-   const real_t  sphereMass( real_t (4)/real_t (3) * math::M_PI * radius_*radius_*radius_ * density );
-   const real_t  cylinderMass( math::M_PI * radius_*radius_ * length_ * density );
+   const real_t  sphereMass( real_t (4)/real_t (3) * math::M_PI * radius*radius*radius * density );
+   const real_t  cylinderMass( math::M_PI * radius*radius * length * density );
 
    // 'Ia' represent the moment of inertia along the x-axis. 'Ia' contains the following two parts:
    //  - cylinder :  I = (1/2)*mass*radius^2
    //  - sphere   :  I = (2/5)*mass*radius^2
-   const real_t  Ia( radius_*radius_ * ( real_t (0.5)*cylinderMass + real_t (0.4)*sphereMass ) );
+   const real_t  Ia( radius*radius * ( real_t (0.5)*cylinderMass + real_t (0.4)*sphereMass ) );
 
    // 'Ib' represent the moment of inertia along the y- and z-axis. 'Ib' contains the following two parts,
    // where full_length is the full length of the cylinder part and half_length is (1/2)*full_length:
    //  - cylinder :  I = mass*( (1/4)*radius^2 + (1/12)*full_length^2 )
    //  - sphere   :  I = mass*( (2/5)*radius^2 + half_length^2 + (3/4)*half_length*radius )
-   const real_t  Ib( cylinderMass*( real_t (0.25)*radius_*radius_ + real_t (1)/real_t (12)*length_*length_ ) +
-                     sphereMass*( real_t (0.4)*radius_*radius_ + real_t (0.375)*radius_*length_ + real_t (0.25)*length_*length_ ) );
+   const real_t  Ib( cylinderMass*( real_t (0.25)*radius*radius + real_t (1)/real_t (12)*length*length ) +
+                     sphereMass*( real_t (0.4)*radius*radius + real_t (0.375)*radius*length + real_t (0.25)*length*length ) );
 
    // Setting the moment of inertia (capsule is aligned along the x-axis)
-   I_[0] = Ia;
-   I_[4] = Ib;
-   I_[8] = Ib;
-   Iinv_ = I_.getInverse();
+   return Mat3::makeDiagonalMatrix(Ia, Ib, Ib);
 }
 //*************************************************************************************************
 
diff --git a/src/pe/rigidbody/Capsule.h b/src/pe/rigidbody/Capsule.h
index 3be8e04530f9b725e2831de746ba8c1875143b98..55070d0224f835f8870f1be99e3eb432f936a6e0 100644
--- a/src/pe/rigidbody/Capsule.h
+++ b/src/pe/rigidbody/Capsule.h
@@ -106,6 +106,7 @@ public:
    static inline real_t  calcVolume( real_t  radius, real_t  length );
    static inline real_t  calcMass( real_t  radius, real_t  length, real_t  density );
    static inline real_t  calcDensity( real_t  radius, real_t  length, real_t  mass );
+   static        Mat3    calcInertia( const real_t radius, const real_t length, const real_t density);
    //@}
    //**********************************************************************************************
 
@@ -139,7 +140,6 @@ protected:
    /*!\name Utility functions */
    //@{
    virtual void calcBoundingBox();  // Calculation of the axis-aligned bounding box
-   void calcInertia();      // Calculation of the moment of inertia
    //@}
    //**********************************************************************************************
 
diff --git a/src/pe/rigidbody/CylindricalBoundary.cpp b/src/pe/rigidbody/CylindricalBoundary.cpp
index 1a96385517c916ce10aafe20132d840269aa5178..6b99c946384f11f2ecc5cd9f3d88a4e65956622d 100644
--- a/src/pe/rigidbody/CylindricalBoundary.cpp
+++ b/src/pe/rigidbody/CylindricalBoundary.cpp
@@ -61,7 +61,7 @@ CylindricalBoundary::CylindricalBoundary( id_t sid, id_t uid, const Vec3& gpos,
    //boundaries are always considered locally and have infinite mass
    setGlobal( true );
    setCommunicating( false );
-   setMass( true );
+   setMassAndInertiaToInfinity();
    setFinite( false );
 
    // Checking the radius
diff --git a/src/pe/rigidbody/Ellipsoid.cpp b/src/pe/rigidbody/Ellipsoid.cpp
index c3a0b6bb8c4c48b745b1f7db34511d96fb7af0eb..3c68d587590468955490f1b60f362f3fbe882007 100644
--- a/src/pe/rigidbody/Ellipsoid.cpp
+++ b/src/pe/rigidbody/Ellipsoid.cpp
@@ -84,15 +84,15 @@ Ellipsoid::Ellipsoid( id_t const typeId, id_t sid, id_t uid, const Vec3& gpos, c
    q_      = q;                      // Setting the orientation
    R_      = q_.toRotationMatrix();  // Setting the rotation matrix
 
-   // Calculating the Ellipsoid mass
-   mass_ = calcMass(semiAxes_, Material::getDensity( material ));
-   invMass_ = real_c(1) / mass_;
-
-   // Calculating the moment of inertia
-   calcInertia();
-
    setGlobal( global );
-   setMass( infiniteMass );
+   if (infiniteMass)
+   {
+      setMassAndInertiaToInfinity();
+   } else
+   {
+      auto mass = calcMass( semiAxes, Material::getDensity( material ) );
+      setMassAndInertia( mass, calcInertia( mass, semiAxes ) );
+   }
    setCommunicating( communicating );
    setFinite( true );
 
diff --git a/src/pe/rigidbody/Ellipsoid.h b/src/pe/rigidbody/Ellipsoid.h
index f2baad173f8f64029055721511af7c220a06e400..e723bc1b9e5cdbe70530b500c2a7459381e1ddd9 100644
--- a/src/pe/rigidbody/Ellipsoid.h
+++ b/src/pe/rigidbody/Ellipsoid.h
@@ -55,8 +55,8 @@ namespace pe {
  * \brief Base class for the Ellipsoid geometry.
  *
  * The Ellipsoid class represents the base class for the Ellipsoid geometry. It provides
- * the basic functionality of a Ellipsoid. An Ellipsoid is obtained from a sphere by deforming it by means 
- * of directional scalings. Its three semi-axes corresponding to the x, y, z direction are labeled 
+ * the basic functionality of a Ellipsoid. An Ellipsoid is obtained from a sphere by deforming it by means
+ * of directional scalings. Its three semi-axes corresponding to the x, y, z direction are labeled
  * a, b, c.
  */
 class Ellipsoid : public GeomPrimitive
@@ -66,11 +66,11 @@ public:
    /*!\name Constructors */
    //@{
    explicit Ellipsoid( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
-                    const Vec3& semiAxes, MaterialID material,
-                    const bool global, const bool communicating, const bool infiniteMass );
+                       const Vec3& semiAxes, MaterialID material,
+                       const bool global, const bool communicating, const bool infiniteMass );
    explicit Ellipsoid( id_t const typeID, id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
-                    const Vec3& semiAxes, MaterialID material,
-                    const bool global, const bool communicating, const bool infiniteMass );
+                       const Vec3& semiAxes, MaterialID material,
+                       const bool global, const bool communicating, const bool infiniteMass );
    //@}
    //**********************************************************************************************
 
@@ -116,6 +116,7 @@ public:
    static inline real_t calcVolume( const Vec3& semiAxes );
    static inline real_t calcMass( const Vec3& semiAxes, real_t density );
    static inline real_t calcDensity( const Vec3& semiAxes, real_t mass );
+   static inline Mat3   calcInertia( const real_t mass, const Vec3& semiAxes );
    //@}
    //**********************************************************************************************
 
@@ -132,7 +133,6 @@ protected:
    /*!\name Utility functions */
    //@{
    inline virtual void calcBoundingBox();  // Calculation of the axis-aligned bounding box
-   inline         void calcInertia();      // Calculation of the moment of inertia
    //@}
    //**********************************************************************************************
 
@@ -140,7 +140,7 @@ protected:
    /*!\name Member variables */
    //@{
    Vec3 semiAxes_;  //!< Semi-axes of the Ellipsoid.
-                  /*!< The radius is constrained to values larger than 0.0. */
+   /*!< The radius is constrained to values larger than 0.0. */
    //@}
    //**********************************************************************************************
 private:
@@ -264,14 +264,14 @@ inline void Ellipsoid::calcBoundingBox()
    const real_t ylength( fabs(R_[3]*semiAxes_[0]) + fabs(R_[4]*semiAxes_[1]) + fabs(R_[5]*semiAxes_[2])  + contactThreshold );
    const real_t zlength( fabs(R_[6]*semiAxes_[0]) + fabs(R_[7]*semiAxes_[1]) + fabs(R_[8]*semiAxes_[2])  + contactThreshold );
    aabb_ = math::AABB(
-         gpos_[0] - xlength,
+            gpos_[0] - xlength,
          gpos_[1] - ylength,
          gpos_[2] - zlength,
          gpos_[0] + xlength,
          gpos_[1] + ylength,
          gpos_[2] + zlength
          );
-	//   WALBERLA_ASSERT( aabb_.isValid()        , "Invalid bounding box detected" );
+   //   WALBERLA_ASSERT( aabb_.isValid()        , "Invalid bounding box detected" );
    WALBERLA_ASSERT( aabb_.contains( gpos_ ), "Invalid bounding box detected("<< getSystemID() <<")\n" << "pos: " << gpos_ << "\nlengths: " << xlength << "," << ylength << ", " << zlength<< "\nvel: " << getLinearVel() << "\nbox: " << aabb_ );
 }
 //*************************************************************************************************
@@ -282,12 +282,12 @@ inline void Ellipsoid::calcBoundingBox()
  *
  * \return void
  */
-inline void Ellipsoid::calcInertia()
+inline Mat3 Ellipsoid::calcInertia( const real_t mass, const Vec3& semiAxes )
 {
-   I_[0] = real_c(0.2) * mass_ * (semiAxes_[1] * semiAxes_[1] + semiAxes_[2] * semiAxes_[2]);
-   I_[4] = real_c(0.2) * mass_ * (semiAxes_[2] * semiAxes_[2] + semiAxes_[0] * semiAxes_[0]);
-   I_[8] = real_c(0.2) * mass_ * (semiAxes_[0] * semiAxes_[0] + semiAxes_[1] * semiAxes_[1]);
-   Iinv_ = I_.getInverse();
+   return Mat3::makeDiagonalMatrix(
+            real_c(0.2) * mass * (semiAxes[1] * semiAxes[1] + semiAxes[2] * semiAxes[2]),
+            real_c(0.2) * mass * (semiAxes[2] * semiAxes[2] + semiAxes[0] * semiAxes[0]),
+            real_c(0.2) * mass * (semiAxes[0] * semiAxes[0] + semiAxes[1] * semiAxes[1]));
 }
 //*************************************************************************************************
 
@@ -303,11 +303,11 @@ inline Vec3 Ellipsoid::support( const Vec3& d ) const
    auto len = d.sqrLength();
    if (!math::equal(len, real_t(0)))
    {
-	  Vec3 d_loc = vectorFromWFtoBF(d);
-	  Vec3 norm_vec(d_loc[0] * semiAxes_[0], d_loc[1] * semiAxes_[1], d_loc[2] * semiAxes_[2]);
-	  real_t norm_length = norm_vec.length();
-	  Vec3 local_support = (real_t(1.0) / norm_length) * Vec3(semiAxes_[0] * semiAxes_[0] * d_loc[0], 
-			semiAxes_[1] * semiAxes_[1] * d_loc[1], semiAxes_[2] * semiAxes_[2] * d_loc[2]);
+      Vec3 d_loc = vectorFromWFtoBF(d);
+      Vec3 norm_vec(d_loc[0] * semiAxes_[0], d_loc[1] * semiAxes_[1], d_loc[2] * semiAxes_[2]);
+      real_t norm_length = norm_vec.length();
+      Vec3 local_support = (real_t(1.0) / norm_length) * Vec3(semiAxes_[0] * semiAxes_[0] * d_loc[0],
+            semiAxes_[1] * semiAxes_[1] * d_loc[1], semiAxes_[2] * semiAxes_[2] * d_loc[2]);
       return pointFromBFtoWF(local_support);
    } else
    {
diff --git a/src/pe/rigidbody/Plane.cpp b/src/pe/rigidbody/Plane.cpp
index ffb6c91a0690eaabb52bb7c45199b0255506deb3..872edbe3e2a7a6ab3324204ae1e12ee4984878b8 100644
--- a/src/pe/rigidbody/Plane.cpp
+++ b/src/pe/rigidbody/Plane.cpp
@@ -71,14 +71,14 @@ Plane::Plane( id_t sid, id_t uid,
    //planes are always considered locally and have infinite mass
    setGlobal( true );
    setCommunicating( false );
-   setMass( true );
+   setMassAndInertiaToInfinity();
    setFinite( false );
 
    // Checking the mass properties of the plane
-   WALBERLA_ASSERT_FLOAT_EQUAL( mass_    , real_c(0), "Mass of plane is not 0" );
+   WALBERLA_ASSERT            ( std::isinf(mass_), "Mass of plane is not infinity" );
    WALBERLA_ASSERT_FLOAT_EQUAL( invMass_ , real_c(0), "Inverse mass of plane is not 0" );
-   WALBERLA_ASSERT( I_       == Mat3(real_c(0)), "Moment of inertia of plane is not 0\n" << I_ );
-   WALBERLA_ASSERT( Iinv_    == Mat3(real_c(0)), "Inverse moment of inertia of plane is not 0" );
+   WALBERLA_ASSERT            ( isinf(I_), "Moment of inertia of plane is not infinity\n" << I_ );
+   WALBERLA_ASSERT_FLOAT_EQUAL( Iinv_    , Mat3(real_c(0)), "Inverse moment of inertia of plane is not 0" );
 
    // Checking the plane normal
    // Since the plane constructor is never directly called but only used in a small number
diff --git a/src/pe/rigidbody/PlaneFactory.cpp b/src/pe/rigidbody/PlaneFactory.cpp
index f1bee615c9e357991f8ba4a8819c6896a41b4cab..2f780a12a1d1377fcf72b283d082e0e3a1320884 100644
--- a/src/pe/rigidbody/PlaneFactory.cpp
+++ b/src/pe/rigidbody/PlaneFactory.cpp
@@ -46,9 +46,6 @@ PlaneID createPlane( BodyStorage& globalStorage, id_t uid, Vec3 normal, const Ve
 
    PlaneID plane = new Plane( sid, uid, gpos, normal, normal*gpos, material );
 
-   plane->setCommunicating( false );
-   plane->setMass( true );
-
    globalStorage.add(plane);
 
    // Logging the successful creation of the plane
diff --git a/src/pe/rigidbody/RigidBody.h b/src/pe/rigidbody/RigidBody.h
index 8627cf49698d946810e946dc3962b42035e30af8..d0cdbdb374d1489388c975cbd15baa6b88cb2945 100644
--- a/src/pe/rigidbody/RigidBody.h
+++ b/src/pe/rigidbody/RigidBody.h
@@ -166,12 +166,12 @@ public:
    inline  void resetSB() ;
 
    inline  void setFinite     ( const bool finite );
-   inline  void setMass       ( bool infinite );
    inline  void setVisible    ( bool visible );
    inline  void setPosition   ( real_t px, real_t py, real_t pz );
    inline  void setPosition   ( const Vec3& gpos );
    inline  void setOrientation( real_t r, real_t i, real_t j, real_t k );
    inline  void setOrientation( const Quat& q );
+   inline  void setMassAndInertiaToInfinity();
 
    inline void setRelLinearVel ( real_t vx, real_t vy, real_t vz );
    inline void setRelLinearVel ( const Vec3& lvel );
@@ -357,8 +357,10 @@ protected:
    virtual void rotateImpl            ( const Quat& dq );
    virtual void rotateAroundOriginImpl( const Quat& dq );
    virtual void rotateAroundPointImpl ( const Vec3& point, const Quat& dq );
-   virtual bool containsRelPointImpl   ( real_t px, real_t py, real_t pz ) const;
-   virtual bool isSurfaceRelPointImpl  ( real_t px, real_t py, real_t pz ) const;
+   virtual bool containsRelPointImpl  ( real_t px, real_t py, real_t pz ) const;
+   virtual bool isSurfaceRelPointImpl ( real_t px, real_t py, real_t pz ) const;
+
+   inline  void setMassAndInertia     ( const real_t mass, const Mat3& inertia );
 
    inline void calcRelPosition();
    //@}
@@ -706,7 +708,7 @@ inline bool RigidBody::isFixed() const
  */
 inline bool RigidBody::hasInfiniteMass() const
 {
-   return (isIdentical(invMass_, real_t(0))) && ( Iinv_.isZero() );
+   return std::isinf(getMass());
 }
 //*************************************************************************************************
 
@@ -2313,39 +2315,30 @@ inline void RigidBody::setFinite( const bool finite )
 
 
 //*************************************************************************************************
-/*!\brief Setting the global position (the center of mass) of the rigid body fixed.
- *
- * \return void
- *
- * This function either fixes the global position (the center of mass) of a finite
- * rigid body. If the body is contained in a superordinate body, fixing the contained
- * body will also fix the global position of the superordinate body.
- * Fixation is permanent and a fixed body cannot be unfixed anymore.
+/*!\brief Sets mass and inertia of a rigid body. Also calculates inverse values.
  *
- * In case of a <b>MPI parallel simulation</b>, changing the settings of a (local) rigid body
- * on one process may invalidate the settings of the rigid body on another process. In order to
- * synchronize all rigid bodies after local changes, the simulation has to be synchronized
- * by the user. Note that any changes on remote rigid
- * bodies are neglected and overwritten by the settings of the rigid body on its local process!
+ * \param mass mass to be set (may be infinity)
+ * \param inertia inertia to be set (if mass is infinity this one will be ignored)
  */
-inline void RigidBody::setMass( bool infinite )
+inline void RigidBody::setMassAndInertia( const real_t mass, const Mat3& inertia )
 {
-   if (infinite)
+   if ( std::isinf( mass ) )
    {
       // Adjusting the inverse mass and inverse moment of inertia
+      mass_    = std::numeric_limits<real_t>::infinity();
+      I_       = Mat3::makeDiagonalMatrix(std::numeric_limits<real_t>::infinity());
       invMass_ = real_c(0);
       Iinv_    = Mat3( real_c(0) );
-
-      // Setting the linear and angular velocity to zero
-      v_ = Vec3(0);
-      w_ = Vec3(0);
    } else
    {
       // Adjusting the inverse mass and inverse moment of inertia
+      mass_    = mass;
+      I_       = inertia;
       invMass_ = real_c(1) / mass_;
       Iinv_    = I_.getInverse();
    }
 
+   if (hasSuperBody()) WALBERLA_LOG_WARNING("Changing the mass of a body contained in a Union is currently untested!!!");
    // Signaling the fixation change to the superordinate body
    signalFixation();
 }
@@ -2555,6 +2548,19 @@ inline void RigidBody::setOrientation( const Quat& q )
 }
 //*************************************************************************************************
 
+//*************************************************************************************************
+/*!\fn void RigidBody::setMassAndInertiaToInfinity( )
+ * \brief Setting the mass to infinity. This will also make the inertia tensor infinite.
+ *
+ * \attention This cannot be undone!
+ */
+//*************************************************************************************************
+inline void RigidBody::setMassAndInertiaToInfinity()
+{
+   setMassAndInertia( std::numeric_limits<real_t>::infinity(), Mat3(std::numeric_limits<real_t>::infinity()) );
+}
+//*************************************************************************************************
+
 
 
 //=================================================================================================
@@ -3261,7 +3267,7 @@ inline Vec3 RigidBody::supportContactThreshold(const Vec3& /*d*/) const
 inline void RigidBody::fix()
 {
    setCommunicating( false );
-   setMass( true );
+   setMassAndInertia( getMass(), getInertia() );
 
    // Signaling the fixation change to the superordinate body
    signalFixation();
diff --git a/src/pe/rigidbody/Sphere.cpp b/src/pe/rigidbody/Sphere.cpp
index 8ea3a81a768d586f47ab77b3016cead0e6b85fb3..f4314e9bad63289046a92b42b073bc15d75a60bc 100644
--- a/src/pe/rigidbody/Sphere.cpp
+++ b/src/pe/rigidbody/Sphere.cpp
@@ -83,15 +83,15 @@ Sphere::Sphere( id_t const typeId, id_t sid, id_t uid, const Vec3& gpos, const V
    q_      = q;                      // Setting the orientation
    R_      = q_.toRotationMatrix();  // Setting the rotation matrix
 
-   // Calculating the sphere mass
-   mass_ = calcMass( radius, Material::getDensity( material ) );
-   invMass_ = real_c(1) / mass_;
-
-   // Calculating the moment of inertia
-   calcInertia();
-
    setGlobal( global );
-   setMass( infiniteMass );
+   if (infiniteMass)
+   {
+      setMassAndInertia( std::numeric_limits<real_t>::infinity(), Mat3(real_t(0)) );
+   } else
+   {
+      auto mass = calcMass( radius, Material::getDensity( material ) );
+      setMassAndInertia( mass, calcInertia( radius, mass ) );
+   }
    setCommunicating( communicating );
    setFinite( true );
 
@@ -194,20 +194,20 @@ void Sphere::print( std::ostream& os, const char* tab ) const
       << tab << "   Linear velocity   = " << getLinearVel() << "\n"
       << tab << "   Angular velocity  = " << getAngularVel() << "\n";
 
-//   if( verboseMode )
-//   {
-      os << tab << "   Bounding box      = " << getAABB() << "\n"
-         << tab << "   Quaternion        = " << getQuaternion() << "\n"
-         << tab << "   Rotation matrix   = ( " << setw(9) << R_[0] << " , " << setw(9) << R_[1] << " , " << setw(9) << R_[2] << " )\n"
-         << tab << "                       ( " << setw(9) << R_[3] << " , " << setw(9) << R_[4] << " , " << setw(9) << R_[5] << " )\n"
-         << tab << "                       ( " << setw(9) << R_[6] << " , " << setw(9) << R_[7] << " , " << setw(9) << R_[8] << " )\n";
-
-      os << std::setiosflags(std::ios::right)
-         << tab << "   Moment of inertia = ( " << setw(9) << I_[0] << " , " << setw(9) << I_[1] << " , " << setw(9) << I_[2] << " )\n"
-         << tab << "                       ( " << setw(9) << I_[3] << " , " << setw(9) << I_[4] << " , " << setw(9) << I_[5] << " )\n"
-         << tab << "                       ( " << setw(9) << I_[6] << " , " << setw(9) << I_[7] << " , " << setw(9) << I_[8] << " )\n"
-         << std::resetiosflags(std::ios::right);
-//   }
+   //   if( verboseMode )
+   //   {
+   os << tab << "   Bounding box      = " << getAABB() << "\n"
+      << tab << "   Quaternion        = " << getQuaternion() << "\n"
+      << tab << "   Rotation matrix   = ( " << setw(9) << R_[0] << " , " << setw(9) << R_[1] << " , " << setw(9) << R_[2] << " )\n"
+      << tab << "                       ( " << setw(9) << R_[3] << " , " << setw(9) << R_[4] << " , " << setw(9) << R_[5] << " )\n"
+      << tab << "                       ( " << setw(9) << R_[6] << " , " << setw(9) << R_[7] << " , " << setw(9) << R_[8] << " )\n";
+
+   os << std::setiosflags(std::ios::right)
+      << tab << "   Moment of inertia = ( " << setw(9) << I_[0] << " , " << setw(9) << I_[1] << " , " << setw(9) << I_[2] << " )\n"
+      << tab << "                       ( " << setw(9) << I_[3] << " , " << setw(9) << I_[4] << " , " << setw(9) << I_[5] << " )\n"
+      << tab << "                       ( " << setw(9) << I_[6] << " , " << setw(9) << I_[7] << " , " << setw(9) << I_[8] << " )\n"
+      << std::resetiosflags(std::ios::right);
+   //   }
 }
 //*************************************************************************************************
 
diff --git a/src/pe/rigidbody/Sphere.h b/src/pe/rigidbody/Sphere.h
index 536f7b7ce767e37ceac9cae875348dfce45b2ab8..d062e616c08c4770bb3533c232f8fd10e4dc8f24 100644
--- a/src/pe/rigidbody/Sphere.h
+++ b/src/pe/rigidbody/Sphere.h
@@ -125,6 +125,7 @@ public:
    static inline real_t calcVolume( real_t radius );
    static inline real_t calcMass( real_t radius, real_t density );
    static inline real_t calcDensity( real_t radius, real_t mass );
+   static inline Mat3   calcInertia( const real_t mass, const real_t radius );
    //@}
    //**********************************************************************************************
 
@@ -141,7 +142,6 @@ protected:
    /*!\name Utility functions */
    //@{
    inline virtual void calcBoundingBox();  // Calculation of the axis-aligned bounding box
-   inline         void calcInertia();      // Calculation of the moment of inertia
    //@}
    //**********************************************************************************************
 
@@ -287,10 +287,9 @@ inline void Sphere::calcBoundingBox()
  *
  * \return void
  */
-inline void Sphere::calcInertia()
+inline Mat3 Sphere::calcInertia( const real_t mass, const real_t radius )
 {
-   I_[0] = I_[4] = I_[8] = real_c(0.4) * mass_ * radius_ * radius_;
-   Iinv_ = I_.getInverse();
+   return Mat3::makeDiagonalMatrix( real_c(0.4) * mass * radius * radius );
 }
 //*************************************************************************************************
 
diff --git a/tests/pe/CheckVitalParameters.h b/tests/pe/CheckVitalParameters.h
index 424ef961278f839a79b251a7846d6599e4ac8d46..2349294e4278b6326cae5733c32666a800792e1c 100644
--- a/tests/pe/CheckVitalParameters.h
+++ b/tests/pe/CheckVitalParameters.h
@@ -41,10 +41,19 @@ inline void checkVitalParameters(SphereID bd1, SphereID bd2)
    WALBERLA_CHECK_FLOAT_EQUAL(bd1->getRotation(), bd2->getRotation());
    WALBERLA_CHECK_FLOAT_EQUAL(bd1->getAngularVel(), bd2->getAngularVel());
 
-   WALBERLA_CHECK_FLOAT_EQUAL(bd1->getMass(), bd2->getMass());
-   WALBERLA_CHECK_FLOAT_EQUAL(bd1->getInvMass(), bd2->getInvMass());
-   WALBERLA_CHECK_FLOAT_EQUAL(bd1->getInertia(), bd2->getInertia());
-   WALBERLA_CHECK_FLOAT_EQUAL(bd1->getInvInertia(), bd2->getInvInertia());
+   if (std::isinf(bd1->getMass()))
+   {
+      WALBERLA_CHECK            ( std::isinf(bd2->getMass()) );
+      WALBERLA_CHECK_FLOAT_EQUAL(bd1->getInvMass(), bd2->getInvMass());
+      WALBERLA_CHECK            ( math::isinf(bd1->getBodyInertia()) );
+      WALBERLA_CHECK            ( math::isinf(bd2->getBodyInertia()) );
+      WALBERLA_CHECK_FLOAT_EQUAL(bd1->getInvInertia(), bd2->getInvInertia());
+   } else {
+      WALBERLA_CHECK_FLOAT_EQUAL(bd1->getMass(), bd2->getMass());
+      WALBERLA_CHECK_FLOAT_EQUAL(bd1->getInvMass(), bd2->getInvMass());
+      WALBERLA_CHECK_FLOAT_EQUAL(bd1->getInertia(), bd2->getInertia());
+      WALBERLA_CHECK_FLOAT_EQUAL(bd1->getInvInertia(), bd2->getInvInertia());
+   }
 
    WALBERLA_CHECK_EQUAL(bd1->isGlobal(), bd2->isGlobal());
    WALBERLA_CHECK_EQUAL(bd1->hasInfiniteMass(), bd2->hasInfiniteMass());
diff --git a/tests/pe/Union.cpp b/tests/pe/Union.cpp
index 8d48dae60856923cd6d64f4a0f906c3b4efb5067..6cd0aec53e1e26b978b0085a67a04ae74b15fc0e 100644
--- a/tests/pe/Union.cpp
+++ b/tests/pe/Union.cpp
@@ -78,24 +78,26 @@ void SnowManFallingOnPlane()
    MaterialID iron = Material::find("iron");
    UnionType* un   = createUnion< boost::tuple<Sphere> >( *globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(5,5,5) );
    SphereID sp1 = new Sphere( 10, 0, Vec3(5,5,1), Vec3(0,0,0), Quat(), real_t(1)  , iron, false, true, false );
-   SphereID sp2 = new Sphere( 11, 0, Vec3(6,5,2), Vec3(0,0,0), Quat(), real_t(1.5), iron, false, true, false );
+   SphereID sp2 = new Sphere( 11, 0, Vec3(real_t(6.7),5,real_t(1.2)), Vec3(0,0,0), Quat(), real_t(1.1), iron, false, true, false );
    un->add(sp1);
    un->add(sp2);
 
-   auto vtkOutput   = make_shared<SphereVtkOutput>(storageID, forest->getBlockStorage()) ;
-   auto vtkWriter   = vtk::createVTKOutput_PointData(vtkOutput, "Bodies", 1, "vtk_out", "simulation_step", false, false);
+   auto distance = (sp1->getPosition() - sp2->getPosition()).length();
 
-   for (unsigned int i = 0; i < 10000; ++i)
+   //auto vtkOutput   = make_shared<SphereVtkOutput>(storageID, forest->getBlockStorage()) ;
+   //auto vtkWriter   = vtk::createVTKOutput_PointData(vtkOutput, "Bodies", 1, "vtk_out", "simulation_step", false, false);
+
+   for (unsigned int i = 0; i < 1000; ++i)
    {
-      vtkWriter->write( true );
-      cr.timestep( real_t(0.001) );
+      //vtkWriter->write( true );
+      cr.timestep( real_t(0.1) );
    }
 
    //WALBERLA_CHECK_FLOAT_EQUAL( sp1->getLinearVel().length(), real_t(0) );
    //WALBERLA_CHECK_FLOAT_EQUAL( sp2->getLinearVel().length(), real_t(0) );
    WALBERLA_CHECK_FLOAT_EQUAL_EPSILON( sp1->getPosition()[2], real_t(1)  , real_t(0.001) );
-   WALBERLA_CHECK_FLOAT_EQUAL_EPSILON( sp2->getPosition()[2], real_t(1.5), real_t(0.001) );
-   WALBERLA_CHECK_FLOAT_EQUAL( (sp1->getPosition() - sp2->getPosition()).length(), real_t(sqrt(2)) );
+   WALBERLA_CHECK_FLOAT_EQUAL_EPSILON( sp2->getPosition()[2], real_t(1.1), real_t(0.001) );
+   WALBERLA_CHECK_FLOAT_EQUAL( (sp1->getPosition() - sp2->getPosition()).length(), distance );
 
    //WALBERLA_LOG_DEVEL(un);
 }