From f0a69f7da7784ffd1e7c74136073c181de28f8e0 Mon Sep 17 00:00:00 2001
From: Tobias Leemann <tobias.leemann@fau.de>
Date: Wed, 10 Jul 2019 13:35:21 +0200
Subject: [PATCH] [API] Union redesign

[API] removed rpos from all body constructors

Changes: Bodies that are part of a union now store all attributes relative to its respective coordinate frame. This affects gpos and q (Rotation), which are implicitly relative once a body becomes part of the union. These properties became private and the global Position can be accessed via getGlobalPos() which performs a recursive calcuation of the position of this body in the world frame. This avoids error-prone update procedures, if a Union is tranlated or rotated.
---
 src/mesh/pe/communication/ConvexPolyhedron.h  |   2 +-
 src/mesh/pe/rigid_body/ConvexPolyhedron.cpp   |  39 +-
 src/mesh/pe/rigid_body/ConvexPolyhedron.h     |   4 +-
 .../pe/rigid_body/ConvexPolyhedronFactory.cpp |   4 +-
 src/pe/communication/Marshalling.cpp          |  10 -
 src/pe/communication/Marshalling.h            |   2 +-
 src/pe/communication/rigidbody/Box.h          |   2 +-
 src/pe/communication/rigidbody/Capsule.h      |   2 +-
 src/pe/communication/rigidbody/Ellipsoid.h    |   2 +-
 src/pe/communication/rigidbody/Sphere.h       |   2 +-
 src/pe/communication/rigidbody/Squirmer.h     |   2 +-
 src/pe/communication/rigidbody/Union.h        |   7 +-
 src/pe/rigidbody/Box.cpp                      |  38 +-
 src/pe/rigidbody/Box.h                        |   4 +-
 src/pe/rigidbody/BoxFactory.cpp               |   4 +-
 src/pe/rigidbody/Capsule.cpp                  |  39 +-
 src/pe/rigidbody/Capsule.h                    |  24 +-
 src/pe/rigidbody/CapsuleFactory.cpp           |   4 +-
 src/pe/rigidbody/CylindricalBoundary.cpp      |  15 +-
 src/pe/rigidbody/Ellipsoid.cpp                |  23 +-
 src/pe/rigidbody/Ellipsoid.h                  |  27 +-
 src/pe/rigidbody/EllipsoidFactory.cpp         |   4 +-
 src/pe/rigidbody/Plane.cpp                    | 169 ++------
 src/pe/rigidbody/Plane.h                      |   8 -
 src/pe/rigidbody/RigidBody.cpp                |   9 +-
 src/pe/rigidbody/RigidBody.h                  | 376 ++++++++----------
 src/pe/rigidbody/Sphere.cpp                   |  23 +-
 src/pe/rigidbody/Sphere.h                     |  48 +--
 src/pe/rigidbody/SphereFactory.cpp            |   4 +-
 src/pe/rigidbody/Squirmer.cpp                 |   8 +-
 src/pe/rigidbody/Squirmer.h                   |   2 +-
 src/pe/rigidbody/SquirmerFactory.cpp          |   4 +-
 src/pe/rigidbody/Union.h                      | 309 ++++----------
 src/pe/rigidbody/UnionFactory.h               |  10 +-
 tests/mesh/MeshMarshalling.cpp                |  42 +-
 tests/mesh/MeshPeRaytracing.cpp               |   4 +-
 tests/pe/BodyFlags.cpp                        |   4 +-
 tests/pe/BodyStorage.cpp                      |   4 +-
 tests/pe/CMakeLists.txt                       |   5 +
 tests/pe/CheckVitalParameters.cpp             |   2 +-
 tests/pe/Collision.cpp                        |  32 +-
 tests/pe/CollisionTobiasGJK.cpp               |  50 +--
 tests/pe/Marshalling.cpp                      |  14 +-
 tests/pe/Raytracing.cpp                       |  20 +-
 tests/pe/RigidBody.cpp                        |  12 +-
 tests/pe/SetBodyTypeIDs.cpp                   |   4 +-
 tests/pe/SimpleCCD.cpp                        |   6 +-
 tests/pe/Synchronization.cpp                  |   2 +-
 tests/pe/SynchronizationLargeBody.cpp         |   2 +-
 tests/pe/Union.cpp                            | 185 ++++++++-
 tests/pe/UnionBehavior.cpp                    | 259 ++++++++++++
 tests/pe/VolumeInertia.cpp                    |   8 +-
 .../geometry/PeIntersectionRatioTest.cpp      |   9 +-
 53 files changed, 1004 insertions(+), 890 deletions(-)
 create mode 100644 tests/pe/UnionBehavior.cpp

