diff --git a/python/mesa_pd.py b/python/mesa_pd.py index 57a8f138210daf92b7d18997adf739780d9c8b90..94cd212a7d618e9381898cb0c3068883052c2bff 100755 --- a/python/mesa_pd.py +++ b/python/mesa_pd.py @@ -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)) diff --git a/python/mesa_pd/mpi/ShapePackUnpack.py b/python/mesa_pd/mpi/ShapePackUnpack.py new file mode 100644 index 0000000000000000000000000000000000000000..cb52010d7fd7e353f712ede06f204131c659f15e --- /dev/null +++ b/python/mesa_pd/mpi/ShapePackUnpack.py @@ -0,0 +1,11 @@ +# -*- 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) diff --git a/python/mesa_pd/mpi/__init__.py b/python/mesa_pd/mpi/__init__.py index 7714d1098c0e44f3d40bbe34e3fd3366347abb1f..c319a8feca8c92c1e302a50b9bce2abb570b1461 100644 --- a/python/mesa_pd/mpi/__init__.py +++ b/python/mesa_pd/mpi/__init__.py @@ -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', ] diff --git a/python/mesa_pd/templates/mpi/ShapePackUnpack.templ.h b/python/mesa_pd/templates/mpi/ShapePackUnpack.templ.h new file mode 100644 index 0000000000000000000000000000000000000000..47e5bd7fc678b353ed6c363b09903edf1e6306f8 --- /dev/null +++ b/python/mesa_pd/templates/mpi/ShapePackUnpack.templ.h @@ -0,0 +1,75 @@ +//====================================================================================================================== +// +// 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 diff --git a/python/mesa_pd/templates/mpi/notifications/ParticleCopyNotification.templ.h b/python/mesa_pd/templates/mpi/notifications/ParticleCopyNotification.templ.h index f9dbf1988e1cc7f3b690d7171e2181d1207d83f3..c2ea7d768bf5471c725bf4e2e4a53c3a1de5e093 100644 --- a/python/mesa_pd/templates/mpi/notifications/ParticleCopyNotification.templ.h +++ b/python/mesa_pd/templates/mpi/notifications/ParticleCopyNotification.templ.h @@ -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> diff --git a/src/mesa_pd/data/shape/BaseShape.h b/src/mesa_pd/data/shape/BaseShape.h index d00b0adeeaf2f87361380cdb89598710044b374b..20ab37d2e2fe296edcb3dcf1ac41b0412f57b99a 100644 --- a/src/mesa_pd/data/shape/BaseShape.h +++ b/src/mesa_pd/data/shape/BaseShape.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 diff --git a/src/mesa_pd/data/shape/Box.h b/src/mesa_pd/data/shape/Box.h index 95fcd9d0e027c8684255f42721e3c5287f53c19c..7cc5606785586fea4c1156a3bb796b5fc34a1456 100644 --- a/src/mesa_pd/data/shape/Box.h +++ b/src/mesa_pd/data/shape/Box.h @@ -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 diff --git a/src/mesa_pd/data/shape/CylindricalBoundary.h b/src/mesa_pd/data/shape/CylindricalBoundary.h index 86380cfa14e3aa672519e46665d0f4367a1be3c8..abe3bca759184a7f8f167ebdc2d5cffb67a7634c 100644 --- a/src/mesa_pd/data/shape/CylindricalBoundary.h +++ b/src/mesa_pd/data/shape/CylindricalBoundary.h @@ -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 diff --git a/src/mesa_pd/data/shape/Ellipsoid.h b/src/mesa_pd/data/shape/Ellipsoid.h index 9a07488e38dc00aafc933f4772a2976de6348dbd..8ff9411852f7f08de766a5409b31cc5e68a05d5d 100644 --- a/src/mesa_pd/data/shape/Ellipsoid.h +++ b/src/mesa_pd/data/shape/Ellipsoid.h @@ -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 diff --git a/src/mesa_pd/data/shape/HalfSpace.h b/src/mesa_pd/data/shape/HalfSpace.h index d24db7ad1b5fbd359aba714c8e485f035ad623b1..8691938fa11ac570d7a285121c26f343d59e4ca4 100644 --- a/src/mesa_pd/data/shape/HalfSpace.h +++ b/src/mesa_pd/data/shape/HalfSpace.h @@ -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 diff --git a/src/mesa_pd/data/shape/Sphere.h b/src/mesa_pd/data/shape/Sphere.h index 3c24aff0cc87635fcc7b5a7de70c9b957d9d07c7..5192c58b156ff061d9c0f5dd74c14f9d86542635 100644 --- a/src/mesa_pd/data/shape/Sphere.h +++ b/src/mesa_pd/data/shape/Sphere.h @@ -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 diff --git a/src/mesa_pd/mpi/ShapePackUnpack.h b/src/mesa_pd/mpi/ShapePackUnpack.h new file mode 100644 index 0000000000000000000000000000000000000000..0b5ab10e22738c55482d50d36e08a62367014aa3 --- /dev/null +++ b/src/mesa_pd/mpi/ShapePackUnpack.h @@ -0,0 +1,91 @@ +//====================================================================================================================== +// +// 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 diff --git a/src/mesa_pd/mpi/notifications/ParticleCopyNotification.h b/src/mesa_pd/mpi/notifications/ParticleCopyNotification.h index e58a0e750a122a40dee8579a59610ab34ae47907..5fdb79680bce3c05a36fc1f3db6b99fd13062939 100644 --- a/src/mesa_pd/mpi/notifications/ParticleCopyNotification.h +++ b/src/mesa_pd/mpi/notifications/ParticleCopyNotification.h @@ -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> diff --git a/tests/mesa_pd/CMakeLists.txt b/tests/mesa_pd/CMakeLists.txt index 5555ac9cfdae03f92baf272ed9c59564d6aed5d5..efb7340505f21de934d657d521b833b203fcc261 100644 --- a/tests/mesa_pd/CMakeLists.txt +++ b/tests/mesa_pd/CMakeLists.txt @@ -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) diff --git a/tests/mesa_pd/mpi/ShapePackUnpack.cpp b/tests/mesa_pd/mpi/ShapePackUnpack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a26177f4896fc66680279ea4e197f72a3025fe34 --- /dev/null +++ b/tests/mesa_pd/mpi/ShapePackUnpack.cpp @@ -0,0 +1,207 @@ +//====================================================================================================================== +// +// 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; + + std::shared_ptr<data::BaseShape> bs0 = std::make_shared<data::Ellipsoid>(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 ellipsoid"); + SendBuffer sb; + sb << bs0; + WALBERLA_LOG_INFO("unpacking ellipsoid"); + RecvBuffer rb(sb); + rb >> bs1; + + WALBERLA_LOG_INFO("checking ellipsoid"); + WALBERLA_CHECK_EQUAL(bs0->getShapeType(), data::Ellipsoid::SHAPE_TYPE); + WALBERLA_CHECK_EQUAL(bs1->getShapeType(), data::Ellipsoid::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 el0 = static_cast<data::Ellipsoid*> (bs0.get()); + auto el1 = static_cast<data::Ellipsoid*> (bs1.get()); + + WALBERLA_CHECK_IDENTICAL(el0->getSemiAxes(), el1->getSemiAxes()); +} + +void checkHalfSpace() +{ + using namespace walberla::mpi; + + std::shared_ptr<data::BaseShape> bs0 = std::make_shared<data::HalfSpace>(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 half space"); + SendBuffer sb; + sb << bs0; + WALBERLA_LOG_INFO("unpacking half space"); + RecvBuffer rb(sb); + rb >> bs1; + + WALBERLA_LOG_INFO("checking half space"); + WALBERLA_CHECK_EQUAL(bs0->getShapeType(), data::HalfSpace::SHAPE_TYPE); + WALBERLA_CHECK_EQUAL(bs1->getShapeType(), data::HalfSpace::SHAPE_TYPE); +// WALBERLA_CHECK_IDENTICAL(bs0->getMass(), bs1->getMass()); //INF + WALBERLA_CHECK_IDENTICAL(bs0->getInvMass(), bs1->getInvMass()); +// WALBERLA_CHECK_IDENTICAL(bs0->getInertiaBF(), bs1->getInertiaBF()); //INF + WALBERLA_CHECK_IDENTICAL(bs0->getInvInertiaBF(), bs1->getInvInertiaBF()); + + auto hs0 = static_cast<data::HalfSpace*> (bs0.get()); + auto hs1 = static_cast<data::HalfSpace*> (bs1.get()); + + WALBERLA_CHECK_IDENTICAL(hs0->getNormal(), hs1->getNormal()); +} + +void checkSphere() +{ + using namespace walberla::mpi; + + std::shared_ptr<data::BaseShape> bs0 = std::make_shared<data::Sphere>(real_t(2.53)); + bs0->updateMassAndInertia(real_t(123)); + std::shared_ptr<data::BaseShape> bs1 = nullptr; + + WALBERLA_LOG_INFO("packing sphere"); + SendBuffer sb; + sb << bs0; + WALBERLA_LOG_INFO("unpacking sphere"); + RecvBuffer rb(sb); + rb >> bs1; + + WALBERLA_LOG_INFO("checking sphere"); + WALBERLA_CHECK_EQUAL(bs0->getShapeType(), data::Sphere::SHAPE_TYPE); + WALBERLA_CHECK_EQUAL(bs1->getShapeType(), data::Sphere::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 sp0 = static_cast<data::Sphere*> (bs0.get()); + auto sp1 = static_cast<data::Sphere*> (bs1.get()); + + WALBERLA_CHECK_IDENTICAL(sp0->getRadius(), sp1->getRadius()); +} + +int main( int argc, char ** argv ) +{ + Environment env(argc, argv); + WALBERLA_UNUSED(env); + mpi::MPIManager::instance()->useWorldComm(); + + checkBox(); + checkCylindricalBoundary(); + checkEllipsoid(); + checkHalfSpace(); + checkSphere(); + + return EXIT_SUCCESS; +} + +} //namespace walberla + +int main( int argc, char ** argv ) +{ + return walberla::main(argc, argv); +}