Commit f50ec7bd authored by Sebastian Eibl's avatar Sebastian Eibl
Browse files

mesa_pd shapes are now pack- and unpackable

parent 7f17d895
Pipeline #19968 passed with stages
in 538 minutes and 50 seconds
......@@ -120,6 +120,7 @@ if __name__ == '__main__':
comm.append(mpi.ClearNextNeighborSync())
comm.append(mpi.ReduceContactHistory())
comm.append(mpi.ReduceProperty())
comm.append(mpi.ShapePackUnpack(shapes))
comm.append(mpi.SyncGhostOwners(ps))
comm.append(mpi.SyncNextNeighbors(ps))
......
# -*- coding: utf-8 -*-
from ..utility import generateFile
class ShapePackUnpack:
def __init__(self, shapes):
self.shapes = shapes
def generate(self, path):
context = dict()
context["shapes"] = self.shapes
generateFile(path, 'mpi/ShapePackUnpack.templ.h', context)
......@@ -4,6 +4,7 @@ from .BroadcastProperty import BroadcastProperty
from .ClearNextNeighborSync import ClearNextNeighborSync
from .ReduceContactHistory import ReduceContactHistory
from .ReduceProperty import ReduceProperty
from .ShapePackUnpack import ShapePackUnpack
from .SyncGhostOwners import SyncGhostOwners
from .SyncNextNeighbors import SyncNextNeighbors
......@@ -11,6 +12,7 @@ __all__ = ['BroadcastProperty',
'ClearNextNeighborSync',
'ReduceContactHistory',
'ReduceProperty',
'ShapePackUnpack',
'SyncGhostOwners',
'SyncNextNeighbors',
]
//======================================================================================================================
//
// 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 ShapePackUnpack.h
//! \author Sebastian Eibl <sebastian.eibl@fau.de>
//
//======================================================================================================================
//======================================================================================================================
//
// THIS FILE IS GENERATED - PLEASE CHANGE THE TEMPLATE !!!
//
//======================================================================================================================
#pragma once
#include <mesa_pd/data/shape/BaseShape.h>
{%- for shape in shapes %}
#include <mesa_pd/data/shape/{{shape}}.h>
{%- endfor %}
#include <core/mpi/RecvBuffer.h>
#include <core/mpi/SendBuffer.h>
#include <memory>
namespace walberla {
namespace mpi {
template< typename T, // Element type of SendBuffer
typename G> // Growth policy of SendBuffer
mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf,
const std::shared_ptr<mesa_pd::data::BaseShape>& bs )
{
buf.addDebugMarker( "up" );
buf << bs->getShapeType();
bs->pack(buf);
return buf;
}
template< typename T> // Element type of RecvBuffer
mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf,
std::shared_ptr<mesa_pd::data::BaseShape>& bs )
{
using namespace mesa_pd::data;
buf.readDebugMarker( "up" );
mesa_pd::data::BaseShape::ShapeTypeT shapeType;
buf >> shapeType;
switch (shapeType)
{
{%- for shape in shapes %}
case {{shape}}::SHAPE_TYPE :
bs = std::make_unique<mesa_pd::data::{{shape}}>();
bs->unpack(buf);
break;
{%- endfor %}
default : WALBERLA_ABORT("Shape type (" << shapeType << ") could not be determined!");
}
return buf;
}
} //namespace mpi
} //namespace walberla
......@@ -28,6 +28,7 @@
#include <mesa_pd/data/DataTypes.h>
#include <mesa_pd/data/ParticleStorage.h>
#include <mesa_pd/mpi/ShapePackUnpack.h>
#include <mesa_pd/mpi/notifications/NotificationType.h>
#include <core/mpi/Datatype.h>
......
......@@ -22,6 +22,9 @@
#include <mesa_pd/data/DataTypes.h>
#include <core/mpi/RecvBuffer.h>
#include <core/mpi/SendBuffer.h>
namespace walberla {
namespace mesa_pd {
namespace data {
......@@ -35,6 +38,8 @@ namespace data {
class BaseShape
{
public:
using ShapeTypeT = int;
explicit BaseShape(const int shapeType) : shapeType_(shapeType) {}
virtual ~BaseShape() = default;
......@@ -49,17 +54,20 @@ public:
const Mat3& getInertiaBF() const {return inertiaBF_;}
const Mat3& getInvInertiaBF() const {return invInertiaBF_;}
const int& getShapeType() const {return shapeType_;}
const ShapeTypeT& getShapeType() const {return shapeType_;}
virtual Vec3 support( const Vec3& /*d*/ ) const {WALBERLA_ABORT("Not implemented!");}
virtual void pack(walberla::mpi::SendBuffer& buf);
virtual void unpack(walberla::mpi::RecvBuffer& buf);
static const int INVALID_SHAPE = -1; ///< Unique *invalid* shape type identifier.\ingroup mesa_pd_shape
protected:
real_t mass_ = real_t(0); ///< mass
real_t invMass_ = real_t(0); ///< inverse mass
Mat3 inertiaBF_ = Mat3(real_t(0)); ///< inertia matrix in the body frame
Mat3 invInertiaBF_ = Mat3(real_t(0)); ///< inverse inertia matrix in the body frame
int shapeType_ = INVALID_SHAPE; ///< \ingroup mesa_pd_shape
real_t mass_ = real_t(0); ///< mass
real_t invMass_ = real_t(0); ///< inverse mass
Mat3 inertiaBF_ = Mat3(real_t(0)); ///< inertia matrix in the body frame
Mat3 invInertiaBF_ = Mat3(real_t(0)); ///< inverse inertia matrix in the body frame
ShapeTypeT shapeType_ = INVALID_SHAPE; ///< \ingroup mesa_pd_shape
};
inline
......@@ -68,6 +76,23 @@ void BaseShape::updateMassAndInertia(const real_t /*density*/)
WALBERLA_ABORT("updateMassAndInertia not implemented!");
}
inline
void BaseShape::pack(walberla::mpi::SendBuffer& buf)
{
buf << mass_;
buf << invMass_;
buf << inertiaBF_;
buf << invInertiaBF_;
}
inline
void BaseShape::unpack(walberla::mpi::RecvBuffer& buf)
{
buf >> mass_;
buf >> invMass_;
buf >> inertiaBF_;
buf >> invInertiaBF_;
}
} //namespace data
} //namespace mesa_pd
} //namespace walberla
......@@ -31,7 +31,7 @@ namespace data {
class Box : public BaseShape
{
public:
explicit Box(const Vec3& edgeLength)
explicit Box(const Vec3& edgeLength = Vec3(real_t(1)))
: BaseShape(Box::SHAPE_TYPE)
, edgeLength_(edgeLength)
{}
......@@ -43,6 +43,9 @@ public:
Vec3 support( const Vec3& bfD ) const override;
void pack(walberla::mpi::SendBuffer& buf) override;
void unpack(walberla::mpi::RecvBuffer& buf) override;
constexpr static int SHAPE_TYPE = 3; ///< Unique shape type identifier for boxes.\ingroup mesa_pd_shape
private:
......@@ -73,6 +76,19 @@ Vec3 Box::support( const Vec3& bfD ) const
return relativSupport;
}
inline
void Box::pack(walberla::mpi::SendBuffer& buf)
{
BaseShape::pack(buf);
buf << edgeLength_;
}
inline
void Box::unpack(walberla::mpi::RecvBuffer& buf)
{
BaseShape::unpack(buf);
buf >> edgeLength_;
}
} //namespace data
} //namespace mesa_pd
} //namespace walberla
......@@ -31,7 +31,8 @@ namespace data {
class CylindricalBoundary : public BaseShape
{
public:
explicit CylindricalBoundary(const real_t& radius, const Vec3& axis)
explicit CylindricalBoundary(const real_t& radius = real_t(1),
const Vec3& axis = Vec3(real_t(1), real_t(0), real_t(0)))
: BaseShape(CylindricalBoundary::SHAPE_TYPE)
, radius_(radius)
, axis_(axis)
......@@ -45,6 +46,9 @@ public:
real_t getVolume() const override { return std::numeric_limits<real_t>::infinity(); };
void updateMassAndInertia(const real_t density) override;
void pack(walberla::mpi::SendBuffer& buf) override;
void unpack(walberla::mpi::RecvBuffer& buf) override;
constexpr static int SHAPE_TYPE = 2; ///< Unique shape type identifier for cylindrical boundaries.\ingroup mesa_pd_shape
private:
......@@ -59,6 +63,21 @@ void CylindricalBoundary::updateMassAndInertia(const real_t /*density*/)
invInertiaBF_ = Mat3(real_t(0.0));
}
inline
void CylindricalBoundary::pack(walberla::mpi::SendBuffer& buf)
{
BaseShape::pack(buf);
buf << radius_;
buf << axis_;
}
inline
void CylindricalBoundary::unpack(walberla::mpi::RecvBuffer& buf)
{
BaseShape::unpack(buf);
buf >> radius_;
buf >> axis_;
}
} //namespace data
} //namespace mesa_pd
} //namespace walberla
......@@ -31,7 +31,7 @@ namespace data {
class Ellipsoid : public BaseShape
{
public:
explicit Ellipsoid(const Vec3& semiAxes)
explicit Ellipsoid(const Vec3& semiAxes = Vec3(real_t(1)))
: BaseShape(Ellipsoid::SHAPE_TYPE)
, semiAxes_(semiAxes)
{}
......@@ -43,6 +43,9 @@ public:
Vec3 support( const Vec3& d_loc ) const override;
void pack(walberla::mpi::SendBuffer& buf) override;
void unpack(walberla::mpi::RecvBuffer& buf) override;
constexpr static int SHAPE_TYPE = 4; ///< Unique shape type identifier for boxes.\ingroup mesa_pd_shape
private:
......@@ -73,6 +76,19 @@ Vec3 Ellipsoid::support( const Vec3& d_loc ) const
return local_support;
}
inline
void Ellipsoid::pack(walberla::mpi::SendBuffer& buf)
{
BaseShape::pack(buf);
buf << semiAxes_;
}
inline
void Ellipsoid::unpack(walberla::mpi::RecvBuffer& buf)
{
BaseShape::unpack(buf);
buf >> semiAxes_;
}
} //namespace data
} //namespace mesa_pd
} //namespace walberla
......@@ -35,7 +35,9 @@ namespace data {
class HalfSpace : public BaseShape
{
public:
explicit HalfSpace(const Vec3& normal) : BaseShape(HalfSpace::SHAPE_TYPE), normal_(normal) { updateMassAndInertia(real_t(1.0)); }
explicit HalfSpace(const Vec3& normal = Vec3(real_t(1), real_t(0), real_t(0)))
: BaseShape(HalfSpace::SHAPE_TYPE), normal_(normal)
{ updateMassAndInertia(real_t(1.0)); }
void updateMassAndInertia(const real_t density) override;
......@@ -43,6 +45,9 @@ public:
const Vec3& getNormal() const { return normal_; }
void pack(walberla::mpi::SendBuffer& buf) override;
void unpack(walberla::mpi::RecvBuffer& buf) override;
constexpr static int SHAPE_TYPE = 0; ///< Unique shape type identifier for planes.\ingroup mesa_pd_shape
private:
/**
......@@ -63,6 +68,19 @@ void HalfSpace::updateMassAndInertia(const real_t /*density*/)
invInertiaBF_ = Mat3(real_t(0));
}
inline
void HalfSpace::pack(walberla::mpi::SendBuffer& buf)
{
BaseShape::pack(buf);
buf << normal_;
}
inline
void HalfSpace::unpack(walberla::mpi::RecvBuffer& buf)
{
BaseShape::unpack(buf);
buf >> normal_;
}
} //namespace data
} //namespace mesa_pd
} //namespace walberla
......@@ -31,7 +31,9 @@ namespace data {
class Sphere : public BaseShape
{
public:
explicit Sphere(const real_t& radius) : BaseShape(Sphere::SHAPE_TYPE), radius_(radius) {}
explicit Sphere(const real_t& radius = real_t(1))
: BaseShape(Sphere::SHAPE_TYPE), radius_(radius)
{}
const real_t& getRadius() const { return radius_; }
......@@ -41,6 +43,9 @@ public:
Vec3 support( const Vec3& d ) const override;
void pack(walberla::mpi::SendBuffer& buf) override;
void unpack(walberla::mpi::RecvBuffer& buf) override;
constexpr static int SHAPE_TYPE = 1; ///< Unique shape type identifier for spheres.\ingroup mesa_pd_shape
private:
......@@ -66,6 +71,19 @@ Vec3 Sphere::support( const Vec3& d ) const
return radius_ * d;
}
inline
void Sphere::pack(walberla::mpi::SendBuffer& buf)
{
BaseShape::pack(buf);
buf << radius_;
}
inline
void Sphere::unpack(walberla::mpi::RecvBuffer& buf)
{
BaseShape::unpack(buf);
buf >> radius_;
}
} //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 ShapePackUnpack.h
//! \author Sebastian Eibl <sebastian.eibl@fau.de>
//
//======================================================================================================================
//======================================================================================================================
//
// THIS FILE IS GENERATED - PLEASE CHANGE THE TEMPLATE !!!
//
//======================================================================================================================
#pragma once
#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 <mesa_pd/data/shape/Ellipsoid.h>
#include <core/mpi/RecvBuffer.h>
#include <core/mpi/SendBuffer.h>
#include <memory>
namespace walberla {
namespace mpi {
template< typename T, // Element type of SendBuffer
typename G> // Growth policy of SendBuffer
mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf,
const std::shared_ptr<mesa_pd::data::BaseShape>& bs )
{
buf.addDebugMarker( "up" );
buf << bs->getShapeType();
bs->pack(buf);
return buf;
}
template< typename T> // Element type of RecvBuffer
mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf,
std::shared_ptr<mesa_pd::data::BaseShape>& bs )
{
using namespace mesa_pd::data;
buf.readDebugMarker( "up" );
mesa_pd::data::BaseShape::ShapeTypeT shapeType;
buf >> shapeType;
switch (shapeType)
{
case Sphere::SHAPE_TYPE :
bs = std::make_unique<mesa_pd::data::Sphere>();
bs->unpack(buf);
break;
case HalfSpace::SHAPE_TYPE :
bs = std::make_unique<mesa_pd::data::HalfSpace>();
bs->unpack(buf);
break;
case CylindricalBoundary::SHAPE_TYPE :
bs = std::make_unique<mesa_pd::data::CylindricalBoundary>();
bs->unpack(buf);
break;
case Box::SHAPE_TYPE :
bs = std::make_unique<mesa_pd::data::Box>();
bs->unpack(buf);
break;
case Ellipsoid::SHAPE_TYPE :
bs = std::make_unique<mesa_pd::data::Ellipsoid>();
bs->unpack(buf);
break;
default : WALBERLA_ABORT("Shape type (" << shapeType << ") could not be determined!");
}
return buf;
}
} //namespace mpi
} //namespace walberla
\ No newline at end of file
......@@ -28,6 +28,7 @@
#include <mesa_pd/data/DataTypes.h>
#include <mesa_pd/data/ParticleStorage.h>
#include <mesa_pd/mpi/ShapePackUnpack.h>
#include <mesa_pd/mpi/notifications/NotificationType.h>
#include <core/mpi/Datatype.h>
......
......@@ -170,6 +170,9 @@ waLBerla_execute_test( NAME MESA_PD_MPI_ReduceContactHistory PROCESSES 8 )
waLBerla_compile_test( NAME MESA_PD_MPI_ReduceProperty FILES mpi/ReduceProperty.cpp DEPENDS core )
waLBerla_execute_test( NAME MESA_PD_MPI_ReduceProperty PROCESSES 8 )
waLBerla_compile_test( NAME MESA_PD_MPI_ShapePackUnpack FILES mpi/ShapePackUnpack.cpp DEPENDS core )
waLBerla_execute_test( NAME MESA_PD_MPI_ShapePackUnpack )
waLBerla_compile_test( NAME MESA_PD_MPI_VelocityCorrectionNotification FILES mpi/VelocityCorrectionNotification.cpp DEPENDS core )
waLBerla_execute_test( NAME MESA_PD_MPI_VelocityCorrectionNotification PROCESSES 8)
......
//======================================================================================================================
//
// 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 PackUnpack.cpp
//! \author Sebastian Eibl <sebastian.eibl@fau.de>
//
//======================================================================================================================
#include <mesa_pd/data/shape/Box.h>
#include <mesa_pd/data/shape/CylindricalBoundary.h>
#include <mesa_pd/data/shape/Ellipsoid.h>
#include <mesa_pd/data/shape/HalfSpace.h>
#include <mesa_pd/data/shape/Sphere.h>
#include <mesa_pd/mpi/ShapePackUnpack.h>
#include <core/Environment.h>
#include <core/logging/Logging.h>
#include <core/mpi/RecvBuffer.h>
#include <core/mpi/SendBuffer.h>
#include <iostream>
#include <memory>
namespace walberla {
using namespace walberla::mesa_pd;
void checkBox()
{
using namespace walberla::mpi;
std::shared_ptr<data::BaseShape> bs0 = std::make_shared<data::Box>(Vec3(real_t(2.53), real_t(4.53), real_t(3.53)));
bs0->updateMassAndInertia(real_t(123));
std::shared_ptr<data::BaseShape> bs1 = nullptr;
WALBERLA_LOG_INFO("packing box");
SendBuffer sb;
sb << bs0;
WALBERLA_LOG_INFO("unpacking box");
RecvBuffer rb(sb);
rb >> bs1;
WALBERLA_LOG_INFO("checking box");
WALBERLA_CHECK_EQUAL(bs0->getShapeType(), data::Box::SHAPE_TYPE);
WALBERLA_CHECK_EQUAL(bs1->getShapeType(), data::Box::SHAPE_TYPE);
WALBERLA_CHECK_IDENTICAL(bs0->getMass(), bs1->getMass());
WALBERLA_CHECK_IDENTICAL(bs0->getInvMass(), bs1->getInvMass());
WALBERLA_CHECK_IDENTICAL(bs0->getInertiaBF(), bs1->getInertiaBF());
WALBERLA_CHECK_IDENTICAL(bs0->getInvInertiaBF(), bs1->getInvInertiaBF());
auto bx0 = static_cast<data::Box*> (bs0.get());
auto bx1 = static_cast<data::Box*> (bs1.get());
WALBERLA_CHECK_IDENTICAL(bx0->getEdgeLength(), bx1->getEdgeLength());
}
void checkCylindricalBoundary()
{
using namespace walberla::mpi;
std::shared_ptr<data::BaseShape> bs0 = std::make_shared<data::CylindricalBoundary>(real_t(9.99),
Vec3(real_t(2.53), real_t(4.53), real_t(3.53)).getNormalized());
bs0->updateMassAndInertia(real_t(123));
std::shared_ptr<data::BaseShape> bs1 = nullptr;
WALBERLA_LOG_INFO("packing cylindrical boundary");
SendBuffer sb;
sb << bs0;
WALBERLA_LOG_INFO("unpacking cylindrical boundary");
RecvBuffer rb(sb);
rb >> bs1;
WALBERLA_LOG_INFO("checking cylindrical boundary");
WALBERLA_CHECK_EQUAL(bs0->getShapeType(), data::CylindricalBoundary::SHAPE_TYPE);
WALBERLA_CHECK_EQUAL(bs1->getShapeType(), data::CylindricalBoundary::SHAPE_TYPE);
WALBERLA_CHECK_IDENTICAL(bs0->getMass(), bs1->getMass());
WALBERLA_CHECK_IDENTICAL(bs0->getInvMass(), bs1->getInvMass());
WALBERLA_CHECK_IDENTICAL(bs0->getInertiaBF(), bs1->getInertiaBF());
WALBERLA_CHECK_IDENTICAL(bs0->getInvInertiaBF(), bs1->getInvInertiaBF());
auto cb0 = static_cast<data::CylindricalBoundary*> (bs0.get());
auto cb1 = static_cast<data::CylindricalBoundary*> (bs1.get());
WALBERLA_CHECK_IDENTICAL(cb0->getAxis(), cb1->getAxis());
WALBERLA_CHECK_IDENTICAL(cb0->getRadius(), cb1->getRadius());
}
void checkEllipsoid()
{
using namespace walberla::mpi;