diff --git a/src/mesh/pe/communication/ConvexPolyhedron.h b/src/mesh/pe/communication/ConvexPolyhedron.h
index df14bb176..1527530b4 100644
--- a/src/mesh/pe/communication/ConvexPolyhedron.h
+++ b/src/mesh/pe/communication/ConvexPolyhedron.h
@@ -74,7 +74,7 @@ inline mesh::pe::ConvexPolyhedronPtr instantiate( mpi::RecvBuffer& buffer, const
    mesh::pe::ConvexPolyhedronParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   auto cp = std::make_unique<mesh::pe::ConvexPolyhedron>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.mesh_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   auto cp = std::make_unique<mesh::pe::ConvexPolyhedron>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.q_, subobjparam.mesh_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
    cp->setLinearVel( subobjparam.v_ );
    cp->setAngularVel( subobjparam.w_ );
    cp->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp b/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
index eb3c3c3ee..62ce1d1c5 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
@@ -62,18 +62,18 @@ namespace pe {
 * \param communicating specifies if the ConvexPolyhedron should take part in synchronization (syncNextNeighbour, syncShadowOwner)
 * \param infiniteMass specifies if the ConvexPolyhedron has infinite mass and will be treated as an obstacle
 */
-ConvexPolyhedron::ConvexPolyhedron( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+ConvexPolyhedron::ConvexPolyhedron( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                                     const TriangleMesh & mesh, MaterialID material,
                                     const bool global, const bool communicating, const bool infiniteMass )
    : GeomPrimitive( getStaticTypeID(), sid, uid, material ),  // Initialization of the parent class
      mesh_( mesh )
 {
-   init( gpos, rpos, q, global, communicating, infiniteMass );
+   init( gpos, q, global, communicating, infiniteMass );
 }
 //*************************************************************************************************
 
 
-void ConvexPolyhedron::init( const Vec3& gpos, const Vec3& rpos, const Quat& q,
+void ConvexPolyhedron::init( const Vec3& gpos,  const Quat& q,
                              const bool global, const bool communicating, const bool infiniteMass )
 {
    WALBERLA_ASSERT_FLOAT_EQUAL( (toWalberla( computeCentroid( mesh_ ) ) - Vec3() ).length(), real_t(0) );
@@ -82,14 +82,21 @@ void ConvexPolyhedron::init( const Vec3& gpos, const Vec3& rpos, const Quat& q,
    mesh_.request_face_normals();
    mesh_.update_face_normals();
 
+   // Calculate the bounding sphere radius first, as setPosition will trigger a call to calcBoundingBox(), which needs it
+   real_t maxSqRadius(0);
+   for(auto vh : mesh_.vertices())
+   {
+      real_t sqRadius = mesh_.point( vh ).sqrnorm();
+      if( sqRadius > maxSqRadius )
+         maxSqRadius = sqRadius;
+   }
+   boundingSphereRadius_ = std::sqrt( maxSqRadius );
+
    // Setting the center of the ConvexPolyhedron
-   gpos_ = gpos;
+   setPosition(gpos);
 
    // Initializing the instantiated ConvexPolyhedron
-   rpos_   = rpos;                   // Setting the relative position
-   q_      = q;                      // Setting the orientation
-   R_      = q_.toRotationMatrix();  // Setting the rotation matrix
-
+   setOrientation(q);
    setGlobal( global );
    if (infiniteMass)
    {
@@ -103,14 +110,7 @@ void ConvexPolyhedron::init( const Vec3& gpos, const Vec3& rpos, const Quat& q,
    setFinite( true );
 
    // Setting the axis-aligned bounding box
-   real_t maxSqRadius(0);
-   for(auto vh : mesh_.vertices())
-   {
-      real_t sqRadius = mesh_.point( vh ).sqrnorm();
-      if( sqRadius > maxSqRadius )
-         maxSqRadius = sqRadius;
-   }
-   boundingSphereRadius_ = std::sqrt( maxSqRadius );
+
    ConvexPolyhedron::calcBoundingBox();
 
    octandVertices_[0] = supportVertex( TriangleMesh::Normal( real_t( 1), real_t( 1), real_t( 1) ), *mesh_.vertices_begin() );
@@ -365,11 +365,12 @@ void ConvexPolyhedron::print( std::ostream& os, const char* tab ) const
 
    //   if( verboseMode )
    //   {
+   Mat3 R = getRotation();
    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";
+      << 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"
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedron.h b/src/mesh/pe/rigid_body/ConvexPolyhedron.h
index 48f7c8ff1..10e6f62a7 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedron.h
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedron.h
@@ -65,7 +65,7 @@ public:
    //**Constructors********************************************************************************
    /*!\name Constructors */
    //@{
-   ConvexPolyhedron( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+   ConvexPolyhedron( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                      const TriangleMesh & mesh, MaterialID material,
                      const bool global, const bool communicating, const bool infiniteMass );
    //@}
@@ -80,7 +80,7 @@ public:
    //**********************************************************************************************
 
 public:
-   void init( const Vec3& gpos, const Vec3& rpos, const Quat& q,
+   void init( const Vec3& gpos, const Quat& q,
               const bool global, const bool communicating, const bool infiniteMass );
 
    //**Get functions*******************************************************************************
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp b/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp
index 6f29a33cf..4229a58f1 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp
@@ -78,7 +78,7 @@ ConvexPolyhedronID createConvexPolyhedron( BodyStorage& globalStorage, BlockStor
       WALBERLA_CHECK_EQUAL(communicating, false, "Global bodies can not be communicating!" );
       WALBERLA_CHECK_EQUAL(infiniteMass, true, "Global bodies must have infinite mass!" );
 
-      auto cp = std::make_unique<ConvexPolyhedron>(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, false, true);
+      auto cp = std::make_unique<ConvexPolyhedron>(sid, uid, gpos, Quat(), mesh, material, global, false, true);
       poly = static_cast<ConvexPolyhedronID>(&globalStorage.add(std::move(cp)));
    } else
    {
@@ -88,7 +88,7 @@ ConvexPolyhedronID createConvexPolyhedron( BodyStorage& globalStorage, BlockStor
             const id_t sid( UniqueID<RigidBody>::create() );
 
             BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
-            auto cp = std::make_unique<ConvexPolyhedron>(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, communicating, infiniteMass);
+            auto cp = std::make_unique<ConvexPolyhedron>(sid, uid, gpos,  Quat(), mesh, material, global, communicating, infiniteMass);
             cp->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
             poly = static_cast<ConvexPolyhedronID>(&bs.add( std::move(cp) ) );
          }
diff --git a/src/pe/communication/Marshalling.cpp b/src/pe/communication/Marshalling.cpp
index bdeb9fd9d..9a8e930f6 100644
--- a/src/pe/communication/Marshalling.cpp
+++ b/src/pe/communication/Marshalling.cpp
@@ -66,10 +66,6 @@ void marshal( mpi::SendBuffer& buffer, const RigidBody& obj ) {
    buffer << obj.hasInfiniteMass();
    buffer << obj.getPosition();
    buffer << obj.hasSuperBody();
-   if( obj.hasSuperBody() )
-   {
-      buffer <<  obj.getRelPosition();
-   }
    buffer << obj.getQuaternion();
    if( !obj.hasSuperBody() )
    {
@@ -96,12 +92,6 @@ void unmarshal( mpi::RecvBuffer& buffer, RigidBodyParameters& objparam ) {
    buffer >> objparam.infiniteMass_;
    buffer >> objparam.gpos_;
    buffer >> objparam.hasSuperBody_;
-
-   if( objparam.hasSuperBody_ )
-   {
-      buffer >> objparam.rpos_;
-   }
-
    buffer >> objparam.q_;
 
    if( !objparam.hasSuperBody_ )
diff --git a/src/pe/communication/Marshalling.h b/src/pe/communication/Marshalling.h
index 225ffaa4f..413636274 100644
--- a/src/pe/communication/Marshalling.h
+++ b/src/pe/communication/Marshalling.h
@@ -75,7 +75,7 @@ struct RigidBodyParameters {
    MPIRigidBodyTraitParameter mpiTrait_;
    bool communicating_, infiniteMass_;
    id_t sid_, uid_;
-   Vec3 gpos_, rpos_, v_, w_;
+   Vec3 gpos_, v_, w_;
    bool hasSuperBody_;
    Quat q_;
 };
diff --git a/src/pe/communication/rigidbody/Box.h b/src/pe/communication/rigidbody/Box.h
index 77f543cbc..78d698f48 100644
--- a/src/pe/communication/rigidbody/Box.h
+++ b/src/pe/communication/rigidbody/Box.h
@@ -64,7 +64,7 @@ inline BoxPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, co
    BoxParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   auto bx = std::make_unique<Box>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.lengths_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   auto bx = std::make_unique<Box>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.q_, subobjparam.lengths_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
    bx->setLinearVel( subobjparam.v_ );
    bx->setAngularVel( subobjparam.w_ );
    bx->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
diff --git a/src/pe/communication/rigidbody/Capsule.h b/src/pe/communication/rigidbody/Capsule.h
index 3ef02f07d..e319d579a 100644
--- a/src/pe/communication/rigidbody/Capsule.h
+++ b/src/pe/communication/rigidbody/Capsule.h
@@ -66,7 +66,7 @@ inline CapsulePtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain
    CapsuleParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   auto cp = std::make_unique<Capsule>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.length_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   auto cp = std::make_unique<Capsule>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_,  subobjparam.q_, subobjparam.radius_, subobjparam.length_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
    cp->setLinearVel( subobjparam.v_ );
    cp->setAngularVel( subobjparam.w_ );
    cp->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
diff --git a/src/pe/communication/rigidbody/Ellipsoid.h b/src/pe/communication/rigidbody/Ellipsoid.h
index a292c5b1d..de8787b45 100644
--- a/src/pe/communication/rigidbody/Ellipsoid.h
+++ b/src/pe/communication/rigidbody/Ellipsoid.h
@@ -66,7 +66,7 @@ inline EllipsoidPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& doma
    EllipsoidParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   auto el = std::make_unique<Ellipsoid>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.semiAxes_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   auto el = std::make_unique<Ellipsoid>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_,  subobjparam.q_, subobjparam.semiAxes_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
    el->setLinearVel( subobjparam.v_ );
    el->setAngularVel( subobjparam.w_ );
    el->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
diff --git a/src/pe/communication/rigidbody/Sphere.h b/src/pe/communication/rigidbody/Sphere.h
index 3e7da5601..846a621e5 100644
--- a/src/pe/communication/rigidbody/Sphere.h
+++ b/src/pe/communication/rigidbody/Sphere.h
@@ -66,7 +66,7 @@ inline SpherePtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain,
    SphereParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   auto sp = std::make_unique<Sphere>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   auto sp = std::make_unique<Sphere>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.q_, subobjparam.radius_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
    sp->setLinearVel( subobjparam.v_ );
    sp->setAngularVel( subobjparam.w_ );
    sp->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
diff --git a/src/pe/communication/rigidbody/Squirmer.h b/src/pe/communication/rigidbody/Squirmer.h
index 3c9b3fbe0..171b9c742 100644
--- a/src/pe/communication/rigidbody/Squirmer.h
+++ b/src/pe/communication/rigidbody/Squirmer.h
@@ -66,7 +66,7 @@ inline SquirmerPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domai
    SquirmerParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   auto sq = std::make_unique<Squirmer>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.squirmerVelocity_, subobjparam.squirmerBeta_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   auto sq = std::make_unique<Squirmer>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.q_, subobjparam.radius_, subobjparam.squirmerVelocity_, subobjparam.squirmerBeta_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
    sq->setLinearVel( subobjparam.v_ );
    sq->setAngularVel( subobjparam.w_ );
    sq->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
diff --git a/src/pe/communication/rigidbody/Union.h b/src/pe/communication/rigidbody/Union.h
index bfaf37881..644f16a8f 100644
--- a/src/pe/communication/rigidbody/Union.h
+++ b/src/pe/communication/rigidbody/Union.h
@@ -119,8 +119,7 @@ inline std::unique_ptr<Union<BodyTypes...>> instantiate( mpi::RecvBuffer& buffer
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
    auto un = std::make_unique<Union<BodyTypes...>>( subobjparam.sid_,
                                                      subobjparam.uid_,
-                                                     subobjparam.gpos_,
-                                                     subobjparam.rpos_,
+                                                     Vec3(),
                                                      subobjparam.q_,
                                                      false,
                                                      subobjparam.communicating_,
@@ -140,6 +139,10 @@ inline std::unique_ptr<Union<BodyTypes...>> instantiate( mpi::RecvBuffer& buffer
    un->setLinearVel( subobjparam.v_ );
    un->setAngularVel( subobjparam.w_ );
    newBody = un.get();
+   // Checks with global data of the union
+   WALBERLA_ASSERT_FLOAT_EQUAL(subobjparam.m_, un->getMass());
+   WALBERLA_ASSERT_FLOAT_EQUAL(subobjparam.I_, un->getBodyInertia());
+   WALBERLA_ASSERT_FLOAT_EQUAL(subobjparam.gpos_, un->getPosition());
    return un;
 }
 
diff --git a/src/pe/rigidbody/Box.cpp b/src/pe/rigidbody/Box.cpp
index ffd27fc8e..0705a4ca1 100644
--- a/src/pe/rigidbody/Box.cpp
+++ b/src/pe/rigidbody/Box.cpp
@@ -55,7 +55,7 @@ namespace pe {
  * \param visible Specifies if the box is visible in a visualization.
  * \param fixed \a true to fix the box, \a false to unfix it.
  */
-Box::Box( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+Box::Box( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
           const Vec3& lengths, MaterialID material,
           const bool global, const bool communicating, const bool infiniteMass )
    : GeomPrimitive( getStaticTypeID(), sid, uid, material )  // Initialization of the parent class
@@ -70,10 +70,8 @@ Box::Box( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
    WALBERLA_ASSERT_GREATER( lengths[2], real_t(0), "Invalid side length in z-dimension" );
 
    // Initializing the instantiated box
-   gpos_   = gpos;
-   rpos_   = rpos;                   // Setting the relative position
-   q_      = q;                      // Setting the orientation
-   R_      = q_.toRotationMatrix();  // Setting the rotation matrix
+   setPosition(gpos);
+   setOrientation(q);                      // Setting the orientation
 
    setGlobal( global );
    if (infiniteMass)
@@ -267,11 +265,12 @@ void Box::print( std::ostream& os, const char* tab ) const
 
    //if( verboseMode )
    {
+      Mat3 R = getRotation();
       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";
+         << 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"
@@ -302,22 +301,23 @@ void Box::print( std::ostream& os, const char* tab ) const
 void Box::calcBoundingBox()
 {
    using std::fabs;
-
-   const real_t xlength( real_t(0.5) * ( fabs(R_[0]*lengths_[0]) + fabs(R_[1]*lengths_[1]) + fabs(R_[2]*lengths_[2]) ) + contactThreshold );
-   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 );
+   Mat3 R = getRotation();
+   const real_t xlength( real_t(0.5) * ( fabs(R[0]*lengths_[0]) + fabs(R[1]*lengths_[1]) + fabs(R[2]*lengths_[2]) ) + contactThreshold );
+   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_[1] - ylength,
-         gpos_[2] - zlength,
-         gpos_[0] + xlength,
-         gpos_[1] + ylength,
-         gpos_[2] + zlength
+            getPosition()[0] - xlength,
+         getPosition()[1] - ylength,
+         getPosition()[2] - zlength,
+         getPosition()[0] + xlength,
+         getPosition()[1] + ylength,
+         getPosition()[2] + zlength
          );
 
    //WALBERLA_ASSERT( aabb_.isValid()        , "Invalid bounding box detected" );
-   WALBERLA_ASSERT( aabb_.contains( gpos_ ), "Invalid bounding box detected" );
+   WALBERLA_ASSERT( aabb_.contains( getPosition() ), "Invalid bounding box detected" );
 }
+
 //*************************************************************************************************
 
 
diff --git a/src/pe/rigidbody/Box.h b/src/pe/rigidbody/Box.h
index 5da39e784..266aead5d 100644
--- a/src/pe/rigidbody/Box.h
+++ b/src/pe/rigidbody/Box.h
@@ -65,7 +65,7 @@ public:
    //**Constructors********************************************************************************
    /*!\name Constructors */
    //@{
-   explicit Box( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+   explicit Box( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                  const Vec3& lengths, MaterialID material,
                  const bool global, const bool communicating, const bool infiniteMass );
    //@}
@@ -440,7 +440,7 @@ inline Vec3 Box::support( const Vec3& d ) const
                                math::sign(bfD[1])*lengths_[1]*real_t(0.5),
                                math::sign(bfD[2])*lengths_[2]*real_t(0.5) );
 
-   return gpos_ + vectorFromBFtoWF(relativSupport);
+   return getPosition() + vectorFromBFtoWF(relativSupport);
 }
 //*************************************************************************************************
 
diff --git a/src/pe/rigidbody/BoxFactory.cpp b/src/pe/rigidbody/BoxFactory.cpp
index 6f471ba55..2a7036004 100644
--- a/src/pe/rigidbody/BoxFactory.cpp
+++ b/src/pe/rigidbody/BoxFactory.cpp
@@ -50,7 +50,7 @@ BoxID createBox(       BodyStorage& globalStorage, BlockStorage& blocks, BlockDa
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      BoxPtr bx = std::make_unique<Box>(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, false, true);
+      BoxPtr bx = std::make_unique<Box>(sid, uid, gpos, Quat(), lengths, material, global, false, true);
       box = static_cast<BoxID>(&globalStorage.add(std::move(bx)));
    } else
    {
@@ -60,7 +60,7 @@ BoxID createBox(       BodyStorage& globalStorage, BlockStorage& blocks, BlockDa
             const id_t sid( UniqueID<RigidBody>::create() );
 
             BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
-            BoxPtr bx = std::make_unique<Box>(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass);
+            BoxPtr bx = std::make_unique<Box>(sid, uid, gpos, Quat(), lengths, material, global, communicating, infiniteMass);
             bx->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
             box = static_cast<BoxID>(&bs.add(std::move(bx)));
          }
diff --git a/src/pe/rigidbody/Capsule.cpp b/src/pe/rigidbody/Capsule.cpp
index 7b58b0ce6..f1d9ad9ee 100644
--- a/src/pe/rigidbody/Capsule.cpp
+++ b/src/pe/rigidbody/Capsule.cpp
@@ -55,7 +55,7 @@ namespace pe {
  *
  * The capsule is created lying along the x-axis.
  */
-Capsule::Capsule( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+Capsule::Capsule( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                   real_t  radius, real_t  length, MaterialID material,
                   const bool global, const bool communicating, const bool infiniteMass )
    : GeomPrimitive( getStaticTypeID(), sid, uid, material )           // Initializing the base object
@@ -70,10 +70,8 @@ Capsule::Capsule( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const
    WALBERLA_ASSERT_GREATER( length, real_t(0), "Invalid capsule length"  );
 
    // Initializing the instantiated capsule
-   gpos_   = gpos;
-   rpos_   = rpos;                   // Setting the relative position
-   q_      = q;                      // Setting the orientation
-   R_      = q_.toRotationMatrix();  // Setting the rotation matrix
+   setPosition(gpos);
+   setOrientation(q);
 
    setGlobal( global );
    if (infiniteMass)
@@ -171,18 +169,20 @@ bool Capsule::isSurfaceRelPointImpl( real_t px, real_t py, real_t  pz ) const
  */
 void Capsule::calcBoundingBox()
 {
-   const real_t  xlength( std::fabs( R_[0]*length_ )*real_t (0.5) + radius_ + contactThreshold );
-   const real_t  ylength( std::fabs( R_[3]*length_ )*real_t (0.5) + radius_ + contactThreshold );
-   const real_t  zlength( std::fabs( R_[6]*length_ )*real_t (0.5) + radius_ + contactThreshold );
+   Mat3 R = getRotation();
+   Vec3 gpos = getPosition();
+   const real_t  xlength( std::fabs( R[0]*length_ )*real_t (0.5) + radius_ + contactThreshold );
+   const real_t  ylength( std::fabs( R[3]*length_ )*real_t (0.5) + radius_ + contactThreshold );
+   const real_t  zlength( std::fabs( R[6]*length_ )*real_t (0.5) + radius_ + contactThreshold );
    aabb_ = math::AABB(
-            gpos_[0] - xlength,
-         gpos_[1] - ylength,
-         gpos_[2] - zlength,
-         gpos_[0] + xlength,
-         gpos_[1] + ylength,
-         gpos_[2] + zlength);
-
-   WALBERLA_ASSERT( aabb_.contains( gpos_ ), "Invalid bounding box detected" );
+           gpos[0] - xlength,
+         gpos[1] - ylength,
+         gpos[2] - zlength,
+         gpos[0] + xlength,
+         gpos[1] + ylength,
+         gpos[2] + zlength);
+
+   WALBERLA_ASSERT( aabb_.contains( getPosition() ), "Invalid bounding box detected" );
 }
 //*************************************************************************************************
 
@@ -243,11 +243,12 @@ void Capsule::print( std::ostream& os, const char* tab ) const
       << tab << "   Linear velocity   = " << getLinearVel() << "\n"
       << tab << "   Angular velocity  = " << getAngularVel() << "\n";
 
+   Mat3 R = getRotation();
    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";
+      << 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"
diff --git a/src/pe/rigidbody/Capsule.h b/src/pe/rigidbody/Capsule.h
index c2d4c6b46..8718f4c90 100644
--- a/src/pe/rigidbody/Capsule.h
+++ b/src/pe/rigidbody/Capsule.h
@@ -70,7 +70,7 @@ public:
    //**Constructors********************************************************************************
    /*!\name Constructors */
    //@{
-   explicit Capsule( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+   explicit Capsule( id_t sid, id_t uid, const Vec3& gpos,  const Quat& q,
                      real_t  radius, real_t  length, MaterialID material,
                      const bool global, const bool communicating, const bool infiniteMass );
    //@}
@@ -97,7 +97,6 @@ public:
    /*!\name Utility functions */
    //@{
    inline virtual Vec3 support( const Vec3& d ) const;
-   inline virtual Vec3 supportContactThreshold( const Vec3& d ) const;
    //@}
    //**********************************************************************************************
 
@@ -278,30 +277,11 @@ inline Vec3 Capsule::support( const Vec3& d ) const
    const Vec3 supportSegment = Vec3( math::sign(bfD[0])*length_*real_t (0.5), real_t (0.0), real_t (0.0));
    const Vec3 supportSphere = radius_ * dnorm;
 
-   return gpos_ + vectorFromBFtoWF(supportSegment) + supportSphere;
+   return getPosition() + vectorFromBFtoWF(supportSegment) + supportSphere;
 }
 //*************************************************************************************************
 
 
-//*************************************************************************************************
-/*!\brief Estimates the point which is farthest in direction \a d.
- *
- * \param d The normalized search direction in world-frame coordinates
- * \return The support point in world-frame coordinates in direction a\ d extended by a vector in
- *         direction \a d of length \a pe::contactThreshold.
- */
-inline Vec3 Capsule::supportContactThreshold( const Vec3& d ) const
-{
-   auto len = d.sqrLength();
-   if (math::equal(len, real_t(0)))
-      return Vec3(0,0,0);
-
-   return support(d) + d*contactThreshold;
-}
-//*************************************************************************************************
-
-
-
 
 //=================================================================================================
 //
diff --git a/src/pe/rigidbody/CapsuleFactory.cpp b/src/pe/rigidbody/CapsuleFactory.cpp
index 325af9701..349e30b2f 100644
--- a/src/pe/rigidbody/CapsuleFactory.cpp
+++ b/src/pe/rigidbody/CapsuleFactory.cpp
@@ -50,7 +50,7 @@ CapsuleID createCapsule(   BodyStorage& globalStorage, BlockStorage& blocks, Blo
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      CapsulePtr cp = std::make_unique<Capsule>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, false, true);
+      CapsulePtr cp = std::make_unique<Capsule>(sid, uid, gpos, Quat(), radius, length, material, global, false, true);
       capsule = static_cast<CapsuleID>(&globalStorage.add(std::move(cp)));
    } else
    {
@@ -60,7 +60,7 @@ CapsuleID createCapsule(   BodyStorage& globalStorage, BlockStorage& blocks, Blo
             const id_t sid( UniqueID<RigidBody>::create() );
 
             BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
-            CapsulePtr cp = std::make_unique<Capsule>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass);
+            CapsulePtr cp = std::make_unique<Capsule>(sid, uid, gpos, Quat(), radius, length, material, global, communicating, infiniteMass);
             cp->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
             capsule = static_cast<CapsuleID>(&bs.add( std::move(cp) ));
          }
diff --git a/src/pe/rigidbody/CylindricalBoundary.cpp b/src/pe/rigidbody/CylindricalBoundary.cpp
index 66f639e49..58f4f97ea 100644
--- a/src/pe/rigidbody/CylindricalBoundary.cpp
+++ b/src/pe/rigidbody/CylindricalBoundary.cpp
@@ -71,9 +71,8 @@ CylindricalBoundary::CylindricalBoundary( id_t sid, id_t uid, const Vec3& gpos,
    WALBERLA_ASSERT_GREATER( radius, real_t(0), "Invalid cylinder radius"  );
 
    // Initializing the instantiated cylinder
-   gpos_   = gpos;
-   q_      = Quat();                 // Setting the orientation
-   R_      = q_.toRotationMatrix();  // Setting the rotation matrix
+   setPosition(gpos);
+   setOrientation(Quat());
 
    // Setting the axis-aligned bounding box
    CylindricalBoundary::calcBoundingBox();
@@ -147,7 +146,7 @@ void CylindricalBoundary::calcBoundingBox()
          +math::Limits<real_t>::inf(),
          +math::Limits<real_t>::inf());
 
-   WALBERLA_ASSERT( aabb_.contains( gpos_ ), "Invalid bounding box detected" );
+   WALBERLA_ASSERT( aabb_.contains( getPosition() ), "Invalid bounding box detected" );
 }
 //*************************************************************************************************
 
@@ -179,12 +178,12 @@ void CylindricalBoundary::print( std::ostream& os, const char* tab ) const
       << tab << "   Global position   = " << getPosition() << "\n"
       << tab << "   Linear velocity   = " << getLinearVel() << "\n"
       << tab << "   Angular velocity  = " << getAngularVel() << "\n";
-
+   Mat3 R = getRotation();
    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";
+      << 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";
 }
 //*************************************************************************************************
 
diff --git a/src/pe/rigidbody/Ellipsoid.cpp b/src/pe/rigidbody/Ellipsoid.cpp
index 3c68d5875..d47b400d5 100644
--- a/src/pe/rigidbody/Ellipsoid.cpp
+++ b/src/pe/rigidbody/Ellipsoid.cpp
@@ -58,12 +58,12 @@ namespace pe {
  * \param communicating specifies if the Ellipsoid should take part in synchronization (syncNextNeighbour, syncShadowOwner)
  * \param infiniteMass specifies if the Ellipsoid has infinite mass and will be treated as an obstacle
  */
-Ellipsoid::Ellipsoid( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+Ellipsoid::Ellipsoid( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                 const Vec3& semiAxes, MaterialID material,
                 const bool global, const bool communicating, const bool infiniteMass )
-   : Ellipsoid::Ellipsoid( getStaticTypeID(), sid, uid, gpos, rpos, q, semiAxes, material, global, communicating, infiniteMass )
+   : Ellipsoid::Ellipsoid( getStaticTypeID(), sid, uid, gpos, q, semiAxes, material, global, communicating, infiniteMass )
 {}
-Ellipsoid::Ellipsoid( id_t const typeId, id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+Ellipsoid::Ellipsoid( id_t const typeId, id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                 const Vec3& semiAxes, MaterialID material,
                 const bool global, const bool communicating, const bool infiniteMass )
    : GeomPrimitive( typeId, sid, uid, material )  // Initialization of the parent class
@@ -76,13 +76,10 @@ Ellipsoid::Ellipsoid( id_t const typeId, id_t sid, id_t uid, const Vec3& gpos, c
    WALBERLA_ASSERT( semiAxes_[0] > real_c(0), "Invalid Ellipsoid radius" );
    WALBERLA_ASSERT( semiAxes_[1] > real_c(0), "Invalid Ellipsoid radius" );
    WALBERLA_ASSERT( semiAxes_[2] > real_c(0), "Invalid Ellipsoid radius" );
-   // Setting the center of the Ellipsoid
-   gpos_ = gpos;
 
-   // Initializing the instantiated Ellipsoid
-   rpos_   = rpos;                   // Setting the relative position
-   q_      = q;                      // Setting the orientation
-   R_      = q_.toRotationMatrix();  // Setting the rotation matrix
+   // Setting the center of the Ellipsoid
+   setPosition(gpos);
+   setOrientation(q);
 
    setGlobal( global );
    if (infiniteMass)
@@ -182,6 +179,8 @@ void Ellipsoid::print( std::ostream& os, const char* tab ) const
 {
    using std::setw;
 
+   Mat3 R = getRotation();
+
    os << tab << " Ellipsoid " << uid_ << " with semi-axis " << semiAxes_ << "\n";
 
    os << tab << "   Fixed: " << isFixed() << " , sleeping: " << !isAwake() << "\n";
@@ -199,9 +198,9 @@ void Ellipsoid::print( std::ostream& os, const char* tab ) const
 //   {
       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";
+         << tab << "   Rotation matrix   = ( " << setw(9) << R[1] << " , " << 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"
diff --git a/src/pe/rigidbody/Ellipsoid.h b/src/pe/rigidbody/Ellipsoid.h
index 573d77348..1cda47381 100644
--- a/src/pe/rigidbody/Ellipsoid.h
+++ b/src/pe/rigidbody/Ellipsoid.h
@@ -65,10 +65,10 @@ public:
    //**Constructors********************************************************************************
    /*!\name Constructors */
    //@{
-   explicit Ellipsoid( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+   explicit Ellipsoid( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                        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,
+   explicit Ellipsoid( id_t const typeID, id_t sid, id_t uid, const Vec3& rpos, const Quat& q,
                        const Vec3& semiAxes, MaterialID material,
                        const bool global, const bool communicating, const bool infiniteMass );
    //@}
@@ -259,20 +259,21 @@ inline real_t Ellipsoid::calcDensity(const Vec3& semiAxes, real_t mass )
 inline void Ellipsoid::calcBoundingBox()
 {	
    using std::fabs;
-
-   const real_t xlength( fabs(R_[0]*semiAxes_[0]) + fabs(R_[1]*semiAxes_[1]) + fabs(R_[2]*semiAxes_[2])  + contactThreshold );
-   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 );
+   Mat3 R(getRotation());
+   Vec3 gpos = getPosition();
+   const real_t xlength( fabs(R[0]*semiAxes_[0]) + fabs(R[1]*semiAxes_[1]) + fabs(R[2]*semiAxes_[2])  + contactThreshold );
+   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_[1] - ylength,
-         gpos_[2] - zlength,
-         gpos_[0] + xlength,
-         gpos_[1] + ylength,
-         gpos_[2] + zlength
+           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_.contains( gpos_ ), "Invalid bounding box detected("<< getSystemID() <<")\n" << "pos: " << gpos_ << "\nlengths: " << xlength << "," << ylength << ", " << zlength<< "\nvel: " << getLinearVel() << "\nbox: " << aabb_ );
+   WALBERLA_ASSERT( aabb_.contains( gpos ), "Invalid bounding box detected("<< getSystemID() <<")\n" << "pos: " << getPosition() << "\nlengths: " << xlength << "," << ylength << ", " << zlength<< "\nvel: " << getLinearVel() << "\nbox: " << aabb_ );
 }
 //*************************************************************************************************
 
diff --git a/src/pe/rigidbody/EllipsoidFactory.cpp b/src/pe/rigidbody/EllipsoidFactory.cpp
index a5e46b350..2136a8414 100644
--- a/src/pe/rigidbody/EllipsoidFactory.cpp
+++ b/src/pe/rigidbody/EllipsoidFactory.cpp
@@ -48,7 +48,7 @@ EllipsoidID createEllipsoid( BodyStorage& globalStorage, BlockStorage& blocks, B
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      EllipsoidPtr el = std::make_unique<Ellipsoid>(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, false, true);
+      EllipsoidPtr el = std::make_unique<Ellipsoid>(sid, uid, gpos, Quat(), semiAxes, material, global, false, true);
       ellipsoid = static_cast<EllipsoidID>(&globalStorage.add(std::move(el)));
    } else
    {
@@ -58,7 +58,7 @@ EllipsoidID createEllipsoid( BodyStorage& globalStorage, BlockStorage& blocks, B
             const id_t sid( UniqueID<RigidBody>::create() );
 
             BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
-            EllipsoidPtr el = std::make_unique<Ellipsoid>(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, communicating, infiniteMass);
+            EllipsoidPtr el = std::make_unique<Ellipsoid>(sid, uid, gpos, Quat(), semiAxes, material, global, communicating, infiniteMass);
             el->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
             ellipsoid = static_cast<EllipsoidID>(&bs.add(std::move(el)));
          }
diff --git a/src/pe/rigidbody/Plane.cpp b/src/pe/rigidbody/Plane.cpp
index 872edbe3e..0d501c60d 100644
--- a/src/pe/rigidbody/Plane.cpp
+++ b/src/pe/rigidbody/Plane.cpp
@@ -87,17 +87,15 @@ Plane::Plane( id_t sid, id_t uid,
    WALBERLA_ASSERT_FLOAT_EQUAL( normal.sqrLength(), real_c(1) , "Invalid plane normal" );
 
    // Setting the global position (anchor point) of the plane
-   gpos_ = gpos;
+   setPosition(gpos);
 
    // Calculating the orientation and rotation
    // The default normal of a plane is <0,0,1>. The rotation of the plane is calculated
    // as the rotation of this default normal to the specified normal.
    if( normal[0]*normal[0] + normal[1]*normal[1] < math::Limits<real_t>::accuracy() )
-      q_ = Quat( Vec3( 1, 0, 0 ), std::acos( normal[2] ) );
+      setOrientation( Quat(Vec3( 1, 0, 0 ), std::acos( normal[2] ) ) );
    else
-      q_ = Quat( Vec3( -normal[1], normal[0], real_c(0) ), std::acos( normal[2] ) );
-
-   R_ = q_.toRotationMatrix();
+      setOrientation( Quat( Vec3( -normal[1], normal[0], real_c(0) ), std::acos( normal[2] ) ) );
 
    // Setting the axis-aligned bounding box
    Plane::calcBoundingBox();
@@ -175,11 +173,8 @@ void Plane::calcBoundingBox()
  */
 void Plane::setPositionImpl( real_t px, real_t py, real_t pz )
 {
-   gpos_[0] = px;
-   gpos_[1] = py;
-   gpos_[2] = pz;
-   d_ = normal_ * gpos_;
-
+   RigidBody::setPositionImpl(px,py,pz);
+   d_ = normal_ * getPosition();
    Plane::calcBoundingBox();    // Updating the axis-aligned bounding box of the plane
 #if MOBILE_INFINITE
    wake();               // Waking the box from sleep mode
@@ -210,16 +205,15 @@ void Plane::setPositionImpl( real_t px, real_t py, real_t pz )
  */
 void Plane::setOrientationImpl( real_t r, real_t i, real_t j, real_t k )
 {
-   q_.set(r, i, j, k);          // Updating the orientation of the plane
-   R_ = q_.toRotationMatrix();  // Updating the rotation of the plane
-
+   RigidBody::setOrientationImpl(r,i,j,k);
+   Mat3 R = getRotation();
    // Updating the normal of the plane ( R * <0,0,1> )
-   normal_[0] = R_[2];
-   normal_[1] = R_[5];
-   normal_[2] = R_[8];
+   normal_[0] = R[2];
+   normal_[1] = R[5];
+   normal_[2] = R[8];
 
    // Updating the displacement from the origin
-   d_ = normal_ * gpos_;
+   d_ = normal_ * getPosition();
 
    Plane::calcBoundingBox();  // Updating the axis-aligned bounding box of the plane
 #if MOBILE_INFINITE
@@ -256,10 +250,9 @@ void Plane::setOrientationImpl( real_t r, real_t i, real_t j, real_t k )
  */
 void Plane::translateImpl( real_t dx, real_t dy, real_t dz )
 {
-   gpos_[0] += dx;
-   gpos_[1] += dy;
-   gpos_[2] += dz;
-   d_ = normal_ * gpos_;
+
+   setPosition(getPosition() + Vec3(dx,dy,dz));
+   d_ = normal_ * getPosition();
 
    Plane::calcBoundingBox();    // Updating the axis-aligned bounding box
 #if MOBILE_INFINITE
@@ -301,16 +294,16 @@ void Plane::rotateImpl( const Quat& dq )
 //   if( ExclusiveSection::isActive() )
 //      throw std::logic_error( "Invalid rotation of a plane inside an exclusive section" );
 
-   q_ = dq * q_;                // Updating the orientation of the plane
-   R_ = q_.toRotationMatrix();  // Updating the rotation of the plane
+   setOrientation(dq * getQuaternion());
 
    // Updating the normal of the plane ( R * <0,0,1> )
-   normal_[0] = R_[2];
-   normal_[1] = R_[5];
-   normal_[2] = R_[8];
+   Mat3 R = getRotation();
+   normal_[0] = R[2];
+   normal_[1] = R[5];
+   normal_[2] = R[8];
 
    // Updating the displacement from the origin
-   d_ = normal_ * gpos_;
+   d_ = normal_ * getPosition();
 
    Plane::calcBoundingBox();  // Updating the axis-aligned bounding box of the plane
 #if MOBILE_INFINITE
@@ -342,14 +335,16 @@ void Plane::rotateImpl( const Quat& dq )
  */
 void Plane::rotateAroundOriginImpl( const Quat& dq )
 {
-   gpos_ = dq.rotate( gpos_ );     // Updating the global position of the plane
-   q_    = dq * q_;                // Updating the orientation of the plane
-   R_    = q_.toRotationMatrix();  // Updating the rotation of the plane
+
+   setPosition(dq.rotate( getPosition() ));     // Updating the global position of the plane
+   setOrientation(dq * getQuaternion());                // Updating the orientation of the plane
+
 
    // Updating the normal of the plane ( R * <0,0,1> )
-   normal_[0] = R_[2];
-   normal_[1] = R_[5];
-   normal_[2] = R_[8];
+   Mat3 R = getRotation();
+   normal_[0] = R[2];
+   normal_[1] = R[5];
+   normal_[2] = R[8];
 
    Plane::calcBoundingBox();  // Updating the axis-aligned bounding box of the plane
    signalRotation();   // Signaling the change of orientation to the superordinate body
@@ -382,19 +377,19 @@ void Plane::rotateAroundOriginImpl( const Quat& dq )
  */
 void Plane::rotateAroundPointImpl( const Vec3& point, const Quat& dq )
 {
-   const Vec3 dp( gpos_ - point );
+   const Vec3 dp( getPosition() - point );
 
-   gpos_ = point + dq.rotate( dp );  // Updating the global position of the box
-   q_    = dq * q_;                  // Updating the orientation of the box
-   R_    = q_.toRotationMatrix();    // Updating the rotation of the box
+   setPosition(point + dq.rotate( dp ) );  // Updating the global position of the box
+   setOrientation(dq * getQuaternion());   // Updating the orientation of the box
 
    // Updating the normal of the plane ( R * <0,0,1> )
-   normal_[0] = R_[2];
-   normal_[1] = R_[5];
-   normal_[2] = R_[8];
+   Mat3 R = getRotation();
+   normal_[0] = R[2];
+   normal_[1] = R[5];
+   normal_[2] = R[8];
 
    // Updating the displacement from the origin
-   d_ = normal_ * gpos_;
+   d_ = normal_ * getPosition();
 
    Plane::calcBoundingBox();  // Updating the axis-aligned bounding box of the plane
 #if MOBILE_INFINITE
@@ -447,85 +442,6 @@ bool Plane::isSurfaceRelPointImpl( real_t /*px*/, real_t /*py*/, real_t pz ) con
 //*************************************************************************************************
 
 
-
-
-
-//=================================================================================================
-//
-//  SIMULATION FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Translation update of a subordinate plane.
- *
- * \param dp Change in the global position of the superordinate body.
- * \return void
- *
- * This update function is triggered by the superordinate body in case of a translational
- * movement. This movement involves a change of the global position, the displacement from
- * the origin and the axis-aligned bounding box.
- */
-void Plane::update( const Vec3& dp )
-{
-   // Checking the state of the plane
-   WALBERLA_ASSERT( checkInvariants(), "Invalid plane state detected" );
-   WALBERLA_ASSERT( hasSuperBody(), "Invalid superordinate body detected" );
-
-   // Updating the global position and the displacement
-   gpos_ += dp;
-   d_ = normal_ * gpos_;
-
-   // Setting the axis-aligned bounding box
-   Plane::calcBoundingBox();
-
-   // Checking the state of the plane
-   WALBERLA_ASSERT( checkInvariants(), "Invalid plane state detected" );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Rotation update of a subordinate plane.
- *
- * \param dq Change in the orientation of the superordinate body.
- * \return void
- *
- * This update function is triggered by the superordinate body in case of a rotational
- * movement. This movement involves a change in the global position, the displacement from
- * the origin, the orientation/rotation, the normal and the axis-aligned bounding box of
- * the plane.
- */
-void Plane::update( const Quat& dq )
-{
-   // Checking the state of the plane
-   WALBERLA_ASSERT( checkInvariants(), "Invalid plane state detected" );
-   WALBERLA_ASSERT( hasSuperBody(), "Invalid superordinate body detected" );
-
-   // Calculating the new orientation and rotation
-   q_ = dq * q_;
-   R_ = q_.toRotationMatrix();
-
-   // Updating the normal of the plane ( R * <0,0,1> )
-   normal_[0] = R_[2];
-   normal_[1] = R_[5];
-   normal_[2] = R_[8];
-
-   // Updating the global position and the displacement
-   gpos_ = sb_->getPosition() + ( sb_->getRotation() * rpos_ );
-   d_    = normal_ * gpos_;
-
-   // Setting the axis-aligned bounding box
-   Plane::calcBoundingBox();
-
-   // Checking the state of the plane
-   WALBERLA_ASSERT( checkInvariants(), "Invalid plane state detected" );
-}
-//*************************************************************************************************
-
-
-
-
 //=================================================================================================
 //
 //  OUTPUT FUNCTIONS
@@ -546,14 +462,15 @@ void Plane::print( std::ostream& os, const char* tab ) const
    os << tab << " Plane " << uid_ << " with normal " << normal_ << " and displacement " << d_ << "\n"
       << tab << "   System ID         = " << sid_ << "\n"
       << tab << "   Material          = " << Material::getName( material_ ) << "\n"
-      << tab << "   Global position   = " << gpos_ << "\n";
+      << tab << "   Global position   = " << getPosition() << "\n";
 
-   os << tab << "   Relative position = " << rpos_ << "\n"
+   os << tab << "   Relative position = " << getRelPosition() << "\n"
       << tab << "   Bounding box      = " << aabb_ << "\n"
-      << tab << "   Quaternion        = " << q_ << "\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";
+      << tab << "   Quaternion        = " << getQuaternion()<< "\n";
+   Mat3 R = getRotation();
+   os << 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";
 }
 //*************************************************************************************************
 
diff --git a/src/pe/rigidbody/Plane.h b/src/pe/rigidbody/Plane.h
index 589d11038..94368f79f 100644
--- a/src/pe/rigidbody/Plane.h
+++ b/src/pe/rigidbody/Plane.h
@@ -138,14 +138,6 @@ protected:
    //@}
    //**********************************************************************************************
 
-   //**Simulation functions************************************************************************
-   /*!\name Simulation functions */
-   //@{
-   virtual void update( const Vec3& dp );  // Translation update of a subordinate plane
-   virtual void update( const Quat& dq );  // Rotation update of a subordinate plane
-   //@}
-   //**********************************************************************************************
-
    //**Member variables****************************************************************************
    /*!\name Member variables */
    //@{
diff --git a/src/pe/rigidbody/RigidBody.cpp b/src/pe/rigidbody/RigidBody.cpp
index f30f35ce6..78743f796 100644
--- a/src/pe/rigidbody/RigidBody.cpp
+++ b/src/pe/rigidbody/RigidBody.cpp
@@ -37,17 +37,13 @@ RigidBody::RigidBody( id_t const typeID, id_t sid, id_t uid )
    , mass_( 0 )               // Total mass of the rigid body
    , invMass_( 0 )            // Inverse total mass of the rigid body
    , motion_(sleepThreshold)  // The current motion of the rigid body
-   , gpos_()                  // Global position of the center of mass
-   , rpos_()                  // Relative position within the body frame of the superordinate body
    , v_()                     // Linear velocity
    , w_()                     // Angular velocity
    , force_()                 // Total force
    , torque_()                // Total torque
    , I_( real_c(0) )          // Moment of inertia
    , Iinv_( real_c(0) )       // Inverse moment of inertia
-   , q_()                     // Orientation of the body frame
-   , R_()                     // Rigid body rotation
-   , manager_(nullptr)              // The rigid body manager responsible for the rigid body
+   , manager_(nullptr)        // The rigid body manager responsible for the rigid body
    , finite_ (true)           // Finiteness flag
    , visible_(true)           // Visibility flag
    , remote_ (false)          // Remote flag
@@ -56,6 +52,9 @@ RigidBody::RigidBody( id_t const typeID, id_t sid, id_t uid )
    , toBeDeleted_(false)      // deletion flag
    , sid_    (sid)            // System-specific body index
    , uid_    (uid)            // User-specific body ID
+   , gpos_()                  // Global position of the center of mass
+   , q_()                     // Orientation of the body frame
+   , R_()                     // Rigid body rotation
    , typeID_(typeID)          // geometry type
 {
    sb_ = this;           // The superordinate rigid body
diff --git a/src/pe/rigidbody/RigidBody.h b/src/pe/rigidbody/RigidBody.h
index d987ca4e7..1ac988c75 100644
--- a/src/pe/rigidbody/RigidBody.h
+++ b/src/pe/rigidbody/RigidBody.h
@@ -98,14 +98,15 @@ public:
    inline bool           isMarkedForDeletion() const { return toBeDeleted_; }
    inline id_t           getSystemID()       const;
    inline id_t           getID()             const;
-   inline const Vec3&    getRelPosition()    const;
-   inline const Vec3&    getPosition()       const;
-   inline const Vec3     getRelLinearVel()   const;
-   inline const Vec3&    getLinearVel()      const;
-   inline const Vec3     getRelAngularVel()  const;
-   inline const Vec3&    getAngularVel()     const;
-   inline const Quat&    getQuaternion()     const;
-   inline const Mat3&    getRotation()       const;
+   inline const Vec3     getRelPosition()    const;
+   inline const Vec3     getPosition()       const;
+   inline const Vec3     getBodyLinearVel()   const;
+   inline const Vec3     getLinearVel()      const;
+   inline const Vec3     getBodyAngularVel()  const;
+   inline const Vec3 &   getAngularVel()     const;
+   inline const Quat     getRelQuaternion()  const;
+   inline const Quat     getQuaternion()     const;
+   inline const Mat3     getRotation()       const;
    inline real_t         getMass()           const;
    inline real_t         getInvMass()        const;
    virtual inline real_t getVolume()         const;
@@ -149,8 +150,10 @@ public:
    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 setRelPosition( 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 setRelOrientation( const Quat& q );
    inline  void setMassAndInertiaToInfinity();
 
    inline void setRelLinearVel ( real_t vx, real_t vy, real_t vz );
@@ -309,8 +312,6 @@ protected:
    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();
    //@}
    //**********************************************************************************************
 
@@ -321,14 +322,6 @@ protected:
    //@}
    //**********************************************************************************************
 
-   //**Simulation functions************************************************************************
-   /*!\name Simulation functions */
-   //@{
-   virtual void update( const Vec3& dp );  // Translation update of a subordinate rigid body
-   virtual void update( const Quat& dq );  // Rotation update of a subordinate rigid body
-   //@}
-   //**********************************************************************************************
-
    //**Functions for internal changes in compound geometries***************************************
    /*!\name Functions for internal changes in compound geometries */
    //@{
@@ -357,12 +350,7 @@ protected:
    real_t motion_;   //!< The current motion of the rigid body.
                   /*!< If this value drops under the specified sleep threshold, the
                        rigid body will be put to sleep. */
-   Vec3 gpos_;       //!< The global position of the center of mass of this rigid body.
-   Vec3 rpos_;       //!< The relative position within the body frame of the superordinate body.
-                  /*!< If the body is contained within a superordinate Union the relative
-                       position gives the position of the body's center of mass within the
-                       body frame of the superordinate body. If the body is not contained
-                       in a Union, the relative position is 0. */
+
    mutable Vec3 v_;  //!< The linear velocity of this rigid body.
    mutable Vec3 w_;  //!< Angular velocity of this rigid body.
    Vec3 force_;      //!< Total force (external+contact) acting in the body's center of mass.
@@ -379,8 +367,7 @@ protected:
                                       I_{zx} & I_{zy} & I_{zz} \\
                                       \end{array}\right)\f] */
    Mat3 Iinv_;       //!< The inverse moment of inertia within the body frame.
-   Quat q_;          //!< The orientation of the body frame in the global world frame.
-   Mat3 R_;          //!< The rotation in reference to the global frame of reference.
+
    //@}
    //**********************************************************************************************
 
@@ -390,6 +377,7 @@ protected:
    BodyID sb_;                //!< The superordinate rigid body.
                               /*!< This data member is the connection to the superordinate body,
                                    which is either the enclosing Union or the rigid body itself. */
+
    bool finite_;              //!< Finiteness flag.
                               /*!< The flag value indicates if the rigid body is finite (\a true)
                                    or infinite (\a false). */
@@ -417,7 +405,15 @@ protected:
    AABB aabb_;  //!< Axis-aligned bounding box for the rigid body.
    //@}
    //**********************************************************************************************
+
 private:
+
+   Vec3 gpos_;       /*!< The position of the center of mass of this rigid body. If the body is contained in union
+                          this and the other properties are relative to its center / orientation. Use the respective function
+                          getPosition() / getRotation() to access the actual global Position in the world frame */
+   Quat q_;          //!< The orientation of the body frame in the global world frame.
+   Mat3 R_;          //!< The rotation in reference to the global frame of reference.
+
    id_t typeID_; //< identify geometry type
 };
 
@@ -694,29 +690,38 @@ inline id_t RigidBody::getID() const
 //*************************************************************************************************
 
 
+
+
+
 //*************************************************************************************************
-/*!\brief Returns the relative position of the rigid body within the superordinate body.
- *
- * \return The relative position of the rigid body.
+/*!\brief Returns the global position of the center of mass of the rigid body.
  *
- * If the rigid body is not contained in a superordinate body, the returned relative position will
- * be \f$ \left(\begin{array}{*{3}{c}} 0 & 0 & 0 \end{array}\right) \f$.
+ * \return The global position of the center of mass.
  */
-inline const Vec3& RigidBody::getRelPosition() const
+inline const Vec3 RigidBody::getPosition() const
 {
-   return rpos_;
+   if( !hasSuperBody() ){
+      return gpos_;
+   }
+   return sb_->getPosition() + sb_->getRotation() * getRelPosition();
+
 }
 //*************************************************************************************************
 
-
 //*************************************************************************************************
-/*!\brief Returns the global position of the center of mass of the rigid body.
+/*!\brief Returns the relative position of the rigid body within the superordinate body.
  *
- * \return The global position of the center of mass.
+ * \return The relative position of the rigid body.
+ *
+ * If this body is not containted in a superbody the zero-vector is returned.
  */
-inline const Vec3& RigidBody::getPosition() const
+inline const Vec3 RigidBody::getRelPosition() const
 {
-   return gpos_;
+   if( hasSuperBody() ){
+      return gpos_;
+   }
+   return Vec3(0, 0, 0);
+
 }
 //*************************************************************************************************
 
@@ -729,11 +734,9 @@ inline const Vec3& RigidBody::getPosition() const
  * This function returns the linear velocity of the center of mass of the rigid body in reference
  * to the body's own frame of reference.
  */
-inline const Vec3 RigidBody::getRelLinearVel() const
+inline const Vec3 RigidBody::getBodyLinearVel() const
 {
-   if( hasSuperBody() )
-      v_ = sb_->velFromWF( gpos_ );
-   return R_.getTranspose() * v_;
+   return getRotation().getTranspose() * getLinearVel();
 }
 //*************************************************************************************************
 
@@ -746,11 +749,13 @@ inline const Vec3 RigidBody::getRelLinearVel() const
  * This function returns the linear velocity of the center of mass of the rigid body in reference
  * to the global world frame.
  */
-inline const Vec3& RigidBody::getLinearVel() const
+inline const Vec3 RigidBody::getLinearVel() const
 {
-   if( hasSuperBody() )
-      v_ = sb_->velFromWF( gpos_ );
+   if( hasSuperBody() ){
+      return sb_->getLinearVel() + (sb_->getAngularVel() % (getPosition() - sb_->getPosition()));
+   }
    return v_;
+
 }
 //*************************************************************************************************
 
@@ -760,14 +765,12 @@ inline const Vec3& RigidBody::getLinearVel() const
  *
  * \return The relative angular velocity.
  *
- * This function returns the angluar velocity of the center of mass in reference to the body's
+ * This function returns the angular velocity of the center of mass in reference to the body's
  * own frame of reference.
  */
-inline const Vec3 RigidBody::getRelAngularVel() const
+inline const Vec3 RigidBody::getBodyAngularVel() const
 {
-   if( hasSuperBody() )
-      w_ = sb_->getAngularVel();
-   return R_.getTranspose() * w_;
+   return getRotation().getTranspose() * getAngularVel();
 }
 //*************************************************************************************************
 
@@ -780,10 +783,11 @@ inline const Vec3 RigidBody::getRelAngularVel() const
  * This function returns the angluar velocity of the center of mass in reference to the global
  * world frame.
  */
-inline const Vec3& RigidBody::getAngularVel() const
+inline const Vec3 & RigidBody::getAngularVel() const
 {
-   if( hasSuperBody() )
-      w_ = sb_->getAngularVel();
+   if( hasSuperBody() ) {
+      return sb_->getAngularVel();
+   }
    return w_;
 }
 //*************************************************************************************************
@@ -797,13 +801,34 @@ inline const Vec3& RigidBody::getAngularVel() const
  * This function returns the quaternion of the rigid body, which represents the orientation of
  * the body in reference to the global world frame.
  */
-inline const Quat& RigidBody::getQuaternion() const
+inline const Quat RigidBody::getQuaternion() const
 {
+   if( hasSuperBody() ){
+      return getRelQuaternion() * sb_->getQuaternion();
+   }
    return q_;
 }
 //*************************************************************************************************
 
 
+//*************************************************************************************************
+/*!\brief Returns the relative orientation of the rigid body to its superbody.
+ *
+ * \return The relative orientation of the rigid body.
+ *
+ * This function returns the quaternion, which represents the orientation of
+ * the body in reference to coordinate system of the superbody. If this body has no superbody
+ * the union-quaternion is returned.
+ */
+inline const Quat RigidBody::getRelQuaternion() const
+{
+   if( hasSuperBody() ){
+      return q_;
+   }
+   return Quat();
+}
+//*************************************************************************************************
+
 //*************************************************************************************************
 /*!\brief Returns the rotation of the rigid body.
  *
@@ -812,8 +837,11 @@ inline const Quat& RigidBody::getQuaternion() const
  * This function returns the rotation matrix of the rigid body, which represents the rotation of
  * the body in reference to the global world frame.
  */
-inline const Mat3& RigidBody::getRotation() const
+inline const Mat3 RigidBody::getRotation() const
 {
+   if( hasSuperBody() ) {
+      return getQuaternion().toRotationMatrix();
+   }
    return R_;
 }
 //*************************************************************************************************
@@ -874,7 +902,7 @@ inline const Mat3& RigidBody::getBodyInertia() const
  */
 inline const Mat3 RigidBody::getInertia() const
 {
-   return math::transformMatrixRART(R_, I_);
+   return math::transformMatrixRART(getRotation(), I_);
 }
 //*************************************************************************************************
 
@@ -898,7 +926,7 @@ inline const Mat3& RigidBody::getInvBodyInertia() const
  */
 inline const Mat3 RigidBody::getInvInertia() const
 {
-   return math::transformMatrixRART(R_, Iinv_);
+   return math::transformMatrixRART(getRotation(), Iinv_);
 }
 //*************************************************************************************************
 
@@ -941,6 +969,7 @@ inline real_t   RigidBody::getKineticEnergy()      const
    return real_c(0.5) * getMass() * getLinearVel() * getLinearVel();
 }
 //*************************************************************************************************
+
 //*************************************************************************************************
 /*!\brief Returns the rotational energy of the rigid body
  *
@@ -951,6 +980,7 @@ inline real_t   RigidBody::getRotationalEnergy()      const
    return real_c(0.5) * getAngularVel() * (getInertia() * getAngularVel());
 }
 //*************************************************************************************************
+
 //*************************************************************************************************
 /*!\brief Returns the energy of the rigid body
  *
@@ -976,7 +1006,7 @@ inline real_t   RigidBody::getEnergy()      const
  */
 inline const Vec3 RigidBody::vectorFromBFtoWF( real_t vx, real_t vy, real_t vz ) const
 {
-   return R_ * Vec3( vx, vy, vz );
+   return getRotation() * Vec3( vx, vy, vz );
 }
 //*************************************************************************************************
 
@@ -992,7 +1022,7 @@ inline const Vec3 RigidBody::vectorFromBFtoWF( real_t vx, real_t vy, real_t vz )
  */
 inline const Vec3 RigidBody::vectorFromBFtoWF( const Vec3& v ) const
 {
-   return R_ * v;
+   return getRotation()  * v;
 }
 //*************************************************************************************************
 
@@ -1010,7 +1040,7 @@ inline const Vec3 RigidBody::vectorFromBFtoWF( const Vec3& v ) const
  */
 inline const Vec3 RigidBody::pointFromBFtoWF( real_t px, real_t py, real_t pz ) const
 {
-   return gpos_ + ( R_ * Vec3( px, py, pz ) );
+   return getPosition() + ( getRotation() * Vec3( px, py, pz ) );
 }
 //*************************************************************************************************
 
@@ -1026,7 +1056,7 @@ inline const Vec3 RigidBody::pointFromBFtoWF( real_t px, real_t py, real_t pz )
  */
 inline const Vec3 RigidBody::pointFromBFtoWF( const Vec3& rpos ) const
 {
-   return gpos_ + ( R_ * rpos );
+   return getPosition() + ( getRotation() * rpos );
 }
 //*************************************************************************************************
 
@@ -1044,7 +1074,7 @@ inline const Vec3 RigidBody::pointFromBFtoWF( const Vec3& rpos ) const
  */
 inline const Vec3 RigidBody::vectorFromWFtoBF( real_t vx, real_t vy, real_t vz ) const
 {
-   return R_.getTranspose() * Vec3( vx, vy, vz );
+   return getRotation() .getTranspose() * Vec3( vx, vy, vz );
 }
 //*************************************************************************************************
 
@@ -1060,7 +1090,7 @@ inline const Vec3 RigidBody::vectorFromWFtoBF( real_t vx, real_t vy, real_t vz )
  */
 inline const Vec3 RigidBody::vectorFromWFtoBF( const Vec3& v ) const
 {
-   return R_.getTranspose() * v;
+   return getRotation() .getTranspose() * v;
 }
 //*************************************************************************************************
 
@@ -1078,7 +1108,7 @@ inline const Vec3 RigidBody::vectorFromWFtoBF( const Vec3& v ) const
  */
 inline const Vec3 RigidBody::pointFromWFtoBF( real_t px, real_t py, real_t pz ) const
 {
-   return R_.getTranspose() * ( Vec3( px, py, pz ) - gpos_ );
+   return getRotation().getTranspose() * ( Vec3( px, py, pz ) - getPosition() );
 }
 //*************************************************************************************************
 
@@ -1094,7 +1124,7 @@ inline const Vec3 RigidBody::pointFromWFtoBF( real_t px, real_t py, real_t pz )
  */
 inline const Vec3 RigidBody::pointFromWFtoBF( const Vec3& gpos ) const
 {
-   return R_.getTranspose() * ( gpos - gpos_ );
+   return getRotation().getTranspose() * ( gpos - getPosition() );
 }
 //*************************************************************************************************
 
@@ -1279,23 +1309,6 @@ inline void RigidBody::setAngularVel( const Vec3& avel )
 //*************************************************************************************************
 
 
-//*************************************************************************************************
-/*!\brief Calculation of the relative position within a superordinate body.
- *
- * \return void
- *
- * The function calculates the relative position depending on its current global position, the
- * current global position of the superordinate body and the rotation of the superordinate body.
- */
-inline void RigidBody::calcRelPosition()
-{
-   rpos_ = sb_->R_.getTranspose()*( gpos_ - sb_->gpos_ );
-}
-//*************************************************************************************************
-
-
-
-
 //=================================================================================================
 //
 //  FORCE FUNCTIONS
@@ -1374,8 +1387,12 @@ inline  void RigidBody::resetSB()
 inline void RigidBody::setForce( const Vec3& f )
 {
    // Increasing the force on this rigid body
+   if(hasSuperBody()){
+      sb_->setForce(f);
+      sb_->setTorque((getPosition() - sb_->getPosition()) % f);
+      return;
+   }
    force_ = f;
-
    wake();
 }
 //*************************************************************************************************
@@ -1389,9 +1406,13 @@ inline void RigidBody::setForce( const Vec3& f )
  */
 inline void RigidBody::setTorque( const Vec3& tau )
 {
-   // Increasing the force on this rigid body
+   // Increasing the torque on this rigid body
+      // Increasing the force on this rigid body
+   if(hasSuperBody()){
+      sb_->setTorque(tau);
+      return;
+   }
    torque_ = tau;
-
    wake();
 }
 //*************************************************************************************************
@@ -1479,7 +1500,7 @@ inline void RigidBody::addForce( const Vec3& f )
       wake();
    } else
    {
-      sb_->addForceAtPos( f, gpos_ );
+      sb_->addForceAtPos( f, getPosition() );
    }
 }
 //*************************************************************************************************
@@ -2099,6 +2120,7 @@ inline void RigidBody::setVisible( bool visible )
 //*************************************************************************************************
 inline void RigidBody::setPositionImpl( real_t px, real_t py, real_t pz )
 {
+   if ( hasSuperBody() ) return;
    if (isFixed())
       WALBERLA_ABORT("Trying to move a fixed body: " << *this);
 
@@ -2112,6 +2134,36 @@ inline void RigidBody::setPositionImpl( real_t px, real_t py, real_t pz )
 }
 //*************************************************************************************************
 
+//*************************************************************************************************
+/*!\fn void RigidBody::setRelPosition( const Vec3 &gpos )
+ * \brief Setting the global position of the rigid body.
+ *
+ * \param gpos The relative position.
+ * \return void
+ *
+ * This function sets the relatvie position of the rigid body w. r. t. the superbodies position.
+ *
+ * \b Note:
+ * - Setting the position of a rigid body without superbody will have no effect.
+ * - 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 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!
+ */
+//*************************************************************************************************
+inline void RigidBody::setRelPosition(const Vec3 &gpos) {
+
+   if ( !hasSuperBody() ) return;
+   if (isFixed())
+   WALBERLA_ABORT("Trying to move a fixed body: " << *this);
+
+   gpos_ = gpos;
+   calcBoundingBox();    // Updating the axis-aligned bounding box of the box
+   wake();               // Waking the box from sleep mode
+}
+//*************************************************************************************************
+
 //*************************************************************************************************
 /*!\fn void RigidBody::setPosition( real_t px, real_t py, real_t pz )
  * \brief Setting the global position of the rigid body.
@@ -2194,6 +2246,7 @@ inline void RigidBody::setPosition( const Vec3& gpos )
 //*************************************************************************************************
 inline void RigidBody::setOrientationImpl( real_t r, real_t i, real_t j, real_t k )
 {
+   if ( hasSuperBody() ) return;
    if (isFixed())
       WALBERLA_ABORT("Trying to rotate a fixed body: " << *this);
 
@@ -2263,6 +2316,38 @@ inline void RigidBody::setOrientation( const Quat& q )
 }
 //*************************************************************************************************
 
+//*************************************************************************************************
+/*!\fn void RigidBody::setRelOrientation( const Quat &q )
+ * \brief Setting the relative position of the rigid body.
+ *
+ * \param q The relative orientation.
+ * \return void
+ *
+ * This function sets the relative orientation of the rigid body w. r. t. the superbodies position.
+ *
+ * \b Note:
+ * - Setting the relative orientation of a rigid body without superbody will have no effect.
+ * - 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 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!
+ */
+//*************************************************************************************************
+inline void RigidBody::setRelOrientation(const Quat &q) {
+
+   if ( !hasSuperBody() ) return;
+
+   if (isFixed())
+   WALBERLA_ABORT("Trying to move a fixed body: " << *this);
+
+   q_ = q;
+
+   calcBoundingBox();    // Updating the axis-aligned bounding box of the box
+   wake();               // Waking the box from sleep mode
+}
+//*************************************************************************************************
+
 //*************************************************************************************************
 /*!\fn void RigidBody::setMassAndInertiaToInfinity( )
  * \brief Setting the mass to infinity. This will also make the inertia tensor infinite.
@@ -2990,125 +3075,6 @@ inline void RigidBody::fix()
 //*************************************************************************************************
 
 
-//=================================================================================================
-//
-//  SIMULATION FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Translation update of a subordinate rigid body.
- *
- * \param dp Change in the global position of the superordinate rigid body.
- * \return void
- *
- * This update function is triggered by the superordinate body in case of a translational
- * movement. This movement involves a change in the global position and the axis-aligned
- * bounding box.
- */
-inline void RigidBody::update( const Vec3& dp )
-{
-   // Checking the state of the sphere
-   WALBERLA_ASSERT( checkInvariants(), "Invalid sphere state detected" );
-   WALBERLA_ASSERT( hasSuperBody(), "Invalid superordinate body detected" );
-
-   // Updating the global position
-   gpos_ += dp;
-
-   // Setting the axis-aligned bounding box
-   calcBoundingBox();
-
-   // Checking the state of the sphere
-   WALBERLA_ASSERT( checkInvariants(), "Invalid sphere state detected" );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Rotation update of a subordinate rigid body.
- *
- * \param dq Change in the orientation of the superordinate rigid body.
- * \return void
- *
- * This update function is triggered by the superordinate body in case of a rotational movement.
- * This movement involves a change in the global position, the orientation/rotation and the
- * axis-aligned bounding box of the sphere.
- */
-inline void RigidBody::update( const Quat& dq )
-{
-   // Checking the state of the sphere
-   WALBERLA_ASSERT( checkInvariants(), "Invalid sphere state detected" );
-   WALBERLA_ASSERT( hasSuperBody(), "Invalid superordinate body detected" );
-
-   // Calculating the new global position
-   gpos_ = sb_->getPosition() + ( sb_->getRotation() * rpos_ );
-
-   // Calculating the new orientation and rotation
-   q_ = dq * q_;
-   R_ = q_.toRotationMatrix();
-
-   // Setting the axis-aligned bounding box
-   calcBoundingBox();
-
-   // Checking the state of the sphere
-   WALBERLA_ASSERT( checkInvariants(), "Invalid sphere state detected" );
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  SIMULATION FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\fn void RigidBody::update( const Vec3& dp )
- * \brief Translation update of a subordinate rigid body.
- *
- * \param dp Change in the global position of the superordinate rigid body.
- * \return void
- *
- * This function calculates the necessary updates for a subordinate rigid body contained
- * in a superordinate rigid body that has performed a translational movement. This function
- * is triggered automatically by the superordinate body in case of a translational movement.
- * All classes deriving from the RigidBody class have to implement this function to update
- * the properties of the rigid body. The following properties of the body might change due
- * to this translation. All derived classes have to make sure these properties are updated
- * correctly:
- *
- *   - the global position
- *   - the axis-aligned bounding box
- */
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\fn void RigidBody::update( const Quat& dq )
- * \brief Rotation update of a subordinate rigid body.
- *
- * \param dq Change in the orientation of the superordinate rigid body.
- * \return void
- *
- * This function calculates the necessary updates for a subordinate rigid body contained
- * in a superordinate rigid body that has performed a rotational movement. The function
- * is triggered automatically by the superordinate body in case of a rotational movement.
- * All classes deriving from the RigidBody class have to implement this function to update
- * the properties of the rigid body. The following properties of the body might change due
- * to this rotation. All derived classes have to make sure these properties are updated
- * correctly:
- *
- *   - the global position
- *   - the orientation/rotation (i.e. the quaterion and the rotation matrix)
- *   - the axis-aligned bounding box
- */
-//*************************************************************************************************
-
-
-
-
 //=================================================================================================
 //
 //  FUNCTIONS FOR INTERNAL CHANGES IN COMPOUND GEOMETRIES
diff --git a/src/pe/rigidbody/Sphere.cpp b/src/pe/rigidbody/Sphere.cpp
index 2d45389cb..c3a76c6d8 100644
--- a/src/pe/rigidbody/Sphere.cpp
+++ b/src/pe/rigidbody/Sphere.cpp
@@ -50,7 +50,6 @@ namespace pe {
  * \param sid Unique system-specific ID for the sphere.
  * \param uid User-specific ID for the sphere.
  * \param gpos Global geometric center of the sphere.
- * \param rpos The relative position within the body frame of a superordinate body.
  * \param q The orientation of the sphere's body frame in the global world frame.
  * \param radius The radius of the sphere \f$ (0..\infty) \f$.
  * \param material The material of the sphere.
@@ -58,12 +57,13 @@ namespace pe {
  * \param communicating specifies if the sphere should take part in synchronization (syncNextNeighbour, syncShadowOwner)
  * \param infiniteMass specifies if the sphere has infinite mass and will be treated as an obstacle
  */
-Sphere::Sphere( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+Sphere::Sphere( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                 real_t radius, MaterialID material,
                 const bool global, const bool communicating, const bool infiniteMass )
-   : Sphere::Sphere( getStaticTypeID(), sid, uid, gpos, rpos, q, radius, material, global, communicating, infiniteMass )
+   : Sphere::Sphere( getStaticTypeID(), sid, uid, gpos, q, radius, material, global, communicating, infiniteMass )
 {}
-Sphere::Sphere( id_t const typeId, id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+
+Sphere::Sphere( id_t const typeId, id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                 real_t radius, MaterialID material,
                 const bool global, const bool communicating, const bool infiniteMass )
    : GeomPrimitive( typeId, sid, uid, material )  // Initialization of the parent class
@@ -76,12 +76,8 @@ Sphere::Sphere( id_t const typeId, id_t sid, id_t uid, const Vec3& gpos, const V
    WALBERLA_ASSERT( radius > real_c(0), "Invalid sphere radius" );
 
    // Setting the center of the sphere
-   gpos_ = gpos;
-
-   // Initializing the instantiated sphere
-   rpos_   = rpos;                   // Setting the relative position
-   q_      = q;                      // Setting the orientation
-   R_      = q_.toRotationMatrix();  // Setting the rotation matrix
+   setPosition(gpos);
+   setOrientation(q);
 
    setGlobal( global );
    if (infiniteMass)
@@ -196,11 +192,12 @@ void Sphere::print( std::ostream& os, const char* tab ) const
 
    //   if( verboseMode )
    //   {
+   Mat3 R = getRotation();
    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";
+      << 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"
diff --git a/src/pe/rigidbody/Sphere.h b/src/pe/rigidbody/Sphere.h
index 8efc9bcae..c4a1c95fc 100644
--- a/src/pe/rigidbody/Sphere.h
+++ b/src/pe/rigidbody/Sphere.h
@@ -63,10 +63,10 @@ public:
    //**Constructors********************************************************************************
    /*!\name Constructors */
    //@{
-   explicit Sphere( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+   explicit Sphere( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                     real_t radius, MaterialID material,
                     const bool global, const bool communicating, const bool infiniteMass );
-   explicit Sphere( id_t const typeID, id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+   explicit Sphere( id_t const typeID, id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                     real_t radius, MaterialID material,
                     const bool global, const bool communicating, const bool infiniteMass );
    //@}
@@ -115,7 +115,6 @@ public:
    /*!\name Utility functions */
    //@{
    inline virtual Vec3 support( const Vec3& d ) const;
-   inline virtual Vec3 supportContactThreshold( const Vec3& d ) const;
    //@}
    //**********************************************************************************************
 
@@ -266,18 +265,18 @@ inline real_t Sphere::calcDensity( real_t radius, real_t mass )
 inline void Sphere::calcBoundingBox()
 {
    const real_t length( radius_ + contactThreshold );
-
+   Vec3 gpos = getPosition();
    aabb_    = AABB(
-              gpos_[0] - length,
-              gpos_[1] - length,
-              gpos_[2] - length,
-              gpos_[0] + length,
-              gpos_[1] + length,
-              gpos_[2] + length
+              gpos[0] - length,
+              gpos[1] - length,
+              gpos[2] - length,
+              gpos[0] + length,
+              gpos[1] + length,
+              gpos[2] + length
    );
 
 //   WALBERLA_ASSERT( aabb_.isValid()        , "Invalid bounding box detected" );
-   WALBERLA_ASSERT( aabb_.contains( gpos_ ), "Invalid bounding box detected("<< getSystemID() <<")\n" << "pos: " << gpos_ << "\nlength: " << length << "\nvel: " << getLinearVel() << "\nbox: " << aabb_ );
+   WALBERLA_ASSERT( aabb_.contains( gpos ), "Invalid bounding box detected("<< getSystemID() <<")\n" << "pos: " << gpos << "\nlength: " << length << "\nvel: " << getLinearVel() << "\nbox: " << aabb_ );
 }
 //*************************************************************************************************
 
@@ -317,29 +316,6 @@ inline Vec3 Sphere::support( const Vec3& d ) const
 //*************************************************************************************************
 
 
-//*************************************************************************************************
-/*!\brief Estimates the point which is farthest in direction \a d.
- *
- * \param d The normalized search direction in world-frame coordinates
- * \return The support point in world-frame coordinates in direction a\ d extended by a vector in
- *         direction \a d of length \a pe::contactThreshold.
- */
-inline Vec3 Sphere::supportContactThreshold( const Vec3& d ) const
-{
-   auto len = d.sqrLength();
-   if (!math::equal(len, real_t(0)))
-   {
-      //WALBERLA_ASSERT_FLOAT_EQUAL( len, real_t(1), "search direction not normalized!");
-      const Vec3 s = getPosition() + (getRadius() / sqrt(len) + contactThreshold) * d;
-      //std::cout << "Support in direction " << d << " with center " << getPosition() << " (r=" << getRadius() << ") is " << s << std::endl;
-      return s;
-   } else
-   {
-      return Vec3(0,0,0);
-   }
-}
-//*************************************************************************************************
-
 //=================================================================================================
 //
 //  UTILITY FUNCTIONS
@@ -409,7 +385,7 @@ inline real_t Sphere::getDepth( real_t px, real_t py, real_t pz ) const
  */
 inline real_t Sphere::getDepth( const Vec3& gpos ) const
 {
-   return ( radius_ - ( gpos - gpos_ ).length() );
+   return ( radius_ - ( gpos - getPosition() ).length() );
 }
 //*************************************************************************************************
 
@@ -477,7 +453,7 @@ inline real_t Sphere::getDistance( real_t px, real_t py, real_t pz ) const
  */
 inline real_t Sphere::getDistance( const Vec3& gpos ) const
 {
-   return ( ( gpos - gpos_ ).length() - radius_ );
+   return ( ( gpos - getPosition() ).length() - radius_ );
 }
 //*************************************************************************************************
 
diff --git a/src/pe/rigidbody/SphereFactory.cpp b/src/pe/rigidbody/SphereFactory.cpp
index d88774c45..dfe500daa 100644
--- a/src/pe/rigidbody/SphereFactory.cpp
+++ b/src/pe/rigidbody/SphereFactory.cpp
@@ -49,7 +49,7 @@ SphereID createSphere( BodyStorage& globalStorage, BlockStorage& blocks, BlockDa
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      SpherePtr sp = std::make_unique<Sphere>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, false, true);
+      SpherePtr sp = std::make_unique<Sphere>(sid, uid, gpos, Quat(), radius, material, global, false, true);
       sphere = static_cast<SphereID>(&globalStorage.add( std::move(sp) ));
    } else
    {
@@ -59,7 +59,7 @@ SphereID createSphere( BodyStorage& globalStorage, BlockStorage& blocks, BlockDa
             const id_t sid( UniqueID<RigidBody>::create() );
 
             BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
-            SpherePtr sp = std::make_unique<Sphere>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass);
+            SpherePtr sp = std::make_unique<Sphere>(sid, uid, gpos, Quat(), radius, material, global, communicating, infiniteMass);
             sp->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
             sphere = static_cast<SphereID>(&bs.add( std::move(sp) ));
          }
diff --git a/src/pe/rigidbody/Squirmer.cpp b/src/pe/rigidbody/Squirmer.cpp
index 99f650b00..e9d386c59 100644
--- a/src/pe/rigidbody/Squirmer.cpp
+++ b/src/pe/rigidbody/Squirmer.cpp
@@ -48,10 +48,10 @@ namespace pe {
  * \param communicating specifies if the sphere should take part in synchronization (syncNextNeighbour, syncShadowOwner)
  * \param infiniteMass specifies if the sphere has infinite mass and will be treated as an obstacle
  */
-Squirmer::Squirmer( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+Squirmer::Squirmer( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                     real_t radius, real_t squirmerVelocity, real_t squirmerBeta, MaterialID material,
                     const bool global, const bool communicating, const bool infiniteMass )
-   : Sphere( getStaticTypeID(), sid, uid, gpos, rpos, q, radius, material, global, communicating, infiniteMass )  // Initialization of the parent class
+   : Sphere( getStaticTypeID(), sid, uid, gpos, q, radius, material, global, communicating, infiniteMass )  // Initialization of the parent class
    , squirmerVelocity_(squirmerVelocity), squirmerBeta_(squirmerBeta)
 {
 }
@@ -106,7 +106,7 @@ const Vec3 Squirmer::velFromBF( real_t px, real_t py, real_t pz ) const
  */
 const Vec3 Squirmer::velFromBF( const Vec3& rpos ) const
 {
-   return Sphere::velFromBF( rpos ) + getSquirmerVelocity( R_ * rpos );
+   return Sphere::velFromBF( rpos ) + getSquirmerVelocity( getRotation() * rpos );
 }
 //*************************************************************************************************
 
@@ -154,7 +154,7 @@ const Vec3 Squirmer::getSquirmerVelocity( const Vec3& rpos ) const
  */
 const Vec3 Squirmer::velFromWF( const Vec3& gpos ) const
 {
-   return Sphere::velFromWF( gpos ) + getSquirmerVelocity( gpos - gpos_ );
+   return Sphere::velFromWF( gpos ) + getSquirmerVelocity( gpos - getPosition() );
 }
 //*************************************************************************************************
 
diff --git a/src/pe/rigidbody/Squirmer.h b/src/pe/rigidbody/Squirmer.h
index 5dcf205c4..0d9514324 100644
--- a/src/pe/rigidbody/Squirmer.h
+++ b/src/pe/rigidbody/Squirmer.h
@@ -32,7 +32,7 @@ public:
    //**Constructors********************************************************************************
    /*!\name Constructors */
    //@{
-   explicit Squirmer( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+   explicit Squirmer( id_t sid, id_t uid, const Vec3& gpos,  const Quat& q,
                     real_t radius, real_t squirmerVelocity, real_t squirmerBeta, MaterialID material,
                     const bool global, const bool communicating, const bool infiniteMass );
    //@}
diff --git a/src/pe/rigidbody/SquirmerFactory.cpp b/src/pe/rigidbody/SquirmerFactory.cpp
index 7160ff2d0..caac4c9a0 100644
--- a/src/pe/rigidbody/SquirmerFactory.cpp
+++ b/src/pe/rigidbody/SquirmerFactory.cpp
@@ -48,7 +48,7 @@ SquirmerID createSquirmer( BodyStorage& globalStorage, BlockStorage& blocks, Blo
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      SquirmerPtr sq = std::make_unique<Squirmer>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, false, true);
+      SquirmerPtr sq = std::make_unique<Squirmer>(sid, uid, gpos, Quat(), radius, squirmerVelocity, squirmerBeta, material, global, false, true);
       squirmer = static_cast<SquirmerID>(&globalStorage.add(std::move(sq)));
    } else
    {
@@ -58,7 +58,7 @@ SquirmerID createSquirmer( BodyStorage& globalStorage, BlockStorage& blocks, Blo
             const id_t sid( UniqueID<RigidBody>::create() );
 
             BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
-            SquirmerPtr sq = std::make_unique<Squirmer>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, communicating, infiniteMass);
+            SquirmerPtr sq = std::make_unique<Squirmer>(sid, uid, gpos, Quat(), radius, squirmerVelocity, squirmerBeta, material, global, communicating, infiniteMass);
             sq->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
             squirmer = static_cast<SquirmerID>(&bs.add( std::move(sq) ));
          }
diff --git a/src/pe/rigidbody/Union.h b/src/pe/rigidbody/Union.h
index 3311851f5..2f462877f 100644
--- a/src/pe/rigidbody/Union.h
+++ b/src/pe/rigidbody/Union.h
@@ -55,11 +55,11 @@ namespace pe {
 //*************************************************************************************************
 /**
  * \ingroup pe
- * \brief Base class for the sphere geometry.
+ * \brief Base class for the union geometry, a rigid assebly of bodies.
  *
- * The Sphere class represents the base class for the sphere geometry. It provides
- * the basic functionality of a sphere. For a full description of the sphere geometry,
- * see the Sphere class description.
+ * The Union class represents the base class for the sphere geometry.
+ * For a full description of the union geometry,
+ * see the Union class description.
  */
 template <typename... BodyTypes>
 class Union : public RigidBody
@@ -79,7 +79,7 @@ public:
    //**Constructors********************************************************************************
    /*!\name Constructors */
    //@{
-   explicit Union( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+   explicit Union( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                    const bool global, const bool communicating, const bool infiniteMass );
    //@}
    //**********************************************************************************************
@@ -132,14 +132,6 @@ public:
 
    virtual inline bool   hasSubBodies()      const WALBERLA_OVERRIDE { return true; }
 
-   //**Simulation functions************************************************************************
-   /*!\name Simulation functions */
-   //@{
-   virtual void update( const Vec3& dp ) WALBERLA_OVERRIDE;  // Translation update of a subordinate rigid body
-   virtual void update( const Quat& dq ) WALBERLA_OVERRIDE;  // Rotation update of a subordinate rigid body
-   //@}
-   //**********************************************************************************************
-
    //**Signal functions***************************************************************************
    /*!\name Signal functions */
    //@{
@@ -189,7 +181,7 @@ protected:
    /*!\name Utility functions */
    //@{
    inline virtual void calcBoundingBox() WALBERLA_OVERRIDE;  // Calculation of the axis-aligned bounding box
-   void calcCenterOfMass(); ///< updates the center of mass (gpos)
+   inline         void calcCenterOfMass(); // Compute mass and center of gravity
    inline         void calcInertia();      // Calculation of the moment of inertia
    //@}
    //**********************************************************************************************
@@ -228,15 +220,13 @@ private:
  * \param infiniteMass specifies if the sphere has infinite mass and will be treated as an obstacle
  */
 template <typename... BodyTypes>
-Union<BodyTypes...>::Union( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
+Union<BodyTypes...>::Union( id_t sid, id_t uid, const Vec3& gpos, const Quat& q,
                              const bool global, const bool communicating, const bool /*infiniteMass*/ )
    : RigidBody( getStaticTypeID(), sid, uid )  // Initialization of the parent class
 {
    // Initializing the instantiated union
-   gpos_   = gpos;                   // Setting the global center of mass
-   rpos_   = rpos;                   // Setting the relative position
-   q_      = q;                      // Setting the orientation
-   R_      = q_.toRotationMatrix();  // Setting the rotation matrix
+   setPosition(gpos);                // Setting the global center of mass
+   setOrientation(q);                // Setting the orientation
 
    calcCenterOfMass();
    calcInertia();
@@ -258,7 +248,7 @@ Union<BodyTypes...>::Union( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rp
 //=================================================================================================
 
 //*************************************************************************************************
-/*!\brief Destructor for the Sphere class.
+/*!\brief Destructor for the Union class.
  */
 template <typename... BodyTypes>
 Union<BodyTypes...>::~Union()
@@ -266,7 +256,7 @@ Union<BodyTypes...>::~Union()
    // Clearing the bodies
    bodies_.clear();
 
-   // Logging the destruction of the sphere
+   // Logging the destruction of the union
    WALBERLA_LOG_DETAIL( "Destroyed union " << sid_ );
 }
 //*************************************************************************************************
@@ -321,27 +311,31 @@ template <typename... BodyTypes>
 void Union<BodyTypes...>::calcBoundingBox()
 {
    // Setting the bounding box of an empty union
+   Vec3 gpos = getPosition();
    if( bodies_.isEmpty() ) {
       aabb_ = math::AABB(
-                 gpos_[0] - real_t(0.01),
-            gpos_[1] - real_t(0.01),
-            gpos_[2] - real_t(0.01),
-            gpos_[0] + real_t(0.01),
-            gpos_[1] + real_t(0.01),
-            gpos_[2] + real_t(0.01)
+              gpos[0] - real_t(0.01),
+              gpos[1] - real_t(0.01),
+              gpos[2] - real_t(0.01),
+              gpos[0] + real_t(0.01),
+              gpos[1] + real_t(0.01),
+              gpos[2] + real_t(0.01)
             );
    }
 
    // Using the bounding box of the first contained bodies as initial bounding box
    // and merging it with the bounding boxes of all other bodies
    else {
+      bodies_.begin()->calcBoundingBox();
       aabb_ = bodies_.begin()->getAABB();
-      for( auto b=bodies_.begin()+1; b!=bodies_.end(); ++b )
-         aabb_.merge( b->getAABB() );
+      for( auto &b : bodies_ ){
+         b.calcBoundingBox();
+         aabb_.merge( b.getAABB() );
+      }
    }
 
    WALBERLA_ASSERT( aabb_.checkInvariant() , "Invalid bounding box detected" );
-   WALBERLA_ASSERT( aabb_.contains( gpos_ ), "Invalid bounding box detected" );
+   WALBERLA_ASSERT( aabb_.contains( getPosition() ), "Invalid bounding box detected" );
 }
 //*************************************************************************************************
 
@@ -364,64 +358,58 @@ void Union<BodyTypes...>::calcCenterOfMass()
    // Don't calculate the center of mass of an empty union
    if( bodies_.isEmpty() ) return;
 
-   // Calculating the center of mass of a single body
-   if( bodies_.size() == 1 )
-   {
-      const BodyID body( bodies_.begin().getBodyID() );
-      gpos_ = body->getPosition();
-      mass_ = body->getMass();
-      if( !isFixed() && mass_ > real_t(0) )
-         invMass_ = real_t(1) / mass_;
-   }
-
-   // Calculating the center of mass of a union containing several bodies
-   else
+   // Resetting the center of mass
+   Vec3 gpos = Vec3(0,0,0);
+   real_t mass = real_t(0.0);
+   // Calculating the center of mass of a finite union
+   if( finite_ )
    {
-      // Resetting the center of mass
-      gpos_.reset();
-
-      // Calculating the center of mass of a finite union
-      if( finite_ )
-      {
-         // Accumulating the mass of all contained rigid bodies
-         for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) {
-            WALBERLA_ASSERT( b->isFinite(), "Invalid infinite body in finite union detected" );
-            mass_ += b->getMass();
-            gpos_ += b->getPosition() * b->getMass();
-         }
-
-         // Calculating the center of mass for unions with non-zero mass
-         if( mass_ > real_t(0) ) {
-            if( !isFixed() ) invMass_ = real_t(1) / mass_;
-            gpos_ /= mass_;
-         }
-
-         // Calculating the center of mass for unions with a mass of zero
-         else {
-            size_t counter( 0 );
-            gpos_.reset();
+      // Accumulating the mass of all contained rigid bodies
+      for( auto &b : bodies_ ) {
+         WALBERLA_ASSERT( b.isFinite(), "Invalid infinite body in finite union detected" );
+         mass += b.getMass();
+         gpos += b.getPosition() * b.getMass();
+      }
 
-            for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) {
-               gpos_ += b->getPosition();
-               ++counter;
-            }
 
-            gpos_ /= counter;
-         }
+      mass_ = mass;
+      // Calculating the center of mass for unions with non-zero mass
+      if( mass > real_t(0) ) {
+         if( !isFixed() ) invMass_ = real_t(1) / mass;
+         gpos /= mass;
       }
 
-      // Calculating the center of mass of an infinite union
+         // Calculating the center of mass for unions with a mass of zero
       else {
          size_t counter( 0 );
 
-         for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) {
-            if( b->isFinite() ) continue;
-            gpos_ += b->getPosition();
+         for( auto &b : bodies_ ) {
+            gpos += b.getPosition();
             ++counter;
          }
 
-         gpos_ /= counter;
+         gpos /= counter;
+      }
+   }
+
+      // Calculating the center of mass of an infinite union
+   else {
+      size_t counter( 0 );
+
+      for( auto &b : bodies_ ) {
+         if( b.isFinite() ) continue;
+         gpos += b.getPosition();
+         ++counter;
       }
+
+      gpos /= counter;
+   }
+
+   // Set new center of mass and adapt all relative positions
+   Vec3 shift = getQuaternion().getInverse().rotate(gpos - getPosition());
+   gpos_ = gpos;
+   for( auto &b : bodies_) {
+      b.setRelPosition(b.getRelPosition() - shift);
    }
 
    // Checking the state of the union
@@ -430,8 +418,12 @@ void Union<BodyTypes...>::calcCenterOfMass()
 //*************************************************************************************************
 
 
+
 //*************************************************************************************************
 /*!\brief Calculation of the moment of inertia in reference to the body frame of the union.
+ *
+ * Use this function only if the center of gravity is set correctly (e.g. after calling
+ * calcCenterOfMass)
  *
  * \return void
  */
@@ -455,7 +447,7 @@ void Union<BodyTypes...>::calcInertia()
    for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
    {
       mass = b->getMass();
-      pos  = b->getPosition() - gpos_;
+      pos  = getRotation() * b->getRelPosition();
 
       I_ += b->getInertia();
       I_[0] += mass * ( pos[1]*pos[1] + pos[2]*pos[2] );
@@ -468,9 +460,8 @@ void Union<BodyTypes...>::calcInertia()
       I_[7] -= mass * pos[1] * pos[2];
       I_[8] += mass * ( pos[0]*pos[0] + pos[1]*pos[1] );
    }
-
    // Rotating the moment of inertia from the global frame of reference to the body frame of reference
-   I_ = R_ * I_ * R_;
+   I_ = getRotation().getTranspose() * I_ * getRotation();
 
    // Calculating the inverse of the body moment of inertia
    if( !isFixed() ) Iinv_ = I_.getInverse();
@@ -504,17 +495,7 @@ void Union<BodyTypes...>::calcInertia()
 template <typename... BodyTypes>
 void Union<BodyTypes...>::setPositionImpl( real_t px, real_t py, real_t pz )
 {
-   Vec3 gpos = Vec3( px, py, pz );
-
-   // Calculating the position change
-   const Vec3 dp( gpos - gpos_ );
-
-   // Setting the global position
-   gpos_ = gpos;
-
-   // Updating the contained bodies
-   for( auto& b : bodies_ )
-      b.update( dp );
+   gpos_ = Vec3( px, py, pz );
 
    Union<BodyTypes...>::calcBoundingBox();    // Setting the axis-aligned bounding box
    wake();               // Waking the union from sleep mode
@@ -542,16 +523,12 @@ void Union<BodyTypes...>::setPositionImpl( real_t px, real_t py, real_t pz )
 template <typename... BodyTypes>
 void Union<BodyTypes...>::setOrientationImpl( real_t r, real_t i, real_t j, real_t k )
 {
-   const Quat q ( r, i, j, k );
-   const Quat dq( q * q_.getInverse() );
+   if ( hasSuperBody() ) return;
 
+   const Quat q ( r, i, j, k );
    q_ = q;
    R_ = q_.toRotationMatrix();
 
-   // Updating the contained bodies
-   for( auto& b : bodies_ )
-      b.update( dq );
-
    Union<BodyTypes...>::calcBoundingBox();  // Setting the axis-aligned bounding box
    wake();             // Waking the union from sleep mode
    signalRotation();   // Signaling the change of orientation to the superordinate body
@@ -560,84 +537,6 @@ void Union<BodyTypes...>::setOrientationImpl( real_t r, real_t i, real_t j, real
 
 
 
-//=================================================================================================
-//
-//  SIMULATION FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Translation update of a subordinate union.
- *
- * \param dp Change in the global position of the superordinate union.
- * \return void
- *
- * This update function is triggered by the superordinate body in case of a translational
- * movement. This movement involves a change in the global position and the axis-aligned
- * bounding box.
- */
-template <typename... BodyTypes>
-void Union<BodyTypes...>::update( const Vec3& dp )
-{
-   // Checking the state of the union
-   WALBERLA_ASSERT( checkInvariants(), "Invalid union state detected" );
-   WALBERLA_ASSERT( hasSuperBody(), "Invalid superordinate body detected" );
-
-   // Updating the global position
-   gpos_ += dp;
-
-   // Updating the contained bodies
-   for( auto& b : bodies_ )
-      b.update( dp );
-
-   // Setting the axis-aligned bounding box
-   Union<BodyTypes...>::calcBoundingBox();
-
-   // Checking the state of the union
-   WALBERLA_ASSERT( checkInvariants(), "Invalid union state detected" );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Rotation update of a subordinate union.
- *
- * \param dq Change in the orientation of the superordinate union.
- * \return void
- *
- * This update function is triggered by the superordinate body in case of a rotational movement.
- * This movement involves a change in the global position, the orientation/rotation and the
- * axis-aligned bounding box of the box.
- */
-template <typename... BodyTypes>
-void Union<BodyTypes...>::update( const Quat& dq )
-{
-   // Checking the state of the union
-   WALBERLA_ASSERT( checkInvariants(), "Invalid union state detected" );
-   WALBERLA_ASSERT( hasSuperBody(), "Invalid superordinate body detected" );
-
-   // Calculating the new global position
-   gpos_ = sb_->getPosition() + ( sb_->getRotation() * rpos_ );
-
-   // Calculating the new orientation and rotation
-   q_ = dq * q_;
-   R_ = q_.toRotationMatrix();
-
-   // Updating the contained bodies
-   for( auto& b : bodies_ )
-      b.update( dq );
-
-   // Setting the axis-aligned bounding box
-   Union<BodyTypes...>::calcBoundingBox();
-
-   // Checking the state of the union
-   WALBERLA_ASSERT( checkInvariants(), "Invalid union state detected" );
-}
-//*************************************************************************************************
-
-
-
-
 //=================================================================================================
 //
 //  RIGID BODY MANAGER FUNCTIONS
@@ -660,9 +559,9 @@ void Union<BodyTypes...>::update( const Quat& dq )
  * The union takes full responsibility for the newly added body, including the necessary
  * memory management. After adding the body to the union, the body is considered part of the
  * union. All functions called on the union (as for instance all kinds of set functions,
- * translation or rotation functions) additionally affect the rigid body. However, the body
- * can still individually be positioned, oriented, translated, rotated, or made (in-)visible
- * within the union.\n\n
+ * translation or rotation functions) additionally define the values for the rigid body
+ * according to its relative position and orientation. Do not call any Set-Functions on the
+ * single rigid body.\n
  *
  *
  * \section union_add_infinite Adding infinite rigid bodies
@@ -704,16 +603,23 @@ RigidBody& Union<BodyTypes...>::add( std::unique_ptr<RigidBody>&& body )
    if( body->isGlobal() ^ global_ )
       throw std::logic_error( "Global flags of body and union do not match" );
 
+   // Only add non-moving particles to a union.
+   WALBERLA_ASSERT_EQUAL(body->getLinearVel(), Vec3());
+   WALBERLA_ASSERT_EQUAL(body->getAngularVel(), Vec3());
+
    // Registering the rigid body
    auto& bd = bodies_.add( std::move(body) );
 
-   Vec3 oldCenterOfMass = getPosition();
-   Vec3 oldImpulse      = getLinearVel() * getMass();
+   Vec3 bdglobalPos = bd.getPosition();
+   Quat bdglobalRot = bd.getQuaternion();
 
-   Vec3 bodyCenterOfMass = bd.getPosition();
-   Vec3 bodyImpulse      = bd.getLinearVel() * bd.getMass();
+   bd.setSB(this);
+   //having a superbody will forward all getVel/Pos/Rot calls to the superbody from now !
 
-   bd.setSB(this); //having a superbody will forward all getVel calls to superbody!!!
+   bd.setRelPosition(getQuaternion().getInverse().rotate(bdglobalPos - getPosition()));
+   bd.setRelOrientation(bdglobalRot * getQuaternion().getInverse());
+   // Update mass, COG and relative positions
+   calcCenterOfMass();
 
    // Updating the axis-aligned bounding box
    if( bodies_.size() == 1 )
@@ -721,24 +627,10 @@ RigidBody& Union<BodyTypes...>::add( std::unique_ptr<RigidBody>&& body )
    else
       aabb_.merge( bd.getAABB() );
 
-   // Setting the union's total mass and center of mass
-   calcCenterOfMass();
-
-   // Setting the contained primitives' relative position in reference to the center of mass
-   for( auto& b : bodies_ )
-      b.calcRelPosition();
 
    // Setting the moment of inertia
    calcInertia();
 
-   //moving impuls to union
-   setLinearVel( Vec3(0,0,0) );
-   setAngularVel( Vec3(0,0,0) );
-   addImpulseAtPos( oldImpulse, oldCenterOfMass);
-   addImpulseAtPos( bodyImpulse, bodyCenterOfMass);
-   bd.setLinearVel( Vec3(0,0,0) );
-   bd.setAngularVel( Vec3(0,0,0) );
-
    // Signaling the internal modification to the superordinate body
    signalModification();
 
@@ -773,10 +665,6 @@ void Union<BodyTypes...>::translateImpl( real_t dx, real_t dy, real_t dz )
    // Changing the global position/reference point
    gpos_ += dp;
 
-   // Updating the contained bodies
-   for( auto& b : bodies_ )
-      b.update( dp );
-
    Union<BodyTypes...>::calcBoundingBox();    // Setting the axis-aligned bounding box
    wake();               // Waking the union from sleep mode
    signalTranslation();  // Signaling the position change to the superordinate body
@@ -813,10 +701,6 @@ void Union<BodyTypes...>::rotateImpl( const Quat& dq )
    q_ = dq * q_;                // Updating the orientation of the union
    R_ = q_.toRotationMatrix();  // Updating the rotation of the union
 
-   // Updating the contained bodies
-   for( auto& b : bodies_ )
-      b.update( dq );
-
    Union<BodyTypes...>::calcBoundingBox();  // Setting the axis-aligned bounding box
    wake();             // Waking the union from sleep mode
    signalRotation();   // Signaling the change of orientation to the superordinate body
@@ -845,10 +729,6 @@ void Union<BodyTypes...>::rotateAroundOriginImpl( const Quat& dq )
    R_    = q_.toRotationMatrix();  // Updating the rotation of the union
    gpos_ = dq.rotate( gpos_ );     // Updating the global position of the union
 
-   // Updating the contained bodies
-   for( auto& b : bodies_ )
-      b.update( dq );
-
    Union<BodyTypes...>::calcBoundingBox();    // Setting the axis-aligned bounding box
    wake();               // Waking the union from sleep mode
    signalTranslation();  // Signaling the position change to the superordinate body
@@ -878,10 +758,6 @@ void Union<BodyTypes...>::rotateAroundPointImpl( const Vec3& point, const Quat &
    R_    = q_.toRotationMatrix();    // Updating the rotation of the union
    gpos_ = point + dq.rotate( dp );  // Updating the global position of the union
 
-   // Updating the contained bodies
-   for( auto& b : bodies_ )
-      b.update( dq );
-
    Union<BodyTypes...>::calcBoundingBox();    // Setting the axis-aligned bounding box
    wake();               // Waking the union from sleep mode
    signalTranslation();  // Signaling the position change to the superordinate body
@@ -977,10 +853,6 @@ void Union<BodyTypes...>::handleModification()
    // Setting the union's total mass and center of mass
    calcCenterOfMass();
 
-   // Setting the contained primitives' relative position in reference to the center of mass
-   for( auto& b : bodies_ )
-      b.calcRelPosition();
-
    // Setting the moment of inertia
    calcInertia();
 
@@ -1007,10 +879,6 @@ void Union<BodyTypes...>::handleTranslation()
    // Setting the union's total mass and center of mass
    calcCenterOfMass();
 
-   // Setting the contained bodies' relative position in reference to the center of mass
-   for( auto& b : bodies_ )
-      b.calcRelPosition();
-
    // Setting the moment of inertia
    calcInertia();
 
@@ -1074,7 +942,6 @@ void Union<BodyTypes...>::print( std::ostream& os, const char* tab ) const
    else os << "*infinite*\n";
 
    os << tab << "   Global position   = " << gpos_ << "\n"
-      << tab << "   Relative position = " << rpos_ << "\n"
       << tab << "   Linear velocity   = " << v_ << "\n"
       << tab << "   Angular velocity  = " << w_ << "\n";
 
diff --git a/src/pe/rigidbody/UnionFactory.h b/src/pe/rigidbody/UnionFactory.h
index 62fe5828e..6ad1d934e 100644
--- a/src/pe/rigidbody/UnionFactory.h
+++ b/src/pe/rigidbody/UnionFactory.h
@@ -82,7 +82,7 @@ Union<BodyTypes...>* createUnion(   BodyStorage& globalStorage, BlockStorage& bl
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      auto un = std::make_unique<Union<BodyTypes...>>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, false, true);
+      auto un = std::make_unique<Union<BodyTypes...>>(sid, uid, gpos, Quat(), global, false, true);
       bd = static_cast<Union<BodyTypes...>*>(&globalStorage.add(std::move(un)));
    } else
    {
@@ -92,7 +92,7 @@ Union<BodyTypes...>* createUnion(   BodyStorage& globalStorage, BlockStorage& bl
             const id_t sid( UniqueID<RigidBody>::create() );
 
             BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
-            auto un = std::make_unique<Union<BodyTypes...>>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, communicating, infiniteMass);
+            auto un = std::make_unique<Union<BodyTypes...>>(sid, uid, gpos, Quat(), global, communicating, infiniteMass);
             un->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
             bd = static_cast<Union<BodyTypes...>*>(&bs.add(std::move(un)));
          }
@@ -156,7 +156,7 @@ BoxID createBox( Union<BodyTypes...>* un,
       sid = UniqueID<RigidBody>::create();
    }
 
-   std::unique_ptr<Box> box = std::make_unique<Box>(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass);
+   std::unique_ptr<Box> box = std::make_unique<Box>(sid, uid, gpos, Quat(), lengths, material, global, communicating, infiniteMass);
    box->MPITrait.setOwner( un->MPITrait.getOwner() );
 
    if (box != NULL)
@@ -226,7 +226,7 @@ CapsuleID createCapsule( Union<BodyTypes...>* un,
       sid = UniqueID<RigidBody>::create();
    }
 
-   std::unique_ptr<Capsule> capsule = std::make_unique<Capsule>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass);
+   std::unique_ptr<Capsule> capsule = std::make_unique<Capsule>(sid, uid, gpos, Quat(), radius, length, material, global, communicating, infiniteMass);
    capsule->MPITrait.setOwner( un->MPITrait.getOwner() );
 
    if (capsule != NULL)
@@ -284,7 +284,7 @@ SphereID createSphere( Union<BodyTypes...>* un,
       sid = UniqueID<RigidBody>::create();
    }
 
-   std::unique_ptr<Sphere> sphere = std::make_unique<Sphere>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass);
+   std::unique_ptr<Sphere> sphere = std::make_unique<Sphere>(sid, uid, gpos, Quat(), radius, material, global, communicating, infiniteMass);
    sphere->MPITrait.setOwner( un->MPITrait.getOwner() );
 
    if (sphere != NULL)
diff --git a/tests/mesh/MeshMarshalling.cpp b/tests/mesh/MeshMarshalling.cpp
index 15e6bd675..cc62c6a63 100644
--- a/tests/mesh/MeshMarshalling.cpp
+++ b/tests/mesh/MeshMarshalling.cpp
@@ -62,8 +62,8 @@ std::vector<Vector3<real_t>> generateOctahedron( const real_t radius)
 void checkMeshEquals(const mesh::TriangleMesh &m1, const mesh::TriangleMesh &m2){
 	// Very basic checks
 	WALBERLA_CHECK_FLOAT_EQUAL(mesh::computeVolume(m1), mesh::computeVolume(m2));
-	WALBERLA_CHECK_EQUAL(mesh::computeCentroid(m1), mesh::computeCentroid(m2));
-	WALBERLA_CHECK_EQUAL(mesh::computeInertiaTensor(m1), mesh::computeInertiaTensor(m2));
+	WALBERLA_CHECK_FLOAT_EQUAL(mesh::toWalberla(mesh::computeCentroid(m1)), mesh::toWalberla(mesh::computeCentroid(m2)));
+	WALBERLA_CHECK_FLOAT_EQUAL(mesh::computeInertiaTensor(m1), mesh::computeInertiaTensor(m2));
 }
 
 // Checks two convexPolyhedrons for equality
@@ -71,8 +71,10 @@ void checkConvexPolyhedronEquals(const mesh::pe::ConvexPolyhedron &b1, const mes
    WALBERLA_CHECK_FLOAT_EQUAL(b1.getPosition(), b2.getPosition());
    WALBERLA_CHECK_FLOAT_EQUAL(b1.getLinearVel(), b2.getLinearVel());
    WALBERLA_CHECK_FLOAT_EQUAL(b1.getAngularVel(), b2.getAngularVel());
-   WALBERLA_CHECK_EQUAL(b1.getInertia(), b2.getInertia());
+   WALBERLA_CHECK_FLOAT_EQUAL(b1.getInertia(), b2.getInertia());
    WALBERLA_CHECK_EQUAL(b1.getMaterial(), b2.getMaterial());
+   WALBERLA_CHECK_FLOAT_EQUAL(b1.getQuaternion(), b2.getQuaternion());
+   WALBERLA_CHECK_FLOAT_EQUAL(b1.getRotation(), b2.getRotation());
    // Check equality of the meshes
    checkMeshEquals(b1.getMesh(), b2.getMesh());
    WALBERLA_CHECK_EQUAL(b1.getID(), b2.getID());
@@ -90,7 +92,7 @@ void testConvexPolyhedron()
    
    MaterialID iron = Material::find("iron");
    
-   mesh::pe::ConvexPolyhedron b1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), *octamesh, iron, false, true, false);
+   mesh::pe::ConvexPolyhedron b1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Quat(), *octamesh, iron, false, true, false);
    b1.setLinearVel(Vec3(real_c(5.2), real_c(6.3), real_c(7.4)));
    b1.setAngularVel(Vec3(real_c(1.2), real_c(2.3), real_c(3.4)));
 
@@ -99,7 +101,7 @@ void testConvexPolyhedron()
    mpi::RecvBuffer rb(sb);
 
    auto bPtr = UnmarshalDynamically<BodyTuple>::execute(rb, mesh::pe::ConvexPolyhedron::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)));
-   mesh::pe::ConvexPolyhedronID b2 = static_cast<mesh::pe::ConvexPolyhedronID>(bPtr.get());
+   auto b2 = dynamic_cast<mesh::pe::ConvexPolyhedronID>(bPtr.get());
    checkConvexPolyhedronEquals(b1, *b2);
    
 }
@@ -114,11 +116,12 @@ void testUnion()
    qhull.run();
    
    MaterialID iron = Material::find("iron");
-   
-   UnionT u1(159, 423, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), false, false, false);
-   u1.add(std::make_unique<mesh::pe::ConvexPolyhedron>(753326, 1267824, Vec3(real_c(2), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), *octamesh, iron, false, true, false));
-   u1.add(std::make_unique<mesh::pe::ConvexPolyhedron>(753246, 1233424, Vec3(real_c(-1), real_c(4), real_c(-2)), Vec3(0,0,0), Quat(), *octamesh, iron, false, true, false));
-   
+   Quat q(real_t(0.3), real_t(0.1), real_t(0.9), real_t(0.3));
+   Quat w(real_t(0.1), real_t(0.3), real_t(0.9), real_t(0.3));
+   UnionT u1(159, 423, Vec3(real_c(1), real_c(2), real_c(3)),  q, false, false, false);
+   u1.add(std::make_unique<mesh::pe::ConvexPolyhedron>(753326, 1267824, Vec3(real_c(2), real_c(2), real_c(3)), w, *octamesh, iron, false, true, false));
+   u1.add(std::make_unique<mesh::pe::ConvexPolyhedron>(753246, 1233424, Vec3(real_c(-1), real_c(4), real_c(-2)), w, *octamesh, iron, false, true, false));
+
    u1.setLinearVel(Vec3(real_c(5.2), real_c(6.3), real_c(7.4)));
    u1.setAngularVel(Vec3(real_c(1.2), real_c(2.3), real_c(3.4)));
    
@@ -127,23 +130,24 @@ void testUnion()
    mpi::RecvBuffer rb(sb);
 
    auto uPtr = UnmarshalDynamically<BodyTuple>::execute(rb, UnionT::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)));
-   UnionID u2 = static_cast<UnionID>(uPtr.get());
+   auto u2 = dynamic_cast<UnionID>(uPtr.get());
    WALBERLA_CHECK_NOT_NULLPTR( u2 );
-
    WALBERLA_CHECK_EQUAL(u1.size(), 2);
    WALBERLA_CHECK_EQUAL(u1.size(), u2->size());
-   WALBERLA_CHECK_EQUAL(u1.getInertia(), u2->getInertia());
-   WALBERLA_CHECK_EQUAL(u1.getPosition(), u2->getPosition());
+   WALBERLA_CHECK_FLOAT_EQUAL(u1.getInertia(), u2->getInertia());
+   WALBERLA_CHECK_FLOAT_EQUAL(u1.getPosition(), u2->getPosition());
    WALBERLA_CHECK_FLOAT_EQUAL(u1.getLinearVel(), u2->getLinearVel());
    WALBERLA_CHECK_FLOAT_EQUAL(u1.getAngularVel(), u2->getAngularVel());
-   
+   WALBERLA_CHECK_FLOAT_EQUAL(u1.getQuaternion(), u2->getQuaternion());
+   WALBERLA_CHECK_FLOAT_EQUAL(u1.getRotation(), u2->getRotation());
+
    //getting polyhedrons of first union
-   mesh::pe::ConvexPolyhedronID p11 = static_cast<mesh::pe::ConvexPolyhedronID > (u1.begin().getBodyID());
-   mesh::pe::ConvexPolyhedronID p21 = static_cast<mesh::pe::ConvexPolyhedronID > ((++(u1.begin())).getBodyID());
+   mesh::pe::ConvexPolyhedronID p11 = dynamic_cast<mesh::pe::ConvexPolyhedronID > (u1.begin().getBodyID());
+   mesh::pe::ConvexPolyhedronID p21 = dynamic_cast<mesh::pe::ConvexPolyhedronID > ((++(u1.begin())).getBodyID());
    
    //getting polyhedrons of second union
-   mesh::pe::ConvexPolyhedronID p12 = static_cast<mesh::pe::ConvexPolyhedronID > (u2->begin().getBodyID());
-   mesh::pe::ConvexPolyhedronID p22 = static_cast<mesh::pe::ConvexPolyhedronID > ((++(u2->begin())).getBodyID());
+   mesh::pe::ConvexPolyhedronID p12 = dynamic_cast<mesh::pe::ConvexPolyhedronID > (u2->begin().getBodyID());
+   mesh::pe::ConvexPolyhedronID p22 = dynamic_cast<mesh::pe::ConvexPolyhedronID > ((++(u2->begin())).getBodyID());
    
    checkConvexPolyhedronEquals(*p11, *p12);
    checkConvexPolyhedronEquals(*p21, *p22);
diff --git a/tests/mesh/MeshPeRaytracing.cpp b/tests/mesh/MeshPeRaytracing.cpp
index ce8f27992..a31dd985a 100644
--- a/tests/mesh/MeshPeRaytracing.cpp
+++ b/tests/mesh/MeshPeRaytracing.cpp
@@ -58,9 +58,9 @@ int CpRayIntersectionTest(const int resolution = 10)
 
    const Vec3 center(1,2,3);
 
-   ConvexPolyhedron cp(0, 0, center, Vec3(0,0,0), Quat(), *mesh, Material::find("iron"), false, true, true);
+   ConvexPolyhedron cp(0, 0, center,Quat(), *mesh, Material::find("iron"), false, true, true);
    cp.rotate(real_t(1), real_t(2), real_t(3));
-   Box bx(0, 0, center, Vec3(0,0,0), Quat(), Vec3(2,2,2), Material::find("iron"), false, true, true);
+   Box bx(0, 0, center, Quat(), Vec3(2,2,2), Material::find("iron"), false, true, true);
    bx.rotate(real_t(1), real_t(2), real_t(3));
 
    real_t dx = real_t(1.0) / static_cast<real_t>(resolution);
diff --git a/tests/pe/BodyFlags.cpp b/tests/pe/BodyFlags.cpp
index fa6db7e1c..cd4f10542 100644
--- a/tests/pe/BodyFlags.cpp
+++ b/tests/pe/BodyFlags.cpp
@@ -70,12 +70,12 @@ int main( int argc, char ** argv )
 
    MaterialID iron = Material::find("iron");
 
-   Sphere refGlobalSphere(1, 0, Vec3(9, 9, 9), Vec3(0,0,0), Quat(), 3, iron, true, false, true);
+   Sphere refGlobalSphere(1, 0, Vec3(9, 9, 9),  Quat(), 3, iron, true, false, true);
    refGlobalSphere.setLinearVel(Vec3(2,2,2));
    SphereID globalSphere = createSphere( *globalStorage, forest->getBlockStorage(), storageID, 0, Vec3(9,9,9), 3, iron, true, false, true);
    globalSphere->setLinearVel(Vec3(2,2,2));
 
-   Sphere refFixedSphere(2, 0, Vec3(9,9,14), Vec3(0,0,0), Quat(), 3, iron, false, false, true);
+   Sphere refFixedSphere(2, 0, Vec3(9,9,14), Quat(), 3, iron, false, false, true);
    SphereID fixedSphere = createSphere( *globalStorage, forest->getBlockStorage(), storageID, 0, Vec3(9,9,14), 3, iron, false, false, true);
    walberla::id_t fixedSphereID = 0;
    if (fixedSphere != nullptr) fixedSphereID = fixedSphere->getSystemID();
diff --git a/tests/pe/BodyStorage.cpp b/tests/pe/BodyStorage.cpp
index 730639317..1ebdc53fd 100644
--- a/tests/pe/BodyStorage.cpp
+++ b/tests/pe/BodyStorage.cpp
@@ -31,14 +31,14 @@ using namespace walberla::pe;
 class Body1 : public Sphere {
 public:
     static int refCount;
-    Body1(walberla::id_t id, MaterialID matID) : Sphere(id, id, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, matID, false, true, false) {++refCount;}
+    Body1(walberla::id_t id, MaterialID matID) : Sphere(id, id, Vec3(0,0,0), Quat(), 1, matID, false, true, false) {++refCount;}
     ~Body1() override {--refCount;}
 };
 
 class Body2 : public Sphere {
 public:
     static int refCount;
-    Body2(walberla::id_t id, MaterialID matID) : Sphere(id, id, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, matID, false, true, false) {++refCount;}
+    Body2(walberla::id_t id, MaterialID matID) : Sphere(id, id, Vec3(0,0,0), Quat(), 1, matID, false, true, false) {++refCount;}
     ~Body2() override {--refCount;}
 };
 
diff --git a/tests/pe/CMakeLists.txt b/tests/pe/CMakeLists.txt
index ec3aab3f8..ca5346fa4 100644
--- a/tests/pe/CMakeLists.txt
+++ b/tests/pe/CMakeLists.txt
@@ -138,6 +138,11 @@ waLBerla_execute_test( NAME   PE_STATICTYPEIDS )
 waLBerla_compile_test( NAME   PE_UNION FILES Union.cpp DEPENDS core  )
 waLBerla_execute_test( NAME   PE_UNION )
 
+waLBerla_compile_test( NAME   PE_UNIONBEHAVIOR FILES UnionBehavior.cpp DEPENDS core  )
+if( WALBERLA_DOUBLE_ACCURACY )
+waLBerla_execute_test( NAME   PE_UNIONBEHAVIOR )
+endif()
+
 waLBerla_compile_test( NAME   PE_RAYTRACING FILES Raytracing.cpp DEPENDS core  )
 waLBerla_execute_test( NAME   PE_RAYTRACING )
 
diff --git a/tests/pe/CheckVitalParameters.cpp b/tests/pe/CheckVitalParameters.cpp
index 063b1b2b3..77325b726 100644
--- a/tests/pe/CheckVitalParameters.cpp
+++ b/tests/pe/CheckVitalParameters.cpp
@@ -34,7 +34,7 @@ int main( int argc, char ** argv )
    WALBERLA_UNUSED(env);
 
    MaterialID iron = Material::find("iron");
-   Sphere sphere(walberla::UniqueID<RigidBody>::create(), 0, Vec3(15, 15, 15), Vec3(0,0,0), Quat(), 3, iron, false, true, false );
+   Sphere sphere(walberla::UniqueID<RigidBody>::create(), 0, Vec3(15, 15, 15), Quat(), 3, iron, false, true, false );
    sphere.MPITrait.setOwner( Owner(0, walberla::blockforest::BlockID().getID() ) );
    checkVitalParameters( &sphere, &sphere );
 
diff --git a/tests/pe/Collision.cpp b/tests/pe/Collision.cpp
index 76f054583..a69762d7f 100644
--- a/tests/pe/Collision.cpp
+++ b/tests/pe/Collision.cpp
@@ -55,10 +55,10 @@ void checkContact(const Contact& c1, const Contact& c2)
 void SphereTest()
 {
    MaterialID iron = Material::find("iron");
-   Sphere sp1(123, 1, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   Sphere sp2(124, 2, Vec3(real_t(1.5),0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   Sphere sp3(125, 3, Vec3(real_t(3.0),0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   Sphere sp4(124, 2, Vec3(0,real_t(1.5),0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
+   Sphere sp1(123, 1, Vec3(0,0,0), Quat(), 1, iron, false, true, false);
+   Sphere sp2(124, 2, Vec3(real_t(1.5),0,0), Quat(), 1, iron, false, true, false);
+   Sphere sp3(125, 3, Vec3(real_t(3.0),0,0), Quat(), 1, iron, false, true, false);
+   Sphere sp4(124, 2, Vec3(0,real_t(1.5),0), Quat(), 1, iron, false, true, false);
    Plane  pl1(223, 1, Vec3(0,0,0), Vec3(1,1,1).getNormalized(), 0, iron);
    CylindricalBoundary cb1(333, 0, Vec3(-100,0,0), 2, iron);
 
@@ -112,13 +112,13 @@ void SphereTest()
 void BoxTest()
 {
    MaterialID iron = Material::find("iron");
-   Box b1(123, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
-   Box b2(124, 0, Vec3(real_t(1.5),0,0), Vec3(0,0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
-   Box b3(125, 0, Vec3(real_t(3.0),0,0), Vec3(0,0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
-   Box b4(123, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
+   Box b1(123, 0, Vec3(0,0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
+   Box b2(124, 0, Vec3(real_t(1.5),0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
+   Box b3(125, 0, Vec3(real_t(3.0),0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
+   Box b4(123, 0, Vec3(0,0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
    b4.rotate( Vec3(1,1,0), real_t(atan(sqrt(2))) );
 
-   Box b5(123, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
+   Box b5(123, 0, Vec3(0,0,0), Quat(), Vec3(2,2,2), iron, false, true, false);
    b5.rotate( Vec3(0,0,1), real_t(math::M_PI * 0.25) );
    b5.rotate( Vec3(1,0,0), real_t(math::M_PI * 0.25) );
 
@@ -157,7 +157,7 @@ void BoxTest()
    b5.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 1.01);
    WALBERLA_CHECK( !collideFunc(&b1, &b5) );
 
-   Sphere s1(126, 0, Vec3(real_t(1.5), real_t(1.5), real_t(1.5)), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
+   Sphere s1(126, 0, Vec3(real_t(1.5), real_t(1.5), real_t(1.5)), Quat(), 1, iron, false, true, false);
    WALBERLA_CHECK( collideFunc(&b1, &s1) );
 //   WALBERLA_LOG_WARNING("contactPoint    : " << contactPoint);
 //   WALBERLA_LOG_WARNING("contactNormal   : " << contactNormal);
@@ -167,8 +167,8 @@ void BoxTest()
 void CapsuleTest()
 {
    MaterialID iron = Material::find("iron");
-   Capsule c1(100, 100, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, 2, iron, false, true, false);
-   Sphere sp1(123, 123, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
+   Capsule c1(100, 100, Vec3(0,0,0), Quat(), 1, 2, iron, false, true, false);
+   Sphere sp1(123, 123, Vec3(0,0,0), Quat(), 1, iron, false, true, false);
 
    std::vector<Contact> contacts;
    fcd::AnalyticCollideFunctor< std::vector<Contact> > collideFunc(contacts);
@@ -210,9 +210,9 @@ void CapsuleTest2()
    const real_t   dynamic_cof ( static_cof ); // Coefficient of dynamic friction. Similar to static friction for low speed friction.
    MaterialID     material = createMaterial( "granular", real_t( 1.0 ), 0, static_cof, dynamic_cof, real_t( 0.5 ), 1, 1, 0, 0 );
    //create obstacle
-   Capsule c1(100, 100, Vec3(10,10,0), Vec3(0,0,0), Quat(), 3, 40, material, false, true, false);
+   Capsule c1(100, 100, Vec3(10,10,0), Quat(), 3, 40, material, false, true, false);
    c1.rotate( Vec3(0,1,0), math::M_PI * real_t(0.5) );
-   Sphere sp1(123, 123, Vec3(real_t(6.5316496854295262864), real_t(10.099999999999999645), real_t(0.46999999991564372914) ), Vec3(0,0,0), Quat(), real_t(0.47), material, false, true, false);
+   Sphere sp1(123, 123, Vec3(real_t(6.5316496854295262864), real_t(10.099999999999999645), real_t(0.46999999991564372914) ), Quat(), real_t(0.47), material, false, true, false);
 
    std::vector<Contact> contacts;
 
@@ -236,8 +236,8 @@ void CapsuleTest2()
 void UnionTest()
 {
    using UnionT = Union<Sphere>;
-   UnionT  un1(120, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), false, true, false);
-   UnionT  un2(121, 0, Vec3(real_t(1.5),0,0), Vec3(0,0,0), Quat(), false, true, false);
+   UnionT  un1(120, 0, Vec3(0,0,0), Quat(), false, true, false);
+   UnionT  un2(121, 0, Vec3(real_t(1.5),0,0), Quat(), false, true, false);
    auto sp1 = createSphere(&un1, 123, Vec3(0,0,0), 1);
    auto sp2 = createSphere(&un2, 124, Vec3(real_t(1.5),0,0), 1);
 
diff --git a/tests/pe/CollisionTobiasGJK.cpp b/tests/pe/CollisionTobiasGJK.cpp
index 6473222d0..41bdf1f69 100644
--- a/tests/pe/CollisionTobiasGJK.cpp
+++ b/tests/pe/CollisionTobiasGJK.cpp
@@ -160,9 +160,9 @@ void MainTest()
    MaterialID iron = Material::find("iron");
 
    // Original SPHERE <-> SPHERE
-   Sphere sp1(123, 1, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   Sphere sp2(124, 2, Vec3(real_t(1.5),0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   Sphere sp3(125, 3, Vec3(real_t(3.0),0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
+   Sphere sp1(123, 1, Vec3(0,0,0), Quat(), 1, iron, false, true, false);
+   Sphere sp2(124, 2, Vec3(real_t(1.5),0,0), Quat(), 1, iron, false, true, false);
+   Sphere sp3(125, 3, Vec3(real_t(3.0),0,0), Quat(), 1, iron, false, true, false);
 
    Vec3     normal;
    Vec3     contactPoint;
@@ -179,8 +179,8 @@ void MainTest()
    WALBERLA_LOG_INFO("Test 01: BOX <-> SPHERE");
    real_t sqr3_inv = real_t(1.0)/std::sqrt(real_t(3.0));
    real_t coordinate= real_t(5.0)* sqr3_inv + real_t(5.0); // 5*(1+ (1/sqrt(3)))
-   Box box1_1(127, 5, Vec3(0, 0, 0), Vec3(0,0,0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
-   Sphere sphere1_2(130, 8, Vec3(coordinate, coordinate, coordinate), Vec3(0,0,0), Quat(), 5, iron, false, true, false);
+   Box box1_1(127, 5, Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
+   Sphere sphere1_2(130, 8, Vec3(coordinate, coordinate, coordinate), Quat(), 5, iron, false, true, false);
    Vec3 wp1(real_t(5.0), real_t(5.0), real_t(5.0));
    Vec3 wpm1(sqr3_inv*real_t(-0.5), sqr3_inv*real_t(-0.5), sqr3_inv*real_t(-0.5));
    Vec3 axis1(-sqr3_inv, -sqr3_inv, -sqr3_inv);
@@ -189,7 +189,7 @@ void MainTest()
    //Testcase 02 Box LongBox (touching plane)
    //Reuse box1_1
    WALBERLA_LOG_INFO("Test 02: BOX <-> LONG BOX");
-   Box box2_1(131, 9, Vec3(real_t(20.0),0,0), Vec3(0,0,0), Quat(), Vec3(real_t(30.0),1,1), iron, false, true, false);
+   Box box2_1(131, 9, Vec3(real_t(20.0),0,0),  Quat(), Vec3(real_t(30.0),1,1), iron, false, true, false);
    Vec3 wp2(5, 0, 0);
    Vec3 wpm2(real_t(-0.5),0,0);
    Vec3 axis2(-1,0,0);
@@ -197,8 +197,8 @@ void MainTest()
 
    //Testcase 03 Sphere Sphere
    WALBERLA_LOG_INFO("Test 03: SPHERE <-> SPHERE");
-   Sphere sphere3_1(129, 7, Vec3(0,0,0), Vec3(0,0,0), Quat(), 5, iron, false, true, false);
-   Sphere sphere3_2(128, 6, Vec3(real_t(10.0),0,0), Vec3(0,0,0), Quat(), 5, iron, false, true, false);
+   Sphere sphere3_1(129, 7, Vec3(0,0,0), Quat(), 5, iron, false, true, false);
+   Sphere sphere3_2(128, 6, Vec3(real_t(10.0),0,0), Quat(), 5, iron, false, true, false);
    Vec3 wp3(5, 0, 0);
    Vec3 wpm3(real_t(-0.5),0,0);
    Vec3 axis3(-1,0,0);
@@ -213,8 +213,8 @@ void MainTest()
 
    //create turned box
    real_t sqr2 = std::sqrt(real_t(2.0));
-   Box box4_1(132, 10, Vec3(real_t(5.0)*(real_t(1.0)+sqr2), real_t(-5.0), 0), Vec3(0,0,0), q4, Vec3(10, 10, 10), iron, false, true, false);
-   Box box4_2(133, 11, Vec3(0, 0, 0), Vec3(0,0,0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
+   Box box4_1(132, 10, Vec3(real_t(5.0)*(real_t(1.0)+sqr2), real_t(-5.0), 0), q4, Vec3(10, 10, 10), iron, false, true, false);
+   Box box4_2(133, 11, Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
    Vec3 wp4(5, -5, 0);
    Vec3 wpm4(real_t(-0.25),real_t(+0.25),0);
    Vec3 collision_axis4(-sqr2/real_t(2.0),+sqr2/real_t(2.0),0);
@@ -224,8 +224,8 @@ void MainTest()
 
    //Testcase 05 Cube and Long Box non-centric (touching plane)
    WALBERLA_LOG_INFO("Test 05: CUBE <-> LONG BOX (NON_CENTRIC)");
-   Box box5_1(133, 12, Vec3(0, 0, 0), Vec3(0,0,0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
-   Box box5_2(134, 13, Vec3(real_t(15.0),real_t(5.5), 0), Vec3(0,0,0), Quat(), Vec3(real_t(30.0),1,1), iron, false, true, false);
+   Box box5_1(133, 12, Vec3(0, 0, 0),  Quat(), Vec3(10, 10, 10), iron, false, true, false);
+   Box box5_2(134, 13, Vec3(real_t(15.0),real_t(5.5), 0), Quat(), Vec3(real_t(30.0),1,1), iron, false, true, false);
    Vec3 wp5(real_t(3.75), 5, 0);
    Vec3 wpm5(0, real_t(-0.5), 0);
    Vec3 axis5(0, -1, 0);
@@ -243,8 +243,8 @@ void MainTest()
    Quat q6(rot_axis6, angle6);
 
    //create turned box with pos = (5*(1+sqrt(3)), 0, 0)
-   Box box6_1(136, 14, Vec3(real_t(5.0)*(real_t(1.0)+sqr6_3), 0, 0), Vec3(0,0,0), q6, Vec3(10, 10, 10), iron, false, true, false);
-   Box box6_2(136, 15, Vec3(0, 0, 0), Vec3(0,0,0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
+   Box box6_1(136, 14, Vec3(real_t(5.0)*(real_t(1.0)+sqr6_3), 0, 0),  q6, Vec3(10, 10, 10), iron, false, true, false);
+   Box box6_2(136, 15, Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
    Vec3 wp6(5, 0, 0);
    Vec3 wpm6(real_t(-0.5), 0, 0);
    Vec3 axis6(-1, 0, 0);
@@ -253,8 +253,8 @@ void MainTest()
    //Testcase 07:
    // BOX <-> SPHERE
    WALBERLA_LOG_INFO("Test 07: BOX <-> SPHERE");
-   Sphere sphere7_1(137, 16, Vec3(0,0,0), Vec3(0,0,0), Quat(), 5, iron, false, true, false);
-   Box box7_2(138, 17, Vec3(0, 0,real_t(7.5)), Vec3(0,0,0), Quat(), Vec3(5, 5, 5), iron, false, true, false);
+   Sphere sphere7_1(137, 16, Vec3(0,0,0),  Quat(), 5, iron, false, true, false);
+   Box box7_2(138, 17, Vec3(0, 0,real_t(7.5)), Quat(), Vec3(5, 5, 5), iron, false, true, false);
    Vec3 wpm7(0, 0, real_t(-0.5));
    Vec3 wp7(0, 0, real_t(5.0));
    Vec3 axis7(0, 0,  real_t(-1.0));
@@ -264,8 +264,8 @@ void MainTest()
    // CAPSULE <-> CAPSULE
    WALBERLA_LOG_INFO("Test 08: CAPSULE <-> CAPSULE");
    Quat q8(Vec3(0,1,0), walberla::math::M_PI/real_t(2.0)); //creates a y-axis aligned capsule
-   Capsule cap8_1(139, 18, Vec3(0,0,0), Vec3(0,0,0), Quat(), real_t(4.0), real_t(10.0), iron, false, true, false);
-   Capsule cap8_2(140, 19, Vec3(0,0, real_t(13.0)), Vec3(0,0,0), q8, real_t(4.0), real_t(10.0), iron, false, true, false);
+   Capsule cap8_1(139, 18, Vec3(0,0,0), Quat(), real_t(4.0), real_t(10.0), iron, false, true, false);
+   Capsule cap8_2(140, 19, Vec3(0,0, real_t(13.0)),  q8, real_t(4.0), real_t(10.0), iron, false, true, false);
    Vec3 wpm8(0, 0, real_t(-0.5));
    Vec3 wp8(0, 0, real_t(4.0));
    Vec3 axis8(0, 0,  real_t(-1.0));
@@ -274,8 +274,8 @@ void MainTest()
    //Testcase 09:
    // ELLIPSOID <-> ELLIPSOID
    WALBERLA_LOG_INFO("Test 09: ELLIPSOID <-> ELLIPSOID");
-   Ellipsoid ell9_1(141, 20, Vec3(0,0,0), Vec3(0,0,0), Quat(), Vec3(10,5,5), iron, false, true, false);
-   Ellipsoid ell9_2(142, 21, Vec3(15,0,0), Vec3(0,0,0), Quat(), Vec3(5,10,5), iron, false, true, false);
+   Ellipsoid ell9_1(141, 20, Vec3(0,0,0), Quat(), Vec3(10,5,5), iron, false, true, false);
+   Ellipsoid ell9_2(142, 21, Vec3(15,0,0), Quat(), Vec3(5,10,5), iron, false, true, false);
    Vec3 wpm9(real_t(-0.5), 0, 0);
    Vec3 wp9(real_t(10), 0, 0);
    Vec3 axis9(real_t(-1.0), 0, 0);
@@ -292,8 +292,8 @@ void PlaneTest()
    fcd::GenericFCD<BodyTuple, fcd::GJKEPACollideFunctor> testFCD;
 
    Plane pl(1, 1, Vec3(0, 1, 0), Vec3(0, 1, 0), real_t(1.0), iron );
-   Sphere sphere(2, 2, Vec3(0, real_t(1.9), 0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   Sphere sphere2(3, 3, Vec3(0, real_t(0.1), 0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
+   Sphere sphere(2, 2, Vec3(0, real_t(1.9), 0), Quat(), 1, iron, false, true, false);
+   Sphere sphere2(3, 3, Vec3(0, real_t(0.1), 0), Quat(), 1, iron, false, true, false);
 
    PossibleContacts pcs;
 
@@ -353,17 +353,17 @@ void UnionTest(){
    fcd::GenericFCD<BodyTuple, fcd::GJKEPACollideFunctor> testFCD;
 
    //A recursive union of three spheres is dropped on a box.
-   Box box(179, 179, Vec3(0,0,0), Vec3(0,0,0), Quat(), Vec3(real_t(10),real_t(2), real_t(10)), iron, false, true, false);
+   Box box(179, 179, Vec3(0,0,0), Quat(), Vec3(real_t(10),real_t(2), real_t(10)), iron, false, true, false);
 
 
    using UnionT = Union<Sphere>;
-   auto unsub = std::make_unique<UnionT>(192, 192, Vec3(0,real_t(3.8),0), Vec3(0,0,0), Quat(), false, true, false);
+   auto unsub = std::make_unique<UnionT>(192, 192, Vec3(0,real_t(3.8),0), Quat(), false, true, false);
 
    auto sp1 = createSphere(unsub.get(), 180, Vec3(-3,real_t(3.8),0), real_t(3.0));
    auto sp2 = createSphere(unsub.get(), 181, Vec3(3,real_t(3.8),0), real_t(3.0));
 
    //Create another union, and add sub union
-   Union<Sphere, Union<Sphere>> un(193, 193, Vec3(0, 0, 0), Vec3(0,0,0), Quat(), false, true, false);
+   Union<Sphere, Union<Sphere>> un(193, 193, Vec3(0,0,0), Quat(), false, true, false);
    createSphere(&un, 182, Vec3(0,real_t(6),0), real_t(3.0));
    un.add(std::move(unsub));
 
diff --git a/tests/pe/Marshalling.cpp b/tests/pe/Marshalling.cpp
index fc18f19eb..52702aa49 100644
--- a/tests/pe/Marshalling.cpp
+++ b/tests/pe/Marshalling.cpp
@@ -50,7 +50,7 @@ void testBox()
 
    MaterialID iron = Material::find("iron");
 
-   Box b1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), Vec3(1,2,3), iron, false, true, false);
+   Box b1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Quat(), Vec3(1,2,3), iron, false, true, false);
    b1.setLinearVel(Vec3(real_c(5.2), real_c(6.3), real_c(7.4)));
    b1.setAngularVel(Vec3(real_c(1.2), real_c(2.3), real_c(3.4)));
 
@@ -75,7 +75,7 @@ void testCapsule()
 
    MaterialID iron = Material::find("iron");
 
-   Capsule c1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), 5, 7, iron, false, false, false);
+   Capsule c1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Quat(), 5, 7, iron, false, false, false);
    c1.setLinearVel(Vec3(real_c(5.2), real_c(6.3), real_c(7.4)));
    c1.setAngularVel(Vec3(real_c(1.2), real_c(2.3), real_c(3.4)));
 
@@ -101,7 +101,7 @@ void testSphere()
 
    MaterialID iron = Material::find("iron");
 
-   Sphere s1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), 5, iron, false, false, false);
+   Sphere s1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)),  Quat(), 5, iron, false, false, false);
    s1.setLinearVel(Vec3(real_c(5.2), real_c(6.3), real_c(7.4)));
    s1.setAngularVel(Vec3(real_c(1.2), real_c(2.3), real_c(3.4)));
 
@@ -126,7 +126,7 @@ void testSquirmer()
 
    MaterialID iron = Material::find("iron");
 
-   Squirmer s1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), real_c(5), real_c(0.1), real_c(4.93), iron, false, false, false);
+   Squirmer s1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Quat(), real_c(5), real_c(0.1), real_c(4.93), iron, false, false, false);
 
    mpi::SendBuffer sb;
    WALBERLA_ASSERT_UNEQUAL(Sphere::getStaticTypeID(), Squirmer::getStaticTypeID(), "Squirmer did not get its own type ID");
@@ -147,7 +147,7 @@ void testEllipsoid()
 
    MaterialID iron = Material::find("iron");
 
-   Ellipsoid e1(759847, 1234795, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), Vec3(3,1,5), iron, false, false, false);
+   Ellipsoid e1(759847, 1234795, Vec3(real_c(1), real_c(2), real_c(3)), Quat(), Vec3(3,1,5), iron, false, false, false);
    e1.setLinearVel(Vec3(real_c(5.2), real_c(6.3), real_c(7.4)));
    e1.setAngularVel(Vec3(real_c(1.2), real_c(2.3), real_c(3.4)));
 
@@ -169,7 +169,7 @@ void testEllipsoid()
 void testUnion()
 {
    WALBERLA_LOG_INFO_ON_ROOT("*** testUnion ***");
-   UnionT u1(159, 423, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), false, false, false);
+   UnionT u1(159, 423, Vec3(real_c(1), real_c(2), real_c(3)), Quat(), false, false, false);
    SphereID s11 = createSphere(&u1, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), 2);
    SphereID s21 = createSphere(&u1, 4567789, Vec3(real_c(3), real_c(2), real_c(3)), real_c(1.5));
    WALBERLA_CHECK_NOT_NULLPTR( s11 );
@@ -185,6 +185,8 @@ void testUnion()
 
    WALBERLA_CHECK_EQUAL(u1.size(), 2);
    WALBERLA_CHECK_EQUAL(u1.size(), u2->size());
+   // More exhaustive tests (with inertia, rotation, etc.)
+   // can be found in tests/mesh/MeshMarshalling.cpp
 
    //getting spheres of second union
    SphereID s12 = static_cast<SphereID> (u2->begin().getBodyID());
diff --git a/tests/pe/Raytracing.cpp b/tests/pe/Raytracing.cpp
index 25e925b8a..15dd6ae60 100644
--- a/tests/pe/Raytracing.cpp
+++ b/tests/pe/Raytracing.cpp
@@ -43,7 +43,7 @@ typedef std::tuple<Box, Plane, Sphere, Capsule, Ellipsoid> BodyTuple ;
 void SphereIntersectsTest()
 {
    MaterialID iron = Material::find("iron");
-   Sphere sp1(123, 1, Vec3(3,3,3), Vec3(0,0,0), Quat(), 2, iron, false, true, false);
+   Sphere sp1(123, 1, Vec3(3,3,3), Quat(), 2, iron, false, true, false);
    real_t t;
    Vec3 n;
    
@@ -62,11 +62,11 @@ void SphereIntersectsTest()
    WALBERLA_CHECK(intersects(&sp1, ray2, t, n));
    
    // sphere behind ray origin
-   Sphere sp2(123, 1, Vec3(3,-8,3), Vec3(0,0,0), Quat(), 2, iron, false, true, false);
+   Sphere sp2(123, 1, Vec3(3,-8,3), Quat(), 2, iron, false, true, false);
    WALBERLA_CHECK(!intersects(&sp2, ray1, t, n));
    
    // sphere around ray origin
-   Sphere sp3(123, 1, Vec3(3,-5,3), Vec3(0,0,0), Quat(), 2, iron, false, true, false);
+   Sphere sp3(123, 1, Vec3(3,-5,3), Quat(), 2, iron, false, true, false);
    WALBERLA_CHECK(intersects(&sp3, ray1, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(2));
 }
@@ -128,15 +128,15 @@ void BoxIntersectsTest() {
    real_t t;
    Vec3 n;
    
-   Box box1(127, 5, Vec3(0, -15, 0), Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
+   Box box1(127, 5, Vec3(0, -15, 0),  Quat(), Vec3(10, 10, 10), iron, false, true, false);
    Ray ray1(Vec3(3,-5,3), Vec3(0,1,0));
    WALBERLA_CHECK(!intersects(&box1, ray1, t, n));
    
-   Box box2(128, 5, Vec3(0, -2, 0), Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
+   Box box2(128, 5, Vec3(0, -2, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
    WALBERLA_CHECK(intersects(&box2, ray1, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(8), real_t(1e-7));
    
-   Box box3(128, 5, Vec3(0, 5, 0), Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
+   Box box3(128, 5, Vec3(0, 5, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
    WALBERLA_CHECK(intersects(&box3, ray1, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(5));
    
@@ -160,14 +160,14 @@ void BoxIntersectsTest() {
    WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(7.0710), real_t(1e-4));
    
    Ray ray3(Vec3(3,-5,3), Vec3(2, real_t(-1.5), real_t(0.5)).getNormalized());
-   Box box4(128, 5, Vec3(0, 8, 0), Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
+   Box box4(128, 5, Vec3(0, 8, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
    WALBERLA_CHECK(!intersects(&box4, ray3, t, n));
    
    Ray ray4(Vec3(3,-5,3), Vec3(-2, 3, real_t(0.5)).getNormalized());
    WALBERLA_CHECK(intersects(&box4, ray4, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(9.7068), real_t(1e-4));
    
-   Box box5(128, 5, Vec3(4, 0, 0), Vec3(0, 0, 0), Quat(), Vec3(4, 4, 4), iron, false, true, false);
+   Box box5(128, 5, Vec3(4, 0, 0), Quat(), Vec3(4, 4, 4), iron, false, true, false);
    box5.rotate(0,0,math::M_PI/4);
    Ray ray5(Vec3(0,1.5,0), Vec3(1,0,0));
    WALBERLA_CHECK(intersects(&box5, ray5, t, n));
@@ -202,7 +202,7 @@ void CapsuleIntersectsTest() {
    real_t t;
    Vec3 n;
    
-   Capsule cp1(0, 0, Vec3(2,3,3), Vec3(0,0,0), Quat(), real_t(2), real_t(2), iron, false, true, false);
+   Capsule cp1(0, 0, Vec3(2,3,3), Quat(), real_t(2), real_t(2), iron, false, true, false);
    
    // ray through the center
    Ray ray1(Vec3(3,-5,3), Vec3(0,1,0));
@@ -229,7 +229,7 @@ void EllipsoidTest() {
    real_t t;
    Vec3 n;
    
-   Ellipsoid el1(0,0, Vec3(2,3,3), Vec3(0,0,0), Quat(), Vec3(2,3,1), iron, false, true, false);
+   Ellipsoid el1(0,0, Vec3(2,3,3), Quat(), Vec3(2,3,1), iron, false, true, false);
    
    Ray ray1(Vec3(-2,3,3), Vec3(1,0,0).getNormalized());
    WALBERLA_CHECK(intersects(&el1, ray1, t, n));
diff --git a/tests/pe/RigidBody.cpp b/tests/pe/RigidBody.cpp
index f72d9ce0b..083c6ab43 100644
--- a/tests/pe/RigidBody.cpp
+++ b/tests/pe/RigidBody.cpp
@@ -82,10 +82,10 @@ void move( BodyStorage& storage, real_t dt )
 void checkRotationFunctions()
 {
    MaterialID iron = Material::find("iron");
-   auto sp1 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
-   auto sp2 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
-   auto sp3 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
-   auto sp4 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
+   auto sp1 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
+   auto sp2 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
+   auto sp3 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
+   auto sp4 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
 
    sp1->rotate( 1, 0, 0, math::M_PI * real_t(0.5));
    sp1->rotate( 0, 1, 0, math::M_PI * real_t(0.5));
@@ -121,7 +121,7 @@ void checkRotationFunctions()
 void checkPointFunctions()
 {
    MaterialID iron = Material::find("iron");
-   auto sp1 = std::make_shared<Sphere>( 0, 0, Vec3(10,10,10), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
+   auto sp1 = std::make_shared<Sphere>( 0, 0, Vec3(10,10,10), Quat(), real_t(1), iron, false, true, false );
 
    WALBERLA_CHECK( sp1->containsPoint( 10, 10, 10 ) );
    WALBERLA_CHECK( sp1->containsPoint( real_c(10.9), 10, 10 ) );
@@ -148,7 +148,7 @@ int main( int argc, char** argv )
 
    MaterialID iron = Material::find("iron");
    BodyStorage storage;
-   SpherePtr spPtr = std::make_unique<Sphere>(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false);
+   SpherePtr spPtr = std::make_unique<Sphere>(0, 0, Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false);
    SphereID sphere = static_cast<SphereID>(&storage.add(std::move(spPtr)));
 
    Vec3 x0 = Vec3(-2,2,0);
diff --git a/tests/pe/SetBodyTypeIDs.cpp b/tests/pe/SetBodyTypeIDs.cpp
index 21e2fcd5c..f6e1482a0 100644
--- a/tests/pe/SetBodyTypeIDs.cpp
+++ b/tests/pe/SetBodyTypeIDs.cpp
@@ -132,8 +132,8 @@ int main( int argc, char** argv )
    WALBERLA_CHECK_UNEQUAL(Plane::getStaticTypeID(), Capsule::getStaticTypeID());
 
    SingleTypeFunctor singleFunc;
-   Box     bx (0, 0, Vec3(0), Vec3(0), Quat(), Vec3(1), Material::find("iron"), false, false, false);
-   Capsule cap(0, 0, Vec3(0), Vec3(0), Quat(), 1, 1, Material::find("iron"), false, false, false);
+   Box     bx (0, 0, Vec3(0), Quat(), Vec3(1), Material::find("iron"), false, false, false);
+   Capsule cap(0, 0, Vec3(0), Quat(), 1, 1, Material::find("iron"), false, false, false);
 
    SingleCast<BodyTuple2, SingleTypeFunctor, void>::execute(Box::getStaticTypeID(), singleFunc);
    SingleCast<BodyTuple2, SingleTypeFunctor, void>::execute(Capsule::getStaticTypeID(), singleFunc);
diff --git a/tests/pe/SimpleCCD.cpp b/tests/pe/SimpleCCD.cpp
index 3d0d5bc7e..63e9dc239 100644
--- a/tests/pe/SimpleCCD.cpp
+++ b/tests/pe/SimpleCCD.cpp
@@ -60,7 +60,7 @@ int main( int argc, char** argv )
     math::seedRandomGenerator(1337);
 
     for (uint_t i = 0; i < 100; ++i)
-      storage[0].add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), real_t(1), iron, false, false, false) );
+      storage[0].add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Quat(), real_t(1), iron, false, false, false) );
 
     sccd.generatePossibleContacts();
 
@@ -84,14 +84,14 @@ int main( int argc, char** argv )
 
     bs.clear();
 
-    bs.add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), real_t(1), iron, false, false, false) );
+    bs.add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Quat(), real_t(1), iron, false, false, false) );
 
     WcTimingPool pool;
     for (int runs = 0; runs < 10; ++runs)
     {
        auto oldSize = bs.size();
        for (uint_t i = 0; i < oldSize; ++i)
-         bs.add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), real_t(0.5), iron, false, false, false) );
+         bs.add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Quat(), real_t(0.5), iron, false, false, false) );
        pool["SCCD"].start();
        sccd.generatePossibleContacts();
        pool["SCCD"].end();
diff --git a/tests/pe/Synchronization.cpp b/tests/pe/Synchronization.cpp
index 3693e9ab8..67dd06832 100644
--- a/tests/pe/Synchronization.cpp
+++ b/tests/pe/Synchronization.cpp
@@ -116,7 +116,7 @@ int main( int argc, char ** argv )
 
    MaterialID iron = Material::find("iron");
    walberla::id_t sid = 123;
-   Sphere refSphere(1, 0, Vec3(15, 15, 15), Vec3(0,0,0), Quat(), 3, iron, false, true, false);
+   Sphere refSphere(1, 0, Vec3(15, 15, 15), Quat(), 3, iron, false, true, false);
    refSphere.setLinearVel(4, 5, 6);
    refSphere.setAngularVel( 1, 2, 3);
    Vec3 gpos = Vec3(15, 15, 15);
diff --git a/tests/pe/SynchronizationLargeBody.cpp b/tests/pe/SynchronizationLargeBody.cpp
index 28fdc39d1..94e205db7 100644
--- a/tests/pe/SynchronizationLargeBody.cpp
+++ b/tests/pe/SynchronizationLargeBody.cpp
@@ -160,7 +160,7 @@ int main( int argc, char ** argv )
    walberla::id_t sid = 123;
    Vec3 gpos = Vec3(3.5, 3.5, 3.5);
    const real_t r = real_c(1.6);
-   Sphere refSphere(1, 0, gpos, Vec3(0,0,0), Quat(), r, iron, false, true, false);
+   Sphere refSphere(1, 0, gpos, Quat(), r, iron, false, true, false);
    refSphere.setLinearVel(4, 5, 6);
    refSphere.setAngularVel( 1, 2, 3);
 
diff --git a/tests/pe/Union.cpp b/tests/pe/Union.cpp
index 49fd6e66b..de959af08 100644
--- a/tests/pe/Union.cpp
+++ b/tests/pe/Union.cpp
@@ -13,7 +13,7 @@
 //  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 ParallelEquivalence.cpp
+//! \file Union.cpp
 //! \author Sebastian Eibl <sebastian.eibl@fau.de>
 //
 //======================================================================================================================
@@ -49,6 +49,7 @@ typedef std::tuple<Sphere, Plane, UnionType> BodyTuple ;
 
 void SnowManFallingOnPlane()
 {
+   WALBERLA_LOG_INFO("- Performing snowman on plane test");
    shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>();
 
    // create blocks
@@ -99,25 +100,178 @@ void SnowManFallingOnPlane()
    //WALBERLA_LOG_DEVEL(un);
 }
 
-void ImpulsCarryover()
+void UnionConstruction()
 {
+
    MaterialID iron = Material::find("iron");
 
-   auto un  = std::make_unique<UnionType>(12, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), false, true, false);
-   auto sp1 = std::make_unique<Sphere>( 10, 0, Vec3( 1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
-   auto sp2 = std::make_unique<Sphere>( 11, 0, Vec3(-1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
+   // Construct a union of two spheres in a non-rotated state and check all its parameters
+   auto un  = std::make_unique<UnionType>(12, 0, Vec3(0,0,0), Quat(), false, true, false);
+   auto sp1 = std::make_unique<Sphere>( 10, 0, Vec3( 1,0,0), Quat(real_t(0.5), real_t(0.5),real_t(0.5),real_t(0.5)), real_t(1), iron, false, true, false );
+   auto sp2 = std::make_unique<Sphere>( 11, 0, Vec3(-1,0,0), Quat(), real_t(1), iron, false, true, false );
+
+   WALBERLA_LOG_INFO("- Adding first body.");
+   // Add first body
+   un->add( std::move(sp1) );
+   const RigidBody& subb1 =  *un->begin();
+
+   // Check relative and global position and rotation
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getPosition(),Vec3(1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getRelPosition(), Vec3(0,0,0));
+
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getRelPosition(), Vec3(0, 0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getPosition(), Vec3(1,0,0));
+   // Global quaternion
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getQuaternion(), Quat(real_t(0.5), real_t(0.5),real_t(0.5),real_t(0.5)));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getRelQuaternion(), Quat(real_t(0.5), real_t(0.5),real_t(0.5),real_t(0.5)));
+
+   // Check mass volume and inertia
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getVolume(), (real_t(4./3.)*real_t(math::M_PI)));
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getMass(), un->getVolume()*Material::getDensity(iron));
+   real_t scalar_inertia = real_t(0.4)*un->getMass(); // for sphere: I = 2/5*m*r*r
+   WALBERLA_CHECK_EQUAL(un->getInertia(), Mat3(scalar_inertia,0,0,0,scalar_inertia,0,0,0,scalar_inertia));
+
+   WALBERLA_LOG_INFO("- Adding second body.");
+   un->add( std::move(sp2) );
+   const RigidBody & subb2 =  *(un->begin()+1);
+   // Check relative and global position
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getPosition(),Vec3(0,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getRelPosition(), Vec3(0,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getRelPosition(), Vec3(1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getPosition(), Vec3(1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb2.getRelPosition(), Vec3(-1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb2.getPosition(), Vec3(-1,0,0));
+
+   // Check mass volume and inertia
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getVolume(), (real_t(8./3.)*real_t(math::M_PI)));
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getMass(), un->getVolume()*Material::getDensity(iron));
+   // Mass of one sphere
+   real_t masssphere = real_t(4./3.)*real_t(math::M_PI)*Material::getDensity(iron);
+   Mat3 bodyinertia(real_t(2.0)*scalar_inertia, 0, 0, 0, real_t(2.0)*(scalar_inertia + masssphere),0, 0, 0, real_t(2.0)*(scalar_inertia + masssphere));
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getInertia(), bodyinertia);
+
+   WALBERLA_CHECK_FLOAT_EQUAL( un->getLinearVel(), Vec3(0,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL( un->getAngularVel(), Vec3(0,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL( un->getAngularVel(), Vec3(0,0,0));
+
+   WALBERLA_LOG_INFO("- Performing Rotation.");
+   //Check values for rotated union
+   Quat rotz30(Vec3(0,0,1), real_t(math::M_PI/6.0)); // rotate by 30 deg via z axis
+   real_t sin30 = real_t(0.5);
+   real_t cos30 = real_t(sqrt(3.0)/2.0);
+   un->setOrientation(rotz30);
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getQuaternion(), rotz30);
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getRelPosition(), Vec3(1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getPosition(), Vec3(cos30,sin30,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb2.getRelPosition(), Vec3(-1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb2.getPosition(), Vec3(-cos30,-sin30,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getRelQuaternion(), Quat(real_t(0.5), real_t(0.5),real_t(0.5),real_t(0.5)));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getQuaternion(), Quat(real_t(0.5), real_t(0.5),real_t(0.5),real_t(0.5))*rotz30 );
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getInertia(), rotz30.toRotationMatrix()*bodyinertia*rotz30.toRotationMatrix().getTranspose());
+
+   WALBERLA_LOG_INFO("- Applying velocities.");
+   //Apply a linear velocity to the union
+   un->setLinearVel(Vec3(1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getLinearVel(), Vec3(1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb2.getLinearVel(), Vec3(1,0,0));
+
+   un->setAngularVel(Vec3(0,0,1));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getAngularVel(), Vec3(0,0,1));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb2.getAngularVel(), Vec3(0,0,1));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb1.getLinearVel(), Vec3(real_t(1.0-sin30),cos30,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb2.getLinearVel(), Vec3(real_t(1.0+sin30),-cos30,0));
+
+   WALBERLA_LOG_INFO("- Constructing rotated union.");
+   //Part 2: Construct exactly the same union, but now in a rotated state.
+   auto un2  = std::make_unique<UnionType>(12, 0, Vec3(0,0,0), rotz30, false, true, false);
+   auto sp12 = std::make_unique<Sphere>( 10, 0, Vec3( 1,0,0), Quat(real_t(0.5), real_t(0.5),real_t(0.5),real_t(0.5)), real_t(1), iron, false, true, false );
+   auto sp22 = std::make_unique<Sphere>( 11, 0, Vec3(-1,0,0), Quat(real_t(0.3), real_t(0.9),real_t(0.1),real_t(0.3)), real_t(1), iron, false, true, false );
+
+   un2->add( std::move(sp12) );
+   un2->add( std::move(sp22) );
+   const RigidBody & subb12 = *un2->begin();
+   const RigidBody & subb22 =  *(un2->begin()+1);
+   // Check relative and global position and rotation
+   WALBERLA_CHECK_FLOAT_EQUAL(un2->getPosition(),Vec3(0,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(un2->getRelPosition(), Vec3(0,0,0));
+
+   WALBERLA_CHECK_FLOAT_EQUAL(subb12.getRelPosition(), Vec3(cos30,-sin30, 0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb12.getPosition(), Vec3(1,0,0));
+
+   WALBERLA_CHECK_FLOAT_EQUAL(subb22.getRelPosition(), Vec3(-cos30,sin30, 0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb22.getPosition(), Vec3(-1,0,0));
 
-   sp1->setLinearVel(Vec3(0,real_c(+1),0));
-   sp2->setLinearVel(Vec3(0,real_c(-1),0));
+   // Global quaternion and local
+   WALBERLA_CHECK_FLOAT_EQUAL(subb12.getQuaternion(), Quat(real_t(0.5), real_t(0.5),real_t(0.5),real_t(0.5)));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb12.getRelQuaternion(), subb12.getQuaternion()*rotz30.getInverse());
+   WALBERLA_CHECK_FLOAT_EQUAL(subb22.getQuaternion(), Quat(real_t(0.3), real_t(0.9),real_t(0.1),real_t(0.3)));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb22.getRelQuaternion(), subb22.getQuaternion()*rotz30.getInverse());
 
+   // Inertia tensor
+   WALBERLA_CHECK_FLOAT_EQUAL(un2->getInertia(), bodyinertia);
+
+   //Rotate again by 30 deg and perform the same checks as before
+   un2->rotate(rotz30);
+   WALBERLA_CHECK_FLOAT_EQUAL(subb12.getPosition(), Vec3(cos30,sin30,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb22.getPosition(), Vec3(-cos30,-sin30,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb12.getQuaternion(), Quat(real_t(0.5), real_t(0.5),real_t(0.5),real_t(0.5))*rotz30 );
+   WALBERLA_CHECK_FLOAT_EQUAL(subb22.getQuaternion(), Quat(real_t(0.3), real_t(0.9),real_t(0.1),real_t(0.3))*rotz30 );
+   WALBERLA_CHECK_FLOAT_EQUAL(un->getInertia(), rotz30.toRotationMatrix()*bodyinertia*rotz30.toRotationMatrix().getTranspose());
+
+   WALBERLA_LOG_INFO("- Applying velocities.");
+   //Apply a linear velocity to the union
+   un2->setLinearVel(Vec3(1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb12.getLinearVel(), Vec3(1,0,0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb22.getLinearVel(), Vec3(1,0,0));
+
+   un2->setAngularVel(Vec3(0,0,1));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb12.getAngularVel(), Vec3(0,0,1));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb22.getAngularVel(), Vec3(0,0,1));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb12.getLinearVel(), Vec3(real_t(1.0-sin30), cos30, 0));
+   WALBERLA_CHECK_FLOAT_EQUAL(subb22.getLinearVel(), Vec3(real_t(1.0+sin30), -cos30, 0));
+
+}
+
+void checkAABB(const AABB &a1, const AABB& a2){
+   WALBERLA_CHECK_FLOAT_EQUAL(a1.xMin(), a2.xMin());
+   WALBERLA_CHECK_FLOAT_EQUAL(a1.yMin(), a2.yMin());
+   WALBERLA_CHECK_FLOAT_EQUAL(a1.zMin(), a2.zMin());
+   WALBERLA_CHECK_FLOAT_EQUAL(a1.xMax(), a2.xMax());
+   WALBERLA_CHECK_FLOAT_EQUAL(a1.yMax(), a2.yMax());
+   WALBERLA_CHECK_FLOAT_EQUAL(a1.zMax(), a2.zMax());
+}
+
+void UnionAABB() {
+   WALBERLA_LOG_INFO("- Performing AABB test");
+   MaterialID iron = Material::find("iron");
+   // Construct a union of two spheres in a non-rotated state and check all its parameters
+   auto un  = std::make_unique<UnionType>(12, 0, Vec3(0,0,0), Quat(), false, true, false);
+   auto sp1 = std::make_unique<Sphere>( 10, 0, Vec3( 1,0,0), Quat(real_t(0.5), real_t(0.5),real_t(0.5),real_t(0.5)), real_t(1), iron, false, true, false );
+   auto sp2 = std::make_unique<Sphere>( 11, 0, Vec3(-1,0,0), Quat(), real_t(1), iron, false, true, false );
    un->add( std::move(sp1) );
    un->add( std::move(sp2) );
+   AABB aabb = un->getAABB();
+   WALBERLA_CHECK_FLOAT_EQUAL(aabb.minCorner(), Vec3(-2,-1,-1));
+   WALBERLA_CHECK_FLOAT_EQUAL(aabb.maxCorner(), Vec3(2, 1, 1));
+
+   Vec3 shift(10,10,10);
+   un->setPosition(shift);
+   aabb = un->getAABB();
+   checkAABB(aabb, AABB(real_t(8),real_t(9),real_t(9),real_t(12),real_t(11),real_t(11)));
+
+   Quat rotz30(Vec3(0,0,1), real_t(math::M_PI/6.0)); // rotate by 30 deg via z axis
+   real_t sin30 = real_t(0.5);
+   real_t cos30 = real_t(sqrt(3.0)/2.0);
+   un->setOrientation(rotz30);
+   aabb = un->getAABB();
+   checkAABB(aabb, AABB(real_t(9.0-cos30),real_t(9.0-sin30),real_t(9), real_t(11.0+cos30), real_t(11.0+sin30), real_t(11)));
+
+   aabb = un->begin()->getAABB();
+   checkAABB(aabb, AABB(real_t(9.0+cos30),real_t(9.0+sin30),real_t(9), real_t(11.0+cos30), real_t(11.0+sin30), real_t(11)));
+
+   aabb = (un->begin()+1)->getAABB();
+   checkAABB(aabb, AABB(real_t(9.0-cos30),real_t(9.0-sin30),real_t(9), real_t(11.0-cos30), real_t(11.0-sin30), real_t(11)));
 
-   WALBERLA_CHECK_FLOAT_EQUAL( un->getPosition(),  Vec3(0,0,0) );
-   WALBERLA_CHECK_FLOAT_EQUAL( un->getLinearVel(), Vec3(0,0,0) );
-   WALBERLA_CHECK_FLOAT_EQUAL( un->getAngularVel() * Vec3(1,0,0), real_t(0) );
-   WALBERLA_CHECK_FLOAT_EQUAL( un->getAngularVel() * Vec3(0,1,0), real_t(0) );
-   WALBERLA_CHECK_GREATER( un->getAngularVel() * Vec3(0,0,1), real_t(0) );
 }
 
 int main( int argc, char ** argv )
@@ -126,8 +280,11 @@ int main( int argc, char ** argv )
 
    walberla::MPIManager::instance()->initializeMPI( &argc, &argv );
 
+   UnionConstruction();
+   UnionAABB();
    SnowManFallingOnPlane();
-   ImpulsCarryover();
+
+
 
    return EXIT_SUCCESS;
 }
@@ -136,4 +293,4 @@ int main( int argc, char ** argv )
 int main( int argc, char* argv[] )
 {
   return walberla::main( argc, argv );
-}
\ No newline at end of file
+}
diff --git a/tests/pe/UnionBehavior.cpp b/tests/pe/UnionBehavior.cpp
new file mode 100644
index 000000000..51037cf48
--- /dev/null
+++ b/tests/pe/UnionBehavior.cpp
@@ -0,0 +1,259 @@
+//======================================================================================================================
+//
+//  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   UnionBehavior.cpp
+//! \author Tobias Leemann <tobias.leemann@fau.de>
+//! \brief Testcase checking whether a single body and a union representing the same geometry behave equally.
+//======================================================================================================================
+
+//! [Includes]
+#include <pe/basic.h>
+
+#include <core/Environment.h>
+#include <core/grid_generator/HCPIterator.h>
+#include <core/grid_generator/SCIterator.h>
+#include <core/logging/Logging.h>
+#include <core/math/Random.h>
+
+#include "blockforest/StructuredBlockForest.h"
+#include "blockforest/Initialization.h"
+#include "pe/fcd/GenericFCD.h"
+
+#include "pe/rigidbody/BoxFactory.h"
+#include "vtk/VTKOutput.h"
+#include "pe/vtk/BodyVtkOutput.h"
+
+
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <cstring>
+#include <tuple>
+
+
+//! [Includes]
+
+namespace walberla {
+using namespace walberla::pe;
+
+
+//! [BodyTypeTuple]
+using BoxUnion = Union<Box>;
+using BodyTypeTuple = std::tuple<Plane, Box, BoxUnion>;
+//! [BodyTypeTuple]
+
+// Override the collide function, so that the collisions between the two bodies themselves are not tracked,
+// only collisions with the surrounding planes are handled
+class PlaneOnlyFCD : public fcd::GenericFCD<BodyTypeTuple, fcd::AnalyticCollideFunctor>{
+public:
+   Contacts& generateContacts(PossibleContacts& possibleContacts) override
+   {
+      contacts_.clear();
+      fcd::AnalyticCollideFunctor<decltype(contacts_)> func(contacts_);
+      for (auto &c : possibleContacts)
+      {
+         if(c.first->getTypeID() == Plane::getStaticTypeID() || c.second->getTypeID() == Plane::getStaticTypeID()) {
+            DoubleCast<BodyTypeTuple, BodyTypeTuple, fcd::AnalyticCollideFunctor<decltype(contacts_)>, bool>::execute(
+                     c.first, c.second, func);
+         }
+      }
+      return contacts_;
+   }
+};
+
+
+int main( int argc, char ** argv )
+{
+
+   Environment env(argc, argv);
+   WALBERLA_UNUSED(env);
+
+   // Parameters
+   auto dt = real_t(0.005);
+   int simulationSteps = 4000;
+   auto domainsize = real_t(100);
+   // Size of the box
+   auto boxlenght = real_t(6.0);
+   auto boxwidth = real_t(2.0);
+
+   Vec3 pos(real_t(domainsize/2.0),real_t(domainsize/2.0),real_t(0.8*domainsize));
+   Vec3 v0(10,2,3); // Linear velocity of the objects
+   Vec3 w0(4,15,1); // Some angular velocity of the objects (quite high)
+   int visSpacing = 10;
+
+
+   // Simulation part
+   math::seedRandomGenerator( static_cast<unsigned int>(1337 * mpi::MPIManager::instance()->worldRank()) );
+
+
+
+   //! [Parameters]
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** GLOBALBODYSTORAGE ***");
+   //! [GlobalBodyStorage]
+   shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>();
+   //! [GlobalBodyStorage]
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** BLOCKFOREST ***");
+   // create forest
+   //! [BlockForest]
+   auto forest = blockforest::createBlockForest( AABB(0,0,0,domainsize,domainsize,domainsize), // simulation domain
+                                                 Vector3<uint_t>(3,1,1), // blocks in each direction
+                                                 Vector3<bool>(true, false, false) // periodicity
+                                                 );
+
+   //! [BlockForest]
+   if (!forest)
+   {
+      WALBERLA_LOG_INFO_ON_ROOT( "No BlockForest created ... exiting!");
+      return EXIT_SUCCESS;
+   }
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** STORAGEDATAHANDLING ***");
+   // add block data
+   //! [StorageDataHandling]
+   auto storageID           = forest->addBlockData(createStorageDataHandling<BodyTypeTuple>(), "Storage");
+   //! [StorageDataHandling]
+   //! [AdditionalBlockData]
+   auto ccdID               = forest->addBlockData(ccd::createHashGridsDataHandling( globalBodyStorage, storageID ), "CCD");
+
+   auto sharedFCDBDH        = make_shared<blockforest::AlwaysCreateBlockDataHandling<PlaneOnlyFCD> >( );
+
+   auto fcdID               = forest->addBlockData(sharedFCDBDH, "FCD");
+   //! [AdditionalBlockData]
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** INTEGRATOR ***");
+   //! [Integrator]
+   cr::DEM cr(globalBodyStorage, forest, storageID, ccdID, fcdID);
+   cr.setGlobalLinearAcceleration( Vec3(0,0,-6) );
+   //! [Integrator]
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** BodyTypeTuple ***");
+   // initialize body type ids
+   //! [SetBodyTypeIDs]
+   SetBodyTypeIDs<BodyTypeTuple>::execute();
+   //! [SetBodyTypeIDs]
+
+
+   // UNCOMMENT THIS BLOCK FOR VTK OUTPUT
+   /*WALBERLA_LOG_INFO_ON_ROOT("*** VTK OUTPUT ***");
+   //! [VTK Domain Output]
+   auto vtkDomainOutput = vtk::createVTKOutput_DomainDecomposition( forest, "domain_decomposition", 1, "VTK", "simulation_step" );
+   vtkDomainOutput->write(true);
+   auto vtkSphereHelper = make_shared<DefaultBodyVTKOutput>(storageID, *forest) ;
+   auto vtkSphereOutput = vtk::createVTKOutput_PointData(vtkSphereHelper, "Bodies", 1, "VTK", "simulation_step", false, false);*/
+   //! [VTK Domain Output]
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** SETUP - START ***");
+   //! [Material]
+   const real_t   static_cof  ( real_c(1.2) / 2 );   // Coefficient of static friction. Note: pe doubles the input coefficient of friction for material-material contacts.
+   const real_t   dynamic_cof ( static_cof ); // Coefficient of dynamic friction. Similar to static friction for low speed friction.
+   MaterialID     material = createMaterial( "granular", real_t( 1.0 ), 0, static_cof, dynamic_cof, real_t( 0.5 ), 1, real_t(8.11e5), real_t(6.86e1), real_t(6.86e1) );
+   //! [Material]
+
+   // Create surronding planes in y,z directions, but not in x.
+   auto simulationDomain = forest->getDomain();
+   //! [Planes]
+   createPlane(*globalBodyStorage, 100, Vec3(0,1,0), simulationDomain.minCorner(), material );
+   createPlane(*globalBodyStorage, 101, Vec3(0,-1,0), simulationDomain.maxCorner(), material );
+   createPlane(*globalBodyStorage, 102, Vec3(0,0,1), simulationDomain.minCorner(), material );
+   createPlane(*globalBodyStorage, 103, Vec3(0,0,-1), simulationDomain.maxCorner(), material );
+   //! [Planes]
+
+   //! [Gas]
+   uint_t numParticles = uint_c(0);
+
+   // Create a union of a two half boxes with the center at pos
+   BoxUnion* particleU = createUnion<Box>( *globalBodyStorage, *forest, storageID, 0, Vec3(10,10,10));
+   // add 2 parts to the union
+   createBox(particleU, 4, pos-Vec3(real_t(boxlenght/4.0),0,0), Vec3(real_t(boxlenght/2.0), boxwidth, boxwidth), material);
+   createBox(particleU, 5, pos+Vec3(real_t(boxlenght/4.0),0,0), Vec3(real_t(boxlenght/2.0), boxwidth, boxwidth), material);
+
+   if (particleU != nullptr) particleU->setLinearVel(v0);
+   if (particleU != nullptr) particleU->setAngularVel(w0);
+   if (particleU != nullptr) ++numParticles;
+
+   // Generate the same box as one particle at pos
+   BoxID particleS = createBox( *globalBodyStorage, *forest, storageID, 1, pos, Vec3(boxlenght, boxwidth, boxwidth), material );
+   if (particleS != nullptr) particleS->setLinearVel(v0);
+   if (particleS != nullptr) particleS->setAngularVel(w0);
+   if (particleS != nullptr) ++numParticles;
+
+   WALBERLA_LOG_INFO_ON_ROOT("#particles created per process: " << numParticles);
+   syncNextNeighbors<BodyTypeTuple>(*forest, storageID);
+   //! [Gas]
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** SETUP - END ***");
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** SIMULATION - START ***");
+   //vtkDomainOutput->write(true);
+   //! [GameLoop]
+   for (int i=0; i < simulationSteps; ++i)
+   {
+      if( i % visSpacing == 0 )
+      {
+         WALBERLA_LOG_INFO_ON_ROOT( "Timestep " << i << " / " << simulationSteps );
+         // UNCOMMENT FOR OUTPUT
+         //vtkSphereOutput->write(true);
+      }
+
+      cr.timestep( real_c(dt) );
+
+      int bdcount = 0;
+      RigidBody* refU = nullptr;
+      RigidBody* refS = nullptr;
+      for (auto blockIt = forest->begin(); blockIt != forest->end(); ++blockIt)
+      {
+         for (auto bodyIt = LocalBodyIterator::begin(*blockIt, storageID); bodyIt != LocalBodyIterator::end(); ++bodyIt)
+         {
+            if(bodyIt->getID() == 0){
+               refU = &*bodyIt;
+            }
+            if(bodyIt->getID() == 1){
+               refS = &*bodyIt;
+            }
+            bdcount ++;
+         }
+      }
+
+      // Compare with an quite large epsilon, as round of errors in collisions will amplify themselves over time
+      auto eps = real_t(1e-4);
+      WALBERLA_CHECK_GREATER_EQUAL(bdcount, 2, "Lost a body.");
+      WALBERLA_CHECK_NOT_NULLPTR(refS, "Single body was not found.");
+      WALBERLA_CHECK_NOT_NULLPTR(refU, "Union was not found.");
+      // norm(pos1-pos2) < 1e-4 -> norm*norm < 1e-8
+      WALBERLA_CHECK_LESS((refU->getPosition()-refS->getPosition()).sqrLength(), eps*eps  );
+      WALBERLA_CHECK_LESS((refU->getLinearVel()-refS->getLinearVel()).sqrLength(), eps*eps );
+      WALBERLA_CHECK_LESS((refU->getAngularVel()-refS->getAngularVel()).sqrLength(), eps*eps);
+
+      // Sums of matrix differences...
+      WALBERLA_CHECK_LESS(std::abs(Vec3(1,1,1) * ((refU->getRotation()-refS->getRotation())*Vec3(1,1,1))), real_t(9.0*eps));
+      WALBERLA_CHECK_LESS(std::abs(Vec3(1,1,1) * ((refU->getInertia()-refS->getInertia())*Vec3(1,1,1))), real_t(9.0*eps));
+      //WALBERLA_LOG_INFO_ON_ROOT("Timestep " << i << ": " <<refU->getPosition() << "/" << refS->getPosition() << (Vec3(1,1,1) * ((refU->getInertia()-refS->getInertia())*Vec3(1,1,1)))<< " " << abs(Vec3(1,1,1) * ((refU->getRotation()-refS->getRotation())*Vec3(1,1,1))));
+
+
+      syncNextNeighbors<BodyTypeTuple>(*forest, storageID);
+   }
+   //! [GameLoop]
+   WALBERLA_LOG_INFO_ON_ROOT("*** SIMULATION - END ***");
+
+   return EXIT_SUCCESS;
+}
+} // namespace walberla
+
+int main( int argc, char* argv[] )
+{
+   return walberla::main( argc, argv );
+}
diff --git a/tests/pe/VolumeInertia.cpp b/tests/pe/VolumeInertia.cpp
index 6deebadad..2ab7738bb 100644
--- a/tests/pe/VolumeInertia.cpp
+++ b/tests/pe/VolumeInertia.cpp
@@ -97,7 +97,7 @@ int main( int argc, char ** argv )
    Vec3   COM;
    Mat3   inertia;
 
-   Sphere sp(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), real_t(2.34), material, false, true, false);
+   Sphere sp(0, 0, Vec3(0,0,0), Quat(), real_t(2.34), material, false, true, false);
    calcNumeric(sp, sp.getAABB(), real_t(0.01), volume, COM, inertia);
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(sp.getVolume(), volume, real_t(10e-4)) );
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(Sphere::calcVolume( real_t(2.34) ), volume, real_t(10e-4)) );
@@ -105,7 +105,7 @@ int main( int argc, char ** argv )
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(sp.getMass(), volume * Material::getDensity(material), real_t(10e-4)) );
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(COM, Vec3(0), real_t(10e-4)) );
 
-   Box bx(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), Vec3(real_t(1.5), real_t(2.5), real_t(3.5)), material, false, true, false);
+   Box bx(0, 0, Vec3(0,0,0), Quat(), Vec3(real_t(1.5), real_t(2.5), real_t(3.5)), material, false, true, false);
    calcNumeric(bx, bx.getAABB(), real_t(0.01), volume, COM, inertia);
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(bx.getVolume(), volume, real_t(10e-4)) );
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(Box::calcVolume( Vec3(real_t(1.5), real_t(2.5), real_t(3.5)) ), volume, real_t(10e-4)) );
@@ -113,7 +113,7 @@ int main( int argc, char ** argv )
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(bx.getMass(), volume * Material::getDensity(material), real_t(10e-4)) );
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(COM, Vec3(0), real_t(10e-4)) );
 
-   Ellipsoid el(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), Vec3(real_t(1.5), real_t(2.5), real_t(3.5)), material, false, true, false);
+   Ellipsoid el(0, 0, Vec3(0,0,0), Quat(), Vec3(real_t(1.5), real_t(2.5), real_t(3.5)), material, false, true, false);
    calcNumeric(el, el.getAABB(), real_t(0.01), volume, COM, inertia);
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(el.getVolume(), volume, real_t(10e-4)) );
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(Ellipsoid::calcVolume( Vec3(real_t(1.5), real_t(2.5), real_t(3.5)) ), volume, real_t(10e-4)) );
@@ -121,7 +121,7 @@ int main( int argc, char ** argv )
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(el.getMass(), volume * Material::getDensity(material), real_t(10e-4)) );
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(COM, Vec3(0), real_t(10e-4)) );
 
-   Capsule cp(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), real_t(1.5), real_t(2.5), material, false, true, false);
+   Capsule cp(0, 0, Vec3(0,0,0), Quat(), real_t(1.5), real_t(2.5), material, false, true, false);
    calcNumeric(cp, cp.getAABB(), real_t(0.01), volume, COM, inertia);
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(cp.getVolume(), volume, real_t(10e-4)) );
    WALBERLA_CHECK( walberla::debug::check_functions_detail::check_float_equal_eps(Capsule::calcVolume( real_t(1.5), real_t(2.5) ), volume, real_t(10e-4)) );
diff --git a/tests/pe_coupling/geometry/PeIntersectionRatioTest.cpp b/tests/pe_coupling/geometry/PeIntersectionRatioTest.cpp
index 496f7db51..76e9a79ba 100644
--- a/tests/pe_coupling/geometry/PeIntersectionRatioTest.cpp
+++ b/tests/pe_coupling/geometry/PeIntersectionRatioTest.cpp
@@ -60,8 +60,7 @@ int main( int argc, char **argv )
 
    walberla::id_t sid = 0;
    walberla::id_t uid = 0;
-
-   Vector3<real_t> rPos( real_t(0));
+   
    Vector3<real_t> rotationAngles( real_t(0));
    Quaternion<real_t> quat( rotationAngles );
    pe::MaterialID material = pe::Material::find("iron");
@@ -74,7 +73,7 @@ int main( int argc, char **argv )
       Vector3<real_t> bodyPos(real_t(1), real_t(0), real_t(0));
       real_t radius = real_t(1);
 
-      pe::Sphere sphere(++sid, ++uid, bodyPos, rPos, quat, radius, material, false, false, false);
+      pe::Sphere sphere(++sid, ++uid, bodyPos, quat, radius, material, false, false, false);
 
       pe::RigidBody & rb = sphere; // otherwise not the pe_coupling/geometry version is matched
 
@@ -123,7 +122,7 @@ int main( int argc, char **argv )
       Vector3<real_t> bodyPos(real_t(1), real_t(0), real_t(0));
       Vector3<real_t> semiAxes1(real_t(1), real_t(1), real_t(1));
 
-      pe::Ellipsoid ellip1(++sid, ++uid, bodyPos, rPos, quat, semiAxes1, material, false, false, false);
+      pe::Ellipsoid ellip1(++sid, ++uid, bodyPos, quat, semiAxes1, material, false, false, false);
 
       pe::RigidBody & rb1 = ellip1; // otherwise not the pe_coupling/geometry version is matched
 
@@ -138,7 +137,7 @@ int main( int argc, char **argv )
       WALBERLA_CHECK_FLOAT_EQUAL(delta2, (std::sqrt(2) - real_t(1)) / std::sqrt(2), "Intersection ratio with ellipsoid wrong!");
 
       Vector3<real_t> semiAxes2(real_t(2), real_t(0.5), real_t(2));
-      pe::Ellipsoid ellip2(++sid, ++uid, bodyPos, rPos, quat, semiAxes2, material, false, false, false);
+      pe::Ellipsoid ellip2(++sid, ++uid, bodyPos, quat, semiAxes2, material, false, false, false);
 
       pe::RigidBody & rb2 = ellip2; // otherwise not the pe_coupling/geometry version is matched
 
-- 
GitLab