Commit c47b6cb9 authored by Sebastian Eibl's avatar Sebastian Eibl

added box and cylindrical boundary

parent 2ac81896
......@@ -27,7 +27,7 @@ if __name__ == '__main__':
os.makedirs(args.path + "/src/mesa_pd/mpi/notifications", exist_ok = True)
os.makedirs(args.path + "/src/mesa_pd/vtk", exist_ok = True)
shapes = ["Sphere", "HalfSpace"]
shapes = ["Sphere", "HalfSpace", "CylindricalBoundary", "Box"]
ps = data.ParticleStorage()
ch = data.ContactHistory()
......
......@@ -57,6 +57,7 @@ public:
void rotate(const Vector3<Type>& rot);
void rotate(const Vector3<Type>& axis, const real_t& angle);
void rotate(const Rot3<Type>& rot);
private:
Quaternion<Type> quat_;
Matrix3<Type> mat_;
......@@ -115,6 +116,14 @@ inline void Rot3<Type>::rotate(const Vector3<Type>& axis, const real_t& angle)
}
}
template< typename Type > // floating point type
inline void Rot3<Type>::rotate(const Rot3<Type>& rot)
{
quat_ = rot.quat_ * quat_;
mat_ = quat_.toRotationMatrix();
WALBERLA_ASSERT_FLOAT_EQUAL( mat_.getDeterminant(), real_t(1), "Corrupted rotation matrix determinant" );
}
template< typename Type > // floating point type
inline std::ostream& operator<<( std::ostream& os, const Rot3<Type>& r )
{
......
......@@ -34,9 +34,9 @@ bool detectSphereSphereCollision( const Vec3& pos1,
const real_t& radius1,
const Vec3& pos2,
const real_t& radius2,
Vec3& contactPoint,
Vec3& contactNormal,
real_t& penetrationDepth,
Vec3& contactPoint,
Vec3& contactNormal,
real_t& penetrationDepth,
const real_t& contactThreshold)
{
contactNormal = pos1 - pos2;
......@@ -53,14 +53,128 @@ bool detectSphereSphereCollision( const Vec3& pos1,
return false;
}
inline
bool detectSphereBoxCollision( const Vec3& pos1,
const real_t& radius1,
const Vec3& pos2,
const Vec3& edgeLength2,
const Rot3& rot2,
Vec3& contactPoint,
Vec3& contactNormal,
real_t& penetrationDepth,
const real_t& contactThreshold)
{
//WALBERLA_ABORT(s << b);
const Vec3 l( real_t(0.5)*edgeLength2 ); // Box half side lengths
const Mat3& R( rot2.getMatrix() ); // Rotation of the box
bool outside( false );
// Calculating the distance between the sphere and the box
const Vec3 d( pos1 - pos2 );
// Calculating the the sphere/box distance in the box's frame of reference
Vec3 p( d[0]*R[0] + d[1]*R[3] + d[2]*R[6],
d[0]*R[1] + d[1]*R[4] + d[2]*R[7],
d[0]*R[2] + d[1]*R[5] + d[2]*R[8] );
// Projection of the x-component
if ( p[0] < -l[0] ) { p[0] = -l[0]; outside = true; }
else if( p[0] > l[0] ) { p[0] = l[0]; outside = true; }
// Projection of the y-component
if ( p[1] < -l[1] ) { p[1] = -l[1]; outside = true; }
else if( p[1] > l[1] ) { p[1] = l[1]; outside = true; }
// Projection of the z-component
if ( p[2] < -l[2] ) { p[2] = -l[2]; outside = true; }
else if( p[2] > l[2] ) { p[2] = l[2]; outside = true; }
// Special treatment if the sphere's center of mass is inside the box
// In this case, a contact at the sphere's center of mass with a normal away from
// the closest face of the box is generated.
if( !outside )
{
real_t dist( std::fabs(p[0]) - l[0] );
size_t face( 0 );
for( size_t i=1; i<3; ++i ) {
const real_t tmp( std::fabs(p[i]) - l[i] );
if( dist < tmp ) {
dist = tmp;
face = i;
}
}
// Calculating the normal direction of the contact
Vec3 n;
n[face] = math::sign( p[face] );
n = R * n;
// Calculating the contact distance
dist -= radius1;
// Creating a single contact between the sphere and the box
contactPoint = pos1;
contactNormal = n;
penetrationDepth = dist;
return true;
}
const Vec3 q( R * p ); // Transformation from the projection to the global world frame
const Vec3 n( d - q ); // Normal direction of the contact (pointing from the box to the sphere)
const real_t dist( n.length() - radius1 ); // Distance between the sphere and the box
// Creating a single contact between the sphere and the box
if( dist < contactThreshold )
{
contactPoint = pos2+q;
contactNormal = n.getNormalizedOrZero();
if (contactNormal.sqrLength() < real_t(0.1))
{
contactNormal = Vec3(1,0,0);
}
penetrationDepth = dist;
return true;
}
return false;
}
inline
bool detectSphereCylindricalBoundaryCollision( const Vec3& pos1,
const real_t& radius1,
const Vec3& pos2,
const real_t& radius2,
const Vec3& axis2,
Vec3& contactPoint,
Vec3& contactNormal,
real_t& penetrationDepth,
const real_t& contactThreshold)
{
WALBERLA_ASSERT_FLOAT_EQUAL( axis2.sqrLength(), real_t(1));
WALBERLA_ASSERT_GREATER( radius2, radius1 );
const Vec3 dist = (pos1 - pos2) - ((pos1 - pos2) * axis2) * axis2;
const real_t effRadius = radius2 - radius1;
if( effRadius * effRadius - dist.sqrLength() < contactThreshold ) {
contactNormal = -dist.getNormalized();
penetrationDepth = effRadius - dist.length();
contactPoint = ( pos1 - ( radius1 + penetrationDepth ) * contactNormal );
return true;
}
return false;
}
inline
bool detectSphereHalfSpaceCollision( const Vec3& pos1,
const real_t& radius1,
const Vec3& pos2,
const Vec3& normal2,
Vec3& contactPoint,
Vec3& contactNormal,
real_t& penetrationDepth,
Vec3& contactPoint,
Vec3& contactNormal,
real_t& penetrationDepth,
const real_t& contactThreshold)
{
/**
......@@ -86,7 +200,7 @@ bool detectSphereHalfSpaceCollision( const Vec3& pos1,
}
} //namespace collision_detection
} //namespace analytic
} //namespace collision_detection
} //namespace mesa_pd
} //namespace walberla
......@@ -23,6 +23,8 @@
#include <mesa_pd/collision_detection/AnalyticCollisionFunctions.h>
#include <mesa_pd/data/DataTypes.h>
#include <mesa_pd/data/shape/BaseShape.h>
#include <mesa_pd/data/shape/Box.h>
#include <mesa_pd/data/shape/CylindricalBoundary.h>
#include <mesa_pd/data/shape/HalfSpace.h>
#include <mesa_pd/data/shape/Sphere.h>
......@@ -72,6 +74,34 @@ public:
const data::Sphere& geo2,
Accessor& ac);
template <typename Accessor>
bool operator()( const size_t idx1,
const size_t idx2,
const data::Sphere& s,
const data::Box& bx,
Accessor& ac );
template <typename Accessor>
bool operator()( const size_t idx1,
const size_t idx2,
const data::Box& bx,
const data::Sphere& s,
Accessor& ac);
template <typename Accessor>
bool operator()( const size_t idx1,
const size_t idx2,
const data::Sphere& s,
const data::CylindricalBoundary& cb,
Accessor& ac );
template <typename Accessor>
bool operator()( const size_t idx1,
const size_t idx2,
const data::CylindricalBoundary& cb,
const data::Sphere& s,
Accessor& ac);
template <typename Accessor>
bool operator()( const size_t idx1,
const size_t idx2,
......@@ -131,6 +161,68 @@ inline bool AnalyticContactDetection::operator()( const size_t idx1,
getContactThreshold());
}
template <typename Accessor>
inline bool AnalyticContactDetection::operator()( const size_t idx1,
const size_t idx2,
const data::Sphere& s,
const data::Box& bx,
Accessor& ac )
{
getIdx1() = idx1;
getIdx2() = idx2;
return analytic::detectSphereBoxCollision(ac.getPosition(getIdx1()),
s.getRadius(),
ac.getPosition(getIdx2()),
bx.getEdgeLength(),
ac.getRotation(getIdx2()),
getContactPoint(),
getContactNormal(),
getPenetrationDepth(),
getContactThreshold());
}
template <typename Accessor>
inline bool AnalyticContactDetection::operator()( const size_t idx1,
const size_t idx2,
const data::Box& bx,
const data::Sphere& s,
Accessor& ac)
{
return operator()(idx2, idx1, s, bx, ac);
}
template <typename Accessor>
inline bool AnalyticContactDetection::operator()( const size_t idx1,
const size_t idx2,
const data::Sphere& s,
const data::CylindricalBoundary& cb,
Accessor& ac )
{
WALBERLA_ASSERT_UNEQUAL(idx1, idx2, "colliding with itself!");
getIdx1() = idx1;
getIdx2() = idx2;
return analytic::detectSphereCylindricalBoundaryCollision(ac.getPosition(getIdx1()),
s.getRadius(),
ac.getPosition(getIdx2()),
cb.getRadius(),
cb.getAxis(),
getContactPoint(),
getContactNormal(),
getPenetrationDepth(),
getContactThreshold());
}
template <typename Accessor>
inline bool AnalyticContactDetection::operator()( const size_t idx1,
const size_t idx2,
const data::CylindricalBoundary& cb,
const data::Sphere& s,
Accessor& ac)
{
return operator()(idx2, idx1, s, cb, ac);
}
template <typename Accessor>
inline bool AnalyticContactDetection::operator()( const size_t idx1,
const size_t idx2,
......
......@@ -20,6 +20,8 @@
#pragma once
#include <mesa_pd/data/Flags.h>
namespace walberla {
namespace mesa_pd {
namespace collision_detection {
......
......@@ -31,6 +31,8 @@
#include <mesa_pd/data/shape/BaseShape.h>
#include <mesa_pd/data/shape/Sphere.h>
#include <mesa_pd/data/shape/HalfSpace.h>
#include <mesa_pd/data/shape/CylindricalBoundary.h>
#include <mesa_pd/data/shape/Box.h>
#include <core/Abort.h>
#include <core/debug/Debug.h>
......@@ -58,6 +60,8 @@ struct ShapeStorage
};
//Make sure that no two different shapes have the same unique identifier!
static_assert( Sphere::SHAPE_TYPE != HalfSpace::SHAPE_TYPE, "Shape types have to be different!" );
static_assert( Sphere::SHAPE_TYPE != CylindricalBoundary::SHAPE_TYPE, "Shape types have to be different!" );
static_assert( Sphere::SHAPE_TYPE != Box::SHAPE_TYPE, "Shape types have to be different!" );
template <typename ShapeT, typename... Args>
size_t ShapeStorage::create(Args&&... args)
......@@ -75,6 +79,8 @@ ReturnType ShapeStorage::singleDispatch( ParticleStorage& ps, size_t idx, func&
{
case Sphere::SHAPE_TYPE : return f(ps, idx, *static_cast<Sphere*>(shapes[ps.getShapeID(idx)].get()));
case HalfSpace::SHAPE_TYPE : return f(ps, idx, *static_cast<HalfSpace*>(shapes[ps.getShapeID(idx)].get()));
case CylindricalBoundary::SHAPE_TYPE : return f(ps, idx, *static_cast<CylindricalBoundary*>(shapes[ps.getShapeID(idx)].get()));
case Box::SHAPE_TYPE : return f(ps, idx, *static_cast<Box*>(shapes[ps.getShapeID(idx)].get()));
default : WALBERLA_ABORT("Shape type (" << shapes[ps.getShapeID(idx)]->getShapeType() << ") could not be determined!");
}
}
......@@ -100,6 +106,16 @@ ReturnType ShapeStorage::doubleDispatch( ParticleStorage& ps, size_t idx, size_t
*static_cast<Sphere*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<HalfSpace*>(shapes[ps.getShapeID(idy)].get()));
case CylindricalBoundary::SHAPE_TYPE : return f(ps,
idx,
*static_cast<Sphere*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<CylindricalBoundary*>(shapes[ps.getShapeID(idy)].get()));
case Box::SHAPE_TYPE : return f(ps,
idx,
*static_cast<Sphere*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<Box*>(shapes[ps.getShapeID(idy)].get()));
default : WALBERLA_ABORT("Shape type (" << shapes[ps.getShapeID(idy)]->getShapeType() << ") could not be determined!");
}
case HalfSpace::SHAPE_TYPE :
......@@ -115,6 +131,66 @@ ReturnType ShapeStorage::doubleDispatch( ParticleStorage& ps, size_t idx, size_t
*static_cast<HalfSpace*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<HalfSpace*>(shapes[ps.getShapeID(idy)].get()));
case CylindricalBoundary::SHAPE_TYPE : return f(ps,
idx,
*static_cast<HalfSpace*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<CylindricalBoundary*>(shapes[ps.getShapeID(idy)].get()));
case Box::SHAPE_TYPE : return f(ps,
idx,
*static_cast<HalfSpace*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<Box*>(shapes[ps.getShapeID(idy)].get()));
default : WALBERLA_ABORT("Shape type (" << shapes[ps.getShapeID(idy)]->getShapeType() << ") could not be determined!");
}
case CylindricalBoundary::SHAPE_TYPE :
switch (shapes[ps.getShapeID(idy)]->getShapeType())
{
case Sphere::SHAPE_TYPE : return f(ps,
idx,
*static_cast<CylindricalBoundary*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<Sphere*>(shapes[ps.getShapeID(idy)].get()));
case HalfSpace::SHAPE_TYPE : return f(ps,
idx,
*static_cast<CylindricalBoundary*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<HalfSpace*>(shapes[ps.getShapeID(idy)].get()));
case CylindricalBoundary::SHAPE_TYPE : return f(ps,
idx,
*static_cast<CylindricalBoundary*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<CylindricalBoundary*>(shapes[ps.getShapeID(idy)].get()));
case Box::SHAPE_TYPE : return f(ps,
idx,
*static_cast<CylindricalBoundary*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<Box*>(shapes[ps.getShapeID(idy)].get()));
default : WALBERLA_ABORT("Shape type (" << shapes[ps.getShapeID(idy)]->getShapeType() << ") could not be determined!");
}
case Box::SHAPE_TYPE :
switch (shapes[ps.getShapeID(idy)]->getShapeType())
{
case Sphere::SHAPE_TYPE : return f(ps,
idx,
*static_cast<Box*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<Sphere*>(shapes[ps.getShapeID(idy)].get()));
case HalfSpace::SHAPE_TYPE : return f(ps,
idx,
*static_cast<Box*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<HalfSpace*>(shapes[ps.getShapeID(idy)].get()));
case CylindricalBoundary::SHAPE_TYPE : return f(ps,
idx,
*static_cast<Box*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<CylindricalBoundary*>(shapes[ps.getShapeID(idy)].get()));
case Box::SHAPE_TYPE : return f(ps,
idx,
*static_cast<Box*>(shapes[ps.getShapeID(idx)].get()),
idy,
*static_cast<Box*>(shapes[ps.getShapeID(idy)].get()));
default : WALBERLA_ABORT("Shape type (" << shapes[ps.getShapeID(idy)]->getShapeType() << ") could not be determined!");
}
default : WALBERLA_ABORT("Shape type (" << shapes[ps.getShapeID(idx)]->getShapeType() << ") could not be determined!");
......
//======================================================================================================================
//
// 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 Box.h
//! \author Sebastian Eibl <sebastian.eibl@fau.de>
//
//======================================================================================================================
#pragma once
#include <mesa_pd/data/shape/BaseShape.h>
#include <core/math/Constants.h>
namespace walberla {
namespace mesa_pd {
namespace data {
class Box : public BaseShape
{
public:
explicit Box(const Vec3& edgeLength)
: BaseShape(Box::SHAPE_TYPE)
, edgeLength_(edgeLength)
{}
const Vec3& getEdgeLength() const { return edgeLength_; }
real_t getVolume() const override { return edgeLength_[0] * edgeLength_[1] * edgeLength_[2]; };
void updateMassAndInertia(const real_t density) override;
static const int SHAPE_TYPE = 3; ///< Unique shape type identifier for boxes.\ingroup mesa_pd_shape
private:
Vec3 edgeLength_; ///< edge length of the box
};
inline
void Box::updateMassAndInertia(const real_t density)
{
const real_t m = getVolume() * density;
const Mat3 I = Mat3::makeDiagonalMatrix(
edgeLength_[1]*edgeLength_[1] + edgeLength_[2]*edgeLength_[2] ,
edgeLength_[0]*edgeLength_[0] + edgeLength_[2]*edgeLength_[2] ,
edgeLength_[0]*edgeLength_[0] + edgeLength_[1]*edgeLength_[1] ) * (m / static_cast<real_t>( 12 ));
getInvMass() = real_t(1.0) / m;
getInvInertiaBF() = I.getInverse();
}
} //namespace data
} //namespace mesa_pd
} //namespace walberla
//======================================================================================================================
//
// 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 CylindricalBoundary.h
//! \author Sebastian Eibl <sebastian.eibl@fau.de>
//
//======================================================================================================================
#pragma once
#include <mesa_pd/data/shape/BaseShape.h>
#include <core/math/Constants.h>
namespace walberla {
namespace mesa_pd {
namespace data {
class CylindricalBoundary : public BaseShape
{
public:
explicit CylindricalBoundary(const real_t& radius, const Vec3& axis)
: BaseShape(CylindricalBoundary::SHAPE_TYPE)
, radius_(radius)
, axis_(axis)
{
WALBERLA_CHECK_FLOAT_EQUAL(axis.sqrLength(), real_t(1.0), "Axis has to be normalized!");
}
const real_t& getRadius() const { return radius_; }
const Vec3& getAxis() const { return axis_; }
real_t getVolume() const override { return std::numeric_limits<real_t>::infinity(); };
void updateMassAndInertia(const real_t density) override;
static const int SHAPE_TYPE = 2; ///< Unique shape type identifier for cylindrical boundaries.\ingroup mesa_pd_shape
private:
real_t radius_; ///< radius of the cylinder
Vec3 axis_; ///< axis of the cylinder
};
inline
void CylindricalBoundary::updateMassAndInertia(const real_t /*density*/)
{
getInvMass() = real_t(0.0);
getInvInertiaBF() = Mat3(real_t(0.0));
}
} //namespace data
} //namespace mesa_pd
} //namespace walberla
......@@ -31,6 +31,8 @@
#include <mesa_pd/data/shape/BaseShape.h>
#include <mesa_pd/data/shape/Sphere.h>
#include <mesa_pd/data/shape/HalfSpace.h>
#include <mesa_pd/data/shape/CylindricalBoundary.h>
#include <mesa_pd/data/shape/Box.h>
#include <core/Abort.h>
#include <core/debug/Debug.h>
......@@ -76,6 +78,16 @@ auto DoubleCast::operator()( size_t idx, size_t idy, Accessor& ac, func& f, Args
*static_cast<Sphere*>(ac.getShape(idx)),
*static_cast<HalfSpace*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case CylindricalBoundary::SHAPE_TYPE : return f(idx,
idy,
*static_cast<Sphere*>(ac.getShape(idx)),
*static_cast<CylindricalBoundary*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case Box::SHAPE_TYPE : return f(idx,
idy,
*static_cast<Sphere*>(ac.getShape(idx)),
*static_cast<Box*>(ac.getShape(idy)),
std::forward<Args>(args)...);
default : WALBERLA_ABORT("Shape type (" << ac.getShape(idy)->getShapeType() << ") could not be determined!");
}
case HalfSpace::SHAPE_TYPE :
......@@ -91,6 +103,66 @@ auto DoubleCast::operator()( size_t idx, size_t idy, Accessor& ac, func& f, Args
*static_cast<HalfSpace*>(ac.getShape(idx)),
*static_cast<HalfSpace*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case CylindricalBoundary::SHAPE_TYPE : return f(idx,
idy,
*static_cast<HalfSpace*>(ac.getShape(idx)),
*static_cast<CylindricalBoundary*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case Box::SHAPE_TYPE : return f(idx,
idy,
*static_cast<HalfSpace*>(ac.getShape(idx)),
*static_cast<Box*>(ac.getShape(idy)),
std::forward<Args>(args)...);
default : WALBERLA_ABORT("Shape type (" << ac.getShape(idy)->getShapeType() << ") could not be determined!");
}
case CylindricalBoundary::SHAPE_TYPE :
switch (ac.getShape(idy)->getShapeType())
{
case Sphere::SHAPE_TYPE : return f(idx,
idy,
*static_cast<CylindricalBoundary*>(ac.getShape(idx)),
*static_cast<Sphere*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case HalfSpace::SHAPE_TYPE : return f(idx,
idy,
*static_cast<CylindricalBoundary*>(ac.getShape(idx)),
*static_cast<HalfSpace*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case CylindricalBoundary::SHAPE_TYPE : return f(idx,
idy,
*static_cast<CylindricalBoundary*>(ac.getShape(idx)),
*static_cast<CylindricalBoundary*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case Box::SHAPE_TYPE : return f(idx,
idy,
*static_cast<CylindricalBoundary*>(ac.getShape(idx)),
*static_cast<Box*>(ac.getShape(idy)),
std::forward<Args>(args)...);
default : WALBERLA_ABORT("Shape type (" << ac.getShape(idy)->getShapeType() << ") could not be determined!");
}
case Box::SHAPE_TYPE :
switch (ac.getShape(idy)->getShapeType())
{
case Sphere::SHAPE_TYPE : return f(idx,
idy,
*static_cast<Box*>(ac.getShape(idx)),
*static_cast<Sphere*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case HalfSpace::SHAPE_TYPE : return f(idx,
idy,
*static_cast<Box*>(ac.getShape(idx)),
*static_cast<HalfSpace*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case CylindricalBoundary::SHAPE_TYPE : return f(idx,
idy,
*static_cast<Box*>(ac.getShape(idx)),
*static_cast<CylindricalBoundary*>(ac.getShape(idy)),
std::forward<Args>(args)...);
case Box::SHAPE_TYPE : return f(idx,
idy,
*static_cast<Box*>(ac.getShape(idx)),
*static_cast<Box*>(ac.getShape(idy)),
std::forward<Args>(args)...);
default : WALBERLA_ABORT("Shape type (" << ac.getShape(idy)->getShapeType() << ") could not be determined!");
}
default : WALBERLA_ABORT("Shape type (" << ac.getShape(idx)->getShapeType() << ") could not be determined!");
......
......@@ -31,6 +31,8 @@
#include <mesa_pd/data/shape/BaseShape.h>
#include <mesa_pd/data/shape/Sphere.h>
#include <mesa_pd/data/shape/HalfSpace.h>
#include <mesa_pd/data/shape/CylindricalBoundary.h>
#include <mesa_pd/data/shape/Box.h>
#include <core/Abort.h>
#include <core/debug/Debug.h>
......@@ -64,6 +66,8 @@ auto SingleCast::operator()( size_t idx, Accessor& ac, func& f, Args&&... args )
{
case Sphere::SHAPE_TYPE : return f(idx, *static_cast<Sphere*>(ac.getShape(idx)), std::forward<Args>(args)...);
case HalfSpace::SHAPE_TYPE : return f(idx, *static_cast<HalfSpace*>(ac.getShape(idx)), std::forward<Args>(args)...);
case CylindricalBoundary::SHAPE_TYPE : return f(idx, *static_cast<CylindricalBoundary*>(ac.getShape(idx)), std::forward<Args>(args)...);
case Box::SHAPE_TYPE : return f(idx, *static_cast<Box*>(ac.getShape(idx)), std::forward<Args>(args)...);
default : WALBERLA_ABORT("Shape type (" << ac.getShape(idx)->getShapeType() << ") could not be determined!");
}
}
......
......@@ -4,6 +4,9 @@
#
###################################################################################################
waLBerla_compile_test( NAME MESA_PD_COLLISIONDETECTION_AnalyticCollisionFunctions FILES collision_detection/AnalyticCollisionFunctions.cpp DEPENDS core )
waLBerla_execute_test( NAME MESA_PD_COLLISIONDETECTION_AnalyticCollisionFunctions )
waLBerla_compile_test( NAME MESA_PD_COLLISIONDETECTION_AnalyticContactDetection FILES collision_detection/AnalyticContactDetection.cpp DEPENDS core )
waLBerla_execute_test( NAME MESA_PD_COLLISIONDETECTION_AnalyticContactDetection )
......
//======================================================================================================================
//
// 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 AnalyticCollisionFunctions.cpp
//! \author Sebastian Eibl <sebastian.eibl@fau.de>