pe - Rigid Body Dynamics

Detailed Description

Good to Know

What geometries are supported?

What synchronization functions are available?

Please check the documentation of each individual method for more information.

What coarse collision detection functions are available?

Please check the documentation of each individual function for more information.

What fine collision detection functions are available?

Please check the documentation of each individual function for more information.

What collision resolution solvers are available?

Please check the documentation of each individual solver for more information.

Global, Communicating and InfiniteMass flags

These flags are given during the creation process of the rigid body. They can be retrieved with RigidBody::isGlobal(), RigidBody::isCommunicating() and RigidBody::hasInfiniteMass().

The global flag decides if the rigid body is stored in the global body storage or in one of the block local body storages. If the body is stored in the global body storage it will receive a global system id. Infinitely large bodies like planes are always global.

The communicating flag decides if the body takes part in the synchronization process, e.g. it spawns shadow copies and updates already existent shadow copies. Bodies which do not move throughout the simulation can be made non communicating.

Attention
There will be no shadow copies of non communicating bodies even if they overlap a subdomain boundary. To overcome this drawback you can set syncNonCommunicatingBodies to true once in your sync call (syncNextNeighbors() or syncShadowOwners()).

The infiniteMass flag decides if the body is "considered" by the collision resolution system. It still influences other rigid bodies but will not be moved itself. Rigid bodies with the infiniteMass flag set can still have a static velocity and will move accordingly.

"Object with id: xxx not found in shadowStorage! Cannot transfer ownership!"

Most likely one of your bodies got too fast. The process of migrating a rigid body to a new process is:

  1. overlap new subdomain
  2. sync
  3. move center of mass into the new subdomain
  4. sync

If a rigid body gets fast enough to move its center of mass into a new subdomain without first creating a shadow copy you will receive that error message.

Contacts Involving Unions

Collision detection for unions is done by colliding each of its subbodies separately. The contacts generated involves the subbodies. With this approach you can use different material parameters for every subbody and the solver component can retrieve the material of every collision partner by retrieving the material of Contact::getBody1(), Contact::getBody2().

Attention
To get the correct mass and inertia of a union during collision resolution you should call RigidBody::getTopSuperBody() and then RigidBody::getMass() (RigidBody::getInertia()) using the returned rigid body.

How can I dynamically switch between sync calls?

You can bind the function to a std::function and call this one.

std::function<void(void)> syncCallWithoutTT;
{
syncCallWithoutTT = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(nullptr), real_c(0.0), false );
} else
{
syncCallWithoutTT = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(nullptr), real_c(0.0), false );
}

Important Classes and Functions

Classes

class  walberla::mesh::pe::ConvexPolyhedron
 pe body representing a ConvexPolyhedron. More...
 
class  walberla::pe::cr::DEMSolver< Integrator, ContactResolver >
 
class  walberla::pe::cr::HardContactSemiImplicitTimesteppingSolvers
 Particular implementation of the collision resoution for the hard contacts. More...
 
class  walberla::pe::Box
 Box geometry. More...
 
class  walberla::pe::Capsule
 Capsule geometry. More...
 
class  walberla::pe::CylindricalBoundary
 
class  walberla::pe::Ellipsoid
 Base class for the Ellipsoid geometry. More...
 
class  walberla::pe::Plane
 Plane geometry. More...
 
class  walberla::pe::RigidBody
 
class  walberla::pe::Sphere
 Base class for the sphere geometry. More...
 
class  walberla::pe::Union< BodyTypes >
 Base class for the union geometry, a rigid assebly of bodies. More...
 

Functions

ConvexPolyhedronID walberla::mesh::pe::createConvexPolyhedron (BodyStorage &globalStorage, BlockStorage &blocks, BlockDataID storageID, id_t uid, const Vec3 &gpos, const std::vector< Vec3 > &pointCloud, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new ConvexPolyhedron. More...
 
ConvexPolyhedronID walberla::mesh::pe::createConvexPolyhedron (BodyStorage &globalStorage, BlockStorage &blocks, BlockDataID storageID, id_t uid, Vec3 gpos, TriangleMesh mesh, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new ConvexPolyhedron. More...
 
BoxID walberla::pe::createBox (BodyStorage &globalStorage, BlockStorage &blocks, BlockDataID storageID, id_t uid, const Vec3 &gpos, const Vec3 &lengths, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new Box. More...
 
CapsuleID walberla::pe::createCapsule (BodyStorage &globalStorage, BlockStorage &blocks, BlockDataID storageID, id_t uid, const Vec3 &gpos, const real_t radius, const real_t length, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new Capsule. More...
 
CylindricalBoundaryID walberla::pe::createCylindricalBoundary (BodyStorage &globalStorage, id_t uid, const Vec3 &gpos, const real_t radius, MaterialID material=Material::find("iron"))
 Setup of a new Cylindrical Boundary. More...
 
EllipsoidID walberla::pe::createEllipsoid (BodyStorage &globalStorage, BlockStorage &blocks, BlockDataID storageID, id_t uid, const Vec3 &gpos, const Vec3 &semiAxes, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new Ellipsoid. More...
 
PlaneID walberla::pe::createPlane (BodyStorage &globalStorage, id_t uid, Vec3 normal, const Vec3 &gpos, MaterialID material=Material::find("iron"))
 Setup of a new Plane. More...
 
static void walberla::pe::SetBodyTypeIDs< BodyTypeTuple, N >::execute ()
 Initial setup of static type ids. More...
 
SphereID walberla::pe::createSphere (BodyStorage &globalStorage, BlockStorage &blocks, BlockDataID storageID, id_t uid, const Vec3 &gpos, real_t radius, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new Sphere. More...
 
SquirmerID walberla::pe::createSquirmer (BodyStorage &globalStorage, BlockStorage &blocks, BlockDataID storageID, id_t uid, const Vec3 &gpos, real_t radius, real_t squirmerVelocity, real_t squirmerBeta, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new Squirmer. More...
 
template<typename... BodyTypes>
Union< BodyTypes... > * walberla::pe::createUnion (BodyStorage &globalStorage, BlockStorage &blocks, BlockDataID storageID, id_t uid, const Vec3 &gpos, bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new Union. More...
 
template<typename... BodyTypes>
BoxID walberla::pe::createBox (Union< BodyTypes... > *un, id_t uid, const Vec3 &gpos, const Vec3 &lengths, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new Box directly attached to a Union. More...
 
template<typename... BodyTypes>
CapsuleID walberla::pe::createCapsule (Union< BodyTypes... > *un, id_t uid, const Vec3 &gpos, const real_t radius, const real_t length, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new Capsule directly attached to a Union. More...
 
template<typename... BodyTypes>
SphereID walberla::pe::createSphere (Union< BodyTypes... > *un, id_t uid, const Vec3 &gpos, real_t radius, MaterialID material=Material::find("iron"), bool global=false, bool communicating=true, bool infiniteMass=false)
 Setup of a new Sphere directly attached to a Union. More...
 

Function Documentation

BoxID walberla::pe::createBox ( BodyStorage globalStorage,
BlockStorage &  blocks,
BlockDataID  storageID,
id_t  uid,
const Vec3 gpos,
const Vec3 lengths,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new Box.

Parameters
globalStorageprocess local global storage
blocksstorage of all the blocks on this process
storageIDBlockDataID of the BlockStorage block datum
uidThe user-specific ID of the box.
gposThe global position of the center of the box.
lengthsThe side length of the box \( (0..\infty) \).
materialThe material of the box.
globalspecifies if the box should be created in the global storage
communicatingspecifies if the box should take part in synchronization (syncNextNeighbour, syncShadowOwner)
infiniteMassspecifies if the box has infinite mass and will be treated as an obstacle
Returns
Handle for the new box.
Exceptions
std::invalid_argumentInvalid box radius.
std::invalid_argumentInvalid global box position.

This function creates a box primitive in the pe simulation system. The box with user-specific ID uid is placed at the global position gpos, has the side lengths lengths, and consists of the material material.

The following code example illustrates the setup of a box:

// Creating the iron box 1 with a side lengths of 2.5 at the global position (2,3,4).
// Note that the box is
// automatically added to the simulation world and is immediately part of the entire
// simulation. The function returns a handle to the newly created box, which can
// be used to for instance rotate the box around the global y-axis.
BoxID box = createBox( *globalBodyStorage, forest->getBlockStorage(), storageID, 1, Vec3(2,3,4), Vec3(2.5,2.5,2.5) );
if (box != nullptr)
box->rotate( 0.0, real_c(math::pi/3.0), 0.0 );
template<typename... BodyTypes>
BoxID walberla::pe::createBox ( Union< BodyTypes... > *  un,
id_t  uid,
const Vec3 gpos,
const Vec3 lengths,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new Box directly attached to a Union.

Template Parameters
BodyTypesall geometries the Union is able to contain
Exceptions
std::runtime_errorBox TypeID not initalized!
std::invalid_argumentcreateBox: Union argument is NULL
std::logic_errorcreateBox: Union is remote
std::invalid_argumentInvalid side length
See also
createBox for more details
CapsuleID walberla::pe::createCapsule ( BodyStorage globalStorage,
BlockStorage &  blocks,
BlockDataID  storageID,
id_t  uid,
const Vec3 gpos,
const real_t  radius,
const real_t  length,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new Capsule.

Parameters
globalStorageprocess local global storage
blocksstorage of all the blocks on this process
storageIDBlockDataID of the BlockStorage block datum
uidThe user-specific ID of the capsule.
gposThe global position of the center of the capsule.
qThe orientation of the capsule's body frame in the global world frame.
radiusThe radius of the cylinder part and the end caps \( (0..\infty) \).
lengthThe length of the cylinder part of the capsule \( (0..\infty) \).
materialThe material of the capsule.
globalspecifies if the capsule should be created in the global storage
communicatingspecifies if the capsule should take part in synchronization (syncNextNeighbour, syncShadowOwner)
infiniteMassspecifies if the capsule has infinite mass and will be treated as an obstacle
Returns
Handle for the new capsule.

The following code example illustrates the setup of a capsule:

// Create a capsule and rotate it after successfull creation.
CapsuleID capsule = createCapsule( *globalBodyStorage, forest->getBlockStorage(), storageID, 1, Vec3(2,3,4), real_t(1), real_t(1) );
if (capsule != nullptr)
capsule->rotate( 0.0, real_c(math::pi/3.0), 0.0 );
template<typename... BodyTypes>
CapsuleID walberla::pe::createCapsule ( Union< BodyTypes... > *  un,
id_t  uid,
const Vec3 gpos,
const real_t  radius,
const real_t  length,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new Capsule directly attached to a Union.

Template Parameters
BodyTypesall geometries the Union is able to contain
Exceptions
std::runtime_errorCapsule TypeID not initalized!
std::invalid_argumentcreateCapsule: Union argument is NULL
std::logic_errorcreateCapsule: Union is remote
std::invalid_argumentInvalid capsule radius
std::invalid_argumentInvalid capsule length
See also
createCapsule for more details
ConvexPolyhedronID walberla::mesh::pe::createConvexPolyhedron ( BodyStorage globalStorage,
BlockStorage &  blocks,
BlockDataID  storageID,
id_t  uid,
const Vec3 gpos,
const std::vector< Vec3 > &  pointCloud,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new ConvexPolyhedron.

Parameters
globalStorageprocess local global storage
blocksstorage of all the blocks on this process
storageIDBlockDataID of the BlockStorage block datum
uidThe user-specific ID of the box.
gposThe global position of the center of the box.
pointCloudA point cloud which convex hull defines the polyhedron
materialThe material of the box.
globalspecifies if the box should be created in the global storage
communicatingspecifies if the box should take part in synchronization (syncNextNeighbour, syncShadowOwner)
infiniteMassspecifies if the box has infinite mass and will be treated as an obstacle
Returns
Handle for the new box.
Exceptions
std::invalid_argumentInvalid box radius.
std::invalid_argumentInvalid global box position.

This function creates a box primitive in the pe simulation system. The box with user-specific ID uid is placed at the global position gpos, has the side lengths lengths, and consists of the material material.

The following code example illustrates the setup of a box:

// Creating the iron box 1 with a side lengths of 2.5 at the global position (2,3,4).
// Note that the box is
// automatically added to the simulation world and is immediately part of the entire
// simulation. The function returns a handle to the newly created box, which can
// be used to for instance rotate the box around the global y-axis.
BoxID box = createBox( *globalBodyStorage, forest->getBlockStorage(), storageID, 1, Vec3(2,3,4), Vec3(2.5,2.5,2.5) );
if (box != nullptr)
box->rotate( 0.0, real_c(math::pi/3.0), 0.0 );
ConvexPolyhedronID walberla::mesh::pe::createConvexPolyhedron ( BodyStorage globalStorage,
BlockStorage &  blocks,
BlockDataID  storageID,
id_t  uid,
Vec3  gpos,
TriangleMesh  mesh,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new ConvexPolyhedron.

Parameters
globalStorageprocess local global storage
blocksstorage of all the blocks on this process
storageIDBlockDataID of the BlockStorage block datum
uidThe user-specific ID of the box.
gposThe global position of the center of the box.
meshSurface mesh of convex polyhedron
materialThe material of the box.
globalspecifies if the box should be created in the global storage
communicatingspecifies if the box should take part in synchronization (syncNextNeighbour, syncShadowOwner)
infiniteMassspecifies if the box has infinite mass and will be treated as an obstacle
Returns
Handle for the new box.
Exceptions
std::invalid_argumentInvalid box radius.
std::invalid_argumentInvalid global box position.

This function creates a box primitive in the pe simulation system. The box with user-specific ID uid is placed at the global position gpos, has the side lengths lengths, and consists of the material material.

The following code example illustrates the setup of a box:

// Creating the iron box 1 with a side lengths of 2.5 at the global position (2,3,4).
// Note that the box is
// automatically added to the simulation world and is immediately part of the entire
// simulation. The function returns a handle to the newly created box, which can
// be used to for instance rotate the box around the global y-axis.
BoxID box = createBox( *globalBodyStorage, forest->getBlockStorage(), storageID, 1, Vec3(2,3,4), Vec3(2.5,2.5,2.5) );
if (box != nullptr)
box->rotate( 0.0, real_c(math::pi/3.0), 0.0 );
CylindricalBoundaryID walberla::pe::createCylindricalBoundary ( BodyStorage globalStorage,
id_t  uid,
const Vec3 gpos,
const real_t  radius,
MaterialID  material = Material::find("iron") 
)

Setup of a new Cylindrical Boundary.

Parameters
globalStorageprocess local global storage
uidThe user-specific ID.
gposOne point located on the central axis.
radiusradius of the cylinder
materialThe material of the boundary.
Returns
Handle for the new boundary.
EllipsoidID walberla::pe::createEllipsoid ( BodyStorage globalStorage,
BlockStorage &  blocks,
BlockDataID  storageID,
id_t  uid,
const Vec3 gpos,
const Vec3 semiAxes,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new Ellipsoid.

Parameters
globalStorageprocess local global storage
blocksstorage of all the blocks on this process
storageIDBlockDataID of the BlockStorage block datum
uidThe user-specific ID of the Ellipsoid.
gposThe global position of the center of the Ellipsoid.
semiAxesThe semiAxes of the Ellipsoid \( (0..\infty) \).
materialThe material of the Ellipsoid.
globalspecifies if the Ellipsoid should be created in the global storage
communicatingspecifies if the Ellipsoid should take part in synchronization (syncNextNeighbour, syncShadowOwner)
infiniteMassspecifies if the Ellipsoid has infinite mass and will be treated as an obstacle
Returns
Handle for the new Ellipsoid.
Exceptions
std::invalid_argumentInvalid Ellipsoid semi-axes.
std::invalid_argumentInvalid global Ellipsoid position.

This function creates a Ellipsoid primitive in the pe simulation system. The Ellipsoid with user-specific ID uid is placed at the global position gpos, has the semi-axes semiAxes, and consists of the material material.

PlaneID walberla::pe::createPlane ( BodyStorage globalStorage,
id_t  uid,
Vec3  normal,
const Vec3 gpos,
MaterialID  material = Material::find("iron") 
)

Setup of a new Plane.

Parameters
globalStorageprocess local global storage
uidThe user-specific ID of the plane.
normalNormal of the plane.
gposOne point located on the plane.
materialThe material of the plane.
Returns
Handle for the new plane.

This function creates a plane primitive in the simulation system. The plane with user-specific ID uid is placed at the global position gpos, oriented with normal and consists of the material material

The following code example illustrates the setup of a plane:

// Create a plane
PlaneID plane = createPlane( *globalBodyStorage, 1, Vec3(2,3,4), Vec3(2,3,4) );
SphereID walberla::pe::createSphere ( BodyStorage globalStorage,
BlockStorage &  blocks,
BlockDataID  storageID,
id_t  uid,
const Vec3 gpos,
real_t  radius,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new Sphere.

Parameters
globalStorageprocess local global storage
blocksstorage of all the blocks on this process
storageIDBlockDataID of the BlockStorage block datum
uidThe user-specific ID of the sphere.
gposThe global position of the center of the sphere.
radiusThe radius of the sphere \( (0..\infty) \).
materialThe material of the sphere.
globalspecifies if the sphere should be created in the global storage
communicatingspecifies if the sphere should take part in synchronization (syncNextNeighbour, syncShadowOwner)
infiniteMassspecifies if the sphere has infinite mass and will be treated as an obstacle
Returns
Handle for the new sphere.
Exceptions
std::invalid_argumentInvalid sphere radius.
std::invalid_argumentInvalid global sphere position.

This function creates a sphere primitive in the pe simulation system. The sphere with user-specific ID uid is placed at the global position gpos, has the radius radius, and consists of the material material.

The following code example illustrates the setup of a sphere:

// Create a sphere and rotate it after successfull creation.
SphereID sphere = createSphere( *globalBodyStorage, forest->getBlockStorage(), storageID, 1, Vec3(2,3,4), real_t(1) );
if (sphere != nullptr)
sphere->rotate( 0.0, real_c(math::pi/3.0), 0.0 );
template<typename... BodyTypes>
SphereID walberla::pe::createSphere ( Union< BodyTypes... > *  un,
id_t  uid,
const Vec3 gpos,
real_t  radius,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new Sphere directly attached to a Union.

Template Parameters
BodyTypesall geometries the Union is able to contain
Exceptions
std::runtime_errorSphere TypeID not initalized!
std::invalid_argumentcreateSphere: Union argument is NULL
std::logic_errorcreateSphere: Union is remote
std::invalid_argumentInvalid sphere radius
See also
createSphere for more details
SquirmerID walberla::pe::createSquirmer ( BodyStorage globalStorage,
BlockStorage &  blocks,
BlockDataID  storageID,
id_t  uid,
const Vec3 gpos,
real_t  radius,
real_t  squirmerVelocity,
real_t  squirmerBeta,
MaterialID  material = Material::find("iron"),
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new Squirmer.

Parameters
globalStorageprocess local global storage
blocksstorage of all the blocks on this process
storageIDBlockDataID of the BlockStorage block datum
uidThe user-specific ID of the sphere.
gposThe global position of the center of the sphere.
radiusThe radius of the sphere \( (0..\infty) \).
squirmerVelocityThe velocity of the squirmer.
squirmerBetaThe dipolar characteristic of the squirmer.
materialThe material of the sphere.
globalspecifies if the sphere should be created in the global storage
communicatingspecifies if the sphere should take part in synchronization (syncNextNeighbour, syncShadowOwner)
infiniteMassspecifies if the sphere has infinite mass and will be treated as an obstacle
Returns
Handle for the new sphere.
Exceptions
std::invalid_argumentInvalid sphere radius.
std::invalid_argumentInvalid global sphere position.

This function creates a squirmer primitive in the pe simulation system. The squirmer with user-specific ID uid is placed at the global position gpos, has the radius radius, and consists of the material material. Its self-propulsion velocity is squirmerVelocity and its dipolar characteristic is squirmerBeta.

template<typename... BodyTypes>
Union<BodyTypes...>* walberla::pe::createUnion ( BodyStorage globalStorage,
BlockStorage &  blocks,
BlockDataID  storageID,
id_t  uid,
const Vec3 gpos,
bool  global = false,
bool  communicating = true,
bool  infiniteMass = false 
)

Setup of a new Union.

Template Parameters
BodyTypesall geometries the Union should be able to contain
Parameters
globalStorageprocess local global storage
blocksstorage of all the blocks on this process
storageIDBlockDataID of the BlockStorage block datum
uidThe user-specific ID of the union.
gposThe global position of the center of the union.
globalspecifies if the union should be created in the global storage
communicatingspecifies if the union should take part in synchronization (syncNextNeighbour, syncShadowOwner)
infiniteMassspecifies if the union has infinite mass and will be treated as an obstacle
Returns
Handle for the new union.
Exceptions
std::runtime_errorUnion TypeID not initalized!

The code example illustrates the setup of a Union. For convenience the following typedefs were made. You can adapt them to your needs.

using UnionT = Union<Box, Capsule, Sphere>;
using UnionID = UnionT *;
// Create a union and add a box, capsule and sphere.
UnionID un = createUnion<Box, Capsule, Sphere>( *globalBodyStorage, forest->getBlockStorage(), storageID, 1, Vec3(2,3,4) );
if (un != nullptr)
{
createBox ( un, 1, Vec3(2,3,4), Vec3(2.5,2.5,2.5) );
createCapsule( un, 1, Vec3(3,3,4), real_t(1), real_t(1) );
createSphere ( un, 1, Vec3(4,3,4), real_t(1) );
}
template<typename BodyTypeTuple , int N = std::tuple_size<BodyTypeTuple>::value - 1>
static void walberla::pe::SetBodyTypeIDs< BodyTypeTuple, N >::execute ( )
inlinestatic

Initial setup of static type ids.

Template Parameters
BodyTypeTuplestd::tuple of all geometries used throughout the simulation

Each geometry has a unique type id which is used to identify the geometry. These type ids have to be set at the start of the simulation using this function.

Note
You have to call this function on all processes identically.

The template parameter is a std::tuple of geometries used during the simulation. Since the tuple is used often a typedef is used.

typedef std::tuple<Box, Capsule, Plane, Sphere, UnionT> BodyTypeTuple ;

The function call then looks like: