Commit 5e29f153 authored by Christoph Schwarzmeier's avatar Christoph Schwarzmeier
Browse files

Merge branch 'mr_mesapd_shape_integration_fix' into 'master'

Fix of integration of angular velocity of non-spherical particles

See merge request walberla/walberla!527
parents 27e2bc06 b67091ed
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
// //
//====================================================================================================================== //======================================================================================================================
#include "Accessor.h"
#include "check.h" #include "check.h"
#include "Contact.h" #include "Contact.h"
#include "CreateParticles.h" #include "CreateParticles.h"
...@@ -32,7 +31,7 @@ ...@@ -32,7 +31,7 @@
#include <mesa_pd/collision_detection/AnalyticContactDetection.h> #include <mesa_pd/collision_detection/AnalyticContactDetection.h>
#include <mesa_pd/data/LinkedCells.h> #include <mesa_pd/data/LinkedCells.h>
#include <mesa_pd/data/ParticleAccessor.h> #include <mesa_pd/data/ParticleAccessorWithShape.h>
#include <mesa_pd/data/ParticleStorage.h> #include <mesa_pd/data/ParticleStorage.h>
#include <mesa_pd/data/ShapeStorage.h> #include <mesa_pd/data/ShapeStorage.h>
#include <mesa_pd/domain/BlockForestDomain.h> #include <mesa_pd/domain/BlockForestDomain.h>
...@@ -90,7 +89,7 @@ public: ...@@ -90,7 +89,7 @@ public:
} }
inline inline
void operator()(const size_t idx1, const size_t idx2, ParticleAccessorWithShape& ac) void operator()(const size_t idx1, const size_t idx2, data::ParticleAccessorWithShape& ac)
{ {
++contactsChecked_; ++contactsChecked_;
...@@ -194,7 +193,7 @@ int main( int argc, char ** argv ) ...@@ -194,7 +193,7 @@ int main( int argc, char ** argv )
//init data structures //init data structures
auto ps = std::make_shared<data::ParticleStorage>(100); auto ps = std::make_shared<data::ParticleStorage>(100);
auto ss = std::make_shared<data::ShapeStorage>(); auto ss = std::make_shared<data::ShapeStorage>();
ParticleAccessorWithShape accessor(ps, ss); data::ParticleAccessorWithShape accessor(ps, ss);
data::LinkedCells lc(localDomain.getExtended(params.spacing), params.spacing ); data::LinkedCells lc(localDomain.getExtended(params.spacing), params.spacing );
auto smallSphere = ss->create<data::Sphere>( params.radius ); auto smallSphere = ss->create<data::Sphere>( params.radius );
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
// //
//====================================================================================================================== //======================================================================================================================
#include "Accessor.h"
#include "check.h" #include "check.h"
#include "Contact.h" #include "Contact.h"
#include "CreateParticles.h" #include "CreateParticles.h"
...@@ -32,7 +31,7 @@ ...@@ -32,7 +31,7 @@
#include <mesa_pd/collision_detection/AnalyticContactDetection.h> #include <mesa_pd/collision_detection/AnalyticContactDetection.h>
#include <mesa_pd/data/LinkedCells.h> #include <mesa_pd/data/LinkedCells.h>
#include <mesa_pd/data/ParticleAccessor.h> #include <mesa_pd/data/ParticleAccessorWithShape.h>
#include <mesa_pd/data/ParticleStorage.h> #include <mesa_pd/data/ParticleStorage.h>
#include <mesa_pd/data/ShapeStorage.h> #include <mesa_pd/data/ShapeStorage.h>
#include <mesa_pd/domain/BlockForestDomain.h> #include <mesa_pd/domain/BlockForestDomain.h>
...@@ -209,7 +208,7 @@ int main( int argc, char ** argv ) ...@@ -209,7 +208,7 @@ int main( int argc, char ** argv )
//init data structures //init data structures
auto ss = std::make_shared<data::ShapeStorage>(); auto ss = std::make_shared<data::ShapeStorage>();
auto ps = std::make_shared<data::ParticleStorage>(100); auto ps = std::make_shared<data::ParticleStorage>(100);
ParticleAccessorWithShape accessor(ps, ss); data::ParticleAccessorWithShape accessor(ps, ss);
data::LinkedCells lc(localDomain.getExtended(params.spacing), params.spacing ); data::LinkedCells lc(localDomain.getExtended(params.spacing), params.spacing );
auto smallSphere = ss->create<data::Sphere>( params.radius ); auto smallSphere = ss->create<data::Sphere>( params.radius );
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
// //
//====================================================================================================================== //======================================================================================================================
#include "Accessor.h"
#include "check.h" #include "check.h"
#include "Contact.h" #include "Contact.h"
#include "CreateParticles.h" #include "CreateParticles.h"
...@@ -32,7 +31,7 @@ ...@@ -32,7 +31,7 @@
#include <mesa_pd/collision_detection/AnalyticContactDetection.h> #include <mesa_pd/collision_detection/AnalyticContactDetection.h>
#include <mesa_pd/data/LinkedCells.h> #include <mesa_pd/data/LinkedCells.h>
#include <mesa_pd/data/ParticleAccessor.h> #include <mesa_pd/data/ParticleAccessorWithShape.h>
#include <mesa_pd/data/ParticleStorage.h> #include <mesa_pd/data/ParticleStorage.h>
#include <mesa_pd/data/ShapeStorage.h> #include <mesa_pd/data/ShapeStorage.h>
#include <mesa_pd/data/SparseLinkedCells.h> #include <mesa_pd/data/SparseLinkedCells.h>
...@@ -198,7 +197,7 @@ int main( int argc, char ** argv ) ...@@ -198,7 +197,7 @@ int main( int argc, char ** argv )
//init data structures //init data structures
auto ps = std::make_shared<data::ParticleStorage>(100); auto ps = std::make_shared<data::ParticleStorage>(100);
auto ss = std::make_shared<data::ShapeStorage>(); auto ss = std::make_shared<data::ShapeStorage>();
ParticleAccessorWithShape accessor(ps, ss); data::ParticleAccessorWithShape accessor(ps, ss);
auto lc = std::make_shared<data::LinkedCells>(domain->getUnionOfLocalAABBs().getExtended(params.spacing), params.spacing ); auto lc = std::make_shared<data::LinkedCells>(domain->getUnionOfLocalAABBs().getExtended(params.spacing), params.spacing );
forest->addBlockData(domain::createBlockForestDataHandling(ps), "Storage"); forest->addBlockData(domain::createBlockForestDataHandling(ps), "Storage");
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
// //
//====================================================================================================================== //======================================================================================================================
#include "Accessor.h"
#include "check.h" #include "check.h"
#include "Contact.h" #include "Contact.h"
#include "CreateParticles.h" #include "CreateParticles.h"
...@@ -32,7 +31,7 @@ ...@@ -32,7 +31,7 @@
#include <mesa_pd/collision_detection/AnalyticContactDetection.h> #include <mesa_pd/collision_detection/AnalyticContactDetection.h>
#include <mesa_pd/data/SparseLinkedCells.h> #include <mesa_pd/data/SparseLinkedCells.h>
#include <mesa_pd/data/ParticleAccessor.h> #include <mesa_pd/data/ParticleAccessorWithShape.h>
#include <mesa_pd/data/ParticleStorage.h> #include <mesa_pd/data/ParticleStorage.h>
#include <mesa_pd/data/ShapeStorage.h> #include <mesa_pd/data/ShapeStorage.h>
#include <mesa_pd/data/STLOverloads.h> #include <mesa_pd/data/STLOverloads.h>
...@@ -236,7 +235,7 @@ int main( int argc, char ** argv ) ...@@ -236,7 +235,7 @@ int main( int argc, char ** argv )
//init data structures //init data structures
auto ps = std::make_shared<data::ParticleStorage>(100); auto ps = std::make_shared<data::ParticleStorage>(100);
auto ss = std::make_shared<data::ShapeStorage>(); auto ss = std::make_shared<data::ShapeStorage>();
ParticleAccessorWithShape accessor(ps, ss); data::ParticleAccessorWithShape accessor(ps, ss);
auto lc = std::make_shared<data::SparseLinkedCells>(domain->getUnionOfLocalAABBs().getExtended(params.spacing), params.spacing ); auto lc = std::make_shared<data::SparseLinkedCells>(domain->getUnionOfLocalAABBs().getExtended(params.spacing), params.spacing );
forest->addBlockData(domain::createBlockForestDataHandling(ps), "Storage"); forest->addBlockData(domain::createBlockForestDataHandling(ps), "Storage");
......
...@@ -43,15 +43,15 @@ public: ...@@ -43,15 +43,15 @@ public:
const auto &getInvMass(const size_t /*p_idx*/) const const auto &getInvMass(const size_t /*p_idx*/) const
{ return invMass_; } { return invMass_; }
void setInvInertiaBF(const size_t /*p_idx*/, const Mat3 &val) const auto &getInvInertiaBF(const size_t /*p_idx*/) const // dummy
{ invInertiaBF_ = val; } { return dummyI_; }
const auto &getInvInertiaBF(const size_t /*p_idx*/) const const auto &getInertiaBF(const size_t /*p_idx*/) const // dummy
{ return invInertiaBF_; } { return dummyI_; }
private: private:
real_t invMass_; real_t invMass_;
Mat3 invInertiaBF_; Mat3 dummyI_{0_r};
}; };
struct Oscillator struct Oscillator
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#pragma once #pragma once
#include "mesa_pd/data/ContactAccessor.h"
#include "mesa_pd/data/ParticleStorage.h" #include "mesa_pd/data/ParticleStorage.h"
#include "Utility.h" #include "Utility.h"
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "mesa_pd/data/ContactStorage.h" #include "mesa_pd/data/ContactStorage.h"
#include "mesa_pd/data/ContactAccessor.h" #include "mesa_pd/data/ContactAccessor.h"
#include "mesa_pd/data/ParticleAccessorWithBaseShape.h"
#include "mesa_pd/data/ParticleStorage.h" #include "mesa_pd/data/ParticleStorage.h"
#include "mesa_pd/data/HashGrids.h" #include "mesa_pd/data/HashGrids.h"
...@@ -418,7 +419,7 @@ int main(int argc, char **argv) { ...@@ -418,7 +419,7 @@ int main(int argc, char **argv) {
/// MESAPD Data /// MESAPD Data
auto particleStorage = std::make_shared<data::ParticleStorage>(1); auto particleStorage = std::make_shared<data::ParticleStorage>(1);
auto contactStorage = std::make_shared<data::ContactStorage>(1); auto contactStorage = std::make_shared<data::ContactStorage>(1);
ParticleAccessorWithShape particleAccessor(particleStorage); data::ParticleAccessorWithBaseShape particleAccessor(particleStorage);
data::ContactAccessor contactAccessor(contactStorage); data::ContactAccessor contactAccessor(contactStorage);
// configure shape creation // configure shape creation
...@@ -626,7 +627,7 @@ int main(int argc, char **argv) { ...@@ -626,7 +627,7 @@ int main(int argc, char **argv) {
math::DistributedSample diameterSample; math::DistributedSample diameterSample;
particleStorage->forEachParticle(useOpenMP, kernel::SelectLocal(), particleAccessor, particleStorage->forEachParticle(useOpenMP, kernel::SelectLocal(), particleAccessor,
[&diameterSample](const size_t idx, ParticleAccessorWithShape& ac){diameterSample.insert(real_c(2)*ac.getInteractionRadius(idx));}, particleAccessor); [&diameterSample](const size_t idx, data::ParticleAccessorWithBaseShape& ac){diameterSample.insert(real_c(2)*ac.getInteractionRadius(idx));}, particleAccessor);
diameterSample.mpiAllGather(); diameterSample.mpiAllGather();
WALBERLA_LOG_INFO_ON_ROOT("Statistics of initially created particles' interaction diameters: " << diameterSample.format()); WALBERLA_LOG_INFO_ON_ROOT("Statistics of initially created particles' interaction diameters: " << diameterSample.format());
...@@ -713,7 +714,7 @@ int main(int argc, char **argv) { ...@@ -713,7 +714,7 @@ int main(int argc, char **argv) {
meshParticleVTK.addFaceOutput< data::SelectParticleLinearVelocity >("LinearVelocity"); meshParticleVTK.addFaceOutput< data::SelectParticleLinearVelocity >("LinearVelocity");
meshParticleVTK.addVertexOutput< data::SelectParticlePosition >("Position"); meshParticleVTK.addVertexOutput< data::SelectParticlePosition >("Position");
meshParticleVTK.addVertexOutput< data::SelectParticleNumContacts >("numContacts"); meshParticleVTK.addVertexOutput< data::SelectParticleNumContacts >("numContacts");
auto surfaceVelDataSource = make_shared<mesa_pd::SurfaceVelocityVertexDataSource< mesh::PolyMesh, ParticleAccessorWithShape > >("SurfaceVelocity", particleAccessor); auto surfaceVelDataSource = make_shared<mesa_pd::SurfaceVelocityVertexDataSource< mesh::PolyMesh, data::ParticleAccessorWithBaseShape > >("SurfaceVelocity", particleAccessor);
meshParticleVTK.setParticleSelector(vtkParticleSelector); meshParticleVTK.setParticleSelector(vtkParticleSelector);
meshParticleVTK.addVertexDataSource(surfaceVelDataSource); meshParticleVTK.addVertexDataSource(surfaceVelDataSource);
...@@ -850,7 +851,7 @@ int main(int argc, char **argv) { ...@@ -850,7 +851,7 @@ int main(int argc, char **argv) {
timing.start("Contact detection"); timing.start("Contact detection");
hashGrids.forEachParticlePairHalf(useOpenMP, kernel::ExcludeInfiniteInfinite(), particleAccessor, hashGrids.forEachParticlePairHalf(useOpenMP, kernel::ExcludeInfiniteInfinite(), particleAccessor,
[domain, contactStorage](size_t idx1, size_t idx2, ParticleAccessorWithShape &ac){ [domain, contactStorage](size_t idx1, size_t idx2, data::ParticleAccessorWithBaseShape &ac){
kernel::DoubleCast double_cast; kernel::DoubleCast double_cast;
mpi::ContactFilter contact_filter; mpi::ContactFilter contact_filter;
collision_detection::GeneralContactDetection contactDetection; collision_detection::GeneralContactDetection contactDetection;
...@@ -890,7 +891,7 @@ int main(int argc, char **argv) { ...@@ -890,7 +891,7 @@ int main(int argc, char **argv) {
} else } else
{ {
linkedCells.forEachParticlePairHalf(useOpenMP, kernel::ExcludeInfiniteInfinite(), particleAccessor, linkedCells.forEachParticlePairHalf(useOpenMP, kernel::ExcludeInfiniteInfinite(), particleAccessor,
[domain, contactStorage](size_t idx1, size_t idx2, ParticleAccessorWithShape &ac){ [domain, contactStorage](size_t idx1, size_t idx2, data::ParticleAccessorWithBaseShape &ac){
collision_detection::GeneralContactDetection contactDetection; collision_detection::GeneralContactDetection contactDetection;
//Attention: does not use contact threshold in general case (GJK) //Attention: does not use contact threshold in general case (GJK)
...@@ -926,9 +927,9 @@ int main(int argc, char **argv) { ...@@ -926,9 +927,9 @@ int main(int argc, char **argv) {
timing.start("Contact eval"); timing.start("Contact eval");
particleStorage->forEachParticle(useOpenMP, kernel::SelectAll(), particleAccessor, particleStorage->forEachParticle(useOpenMP, kernel::SelectAll(), particleAccessor,
[](size_t p_idx, ParticleAccessorWithShape& ac){ac.setNumContacts(p_idx,0);}, particleAccessor); [](size_t p_idx, data::ParticleAccessorWithBaseShape& ac){ac.setNumContacts(p_idx,0);}, particleAccessor);
contactStorage->forEachContact(useOpenMP, kernel::SelectAll(), contactAccessor, contactStorage->forEachContact(useOpenMP, kernel::SelectAll(), contactAccessor,
[](size_t c, data::ContactAccessor &ca, ParticleAccessorWithShape &pa) { [](size_t c, data::ContactAccessor &ca, data::ParticleAccessorWithBaseShape &pa) {
auto idx1 = ca.getId1(c); auto idx1 = ca.getId1(c);
auto idx2 = ca.getId2(c); auto idx2 = ca.getId2(c);
pa.getNumContactsRef(idx1)++; pa.getNumContactsRef(idx1)++;
...@@ -996,7 +997,7 @@ int main(int argc, char **argv) { ...@@ -996,7 +997,7 @@ int main(int argc, char **argv) {
timing.start("DEM"); timing.start("DEM");
timing.start("Collision"); timing.start("Collision");
contactStorage->forEachContact(useOpenMP, kernel::SelectAll(), contactAccessor, contactStorage->forEachContact(useOpenMP, kernel::SelectAll(), contactAccessor,
[&dem_collision, coefficientOfRestitution, dem_collisionTime, dem_kappa, dt](size_t c, data::ContactAccessor &ca, ParticleAccessorWithShape &pa){ [&dem_collision, coefficientOfRestitution, dem_collisionTime, dem_kappa, dt](size_t c, data::ContactAccessor &ca, data::ParticleAccessorWithBaseShape &pa){
auto idx1 = ca.getId1(c); auto idx1 = ca.getId1(c);
auto idx2 = ca.getId2(c); auto idx2 = ca.getId2(c);
auto meff = real_t(1) / (pa.getInvMass(idx1) + pa.getInvMass(idx2)); auto meff = real_t(1) / (pa.getInvMass(idx1) + pa.getInvMass(idx2));
...@@ -1125,7 +1126,7 @@ int main(int argc, char **argv) { ...@@ -1125,7 +1126,7 @@ int main(int argc, char **argv) {
// apply damping // apply damping
particleStorage->forEachParticle(useOpenMP, kernel::SelectAll(), particleAccessor, particleStorage->forEachParticle(useOpenMP, kernel::SelectAll(), particleAccessor,
[velocityDampingFactor](size_t idx, ParticleAccessorWithShape &ac){ [velocityDampingFactor](size_t idx, data::ParticleAccessorWithBaseShape &ac){
ac.getLinearVelocityRef(idx) *= velocityDampingFactor; ac.getLinearVelocityRef(idx) *= velocityDampingFactor;
ac.getAngularVelocityRef(idx) *= velocityDampingFactor;}, ac.getAngularVelocityRef(idx) *= velocityDampingFactor;},
particleAccessor); particleAccessor);
......
...@@ -20,7 +20,11 @@ ...@@ -20,7 +20,11 @@
#pragma once #pragma once
#include "core/mpi/MPITextFile.h"
#include "mesa_pd/data/ParticleStorage.h" #include "mesa_pd/data/ParticleStorage.h"
#include "mesa_pd/data/shape/HalfSpace.h"
#include "mesa_pd/data/shape/CylindricalBoundary.h"
#include <iterator> #include <iterator>
#include <algorithm> #include <algorithm>
...@@ -29,22 +33,6 @@ ...@@ -29,22 +33,6 @@
namespace walberla { namespace walberla {
namespace mesa_pd { namespace mesa_pd {
class ParticleAccessorWithShape : public data::ParticleAccessor
{
public:
ParticleAccessorWithShape(std::shared_ptr<data::ParticleStorage>& particleStorage)
: ParticleAccessor(particleStorage)
{}
walberla::real_t const & getInvMass(const size_t p_idx) const {return ps_->getBaseShapeRef(p_idx)->getInvMass();}
Mat3 const & getInvInertiaBF(const size_t p_idx) const {return ps_->getBaseShapeRef(p_idx)->getInvInertiaBF();}
Mat3 const & getInertiaBF(const size_t p_idx) const {return ps_->getBaseShapeRef(p_idx)->getInertiaBF();}
data::BaseShape* getShape(const size_t p_idx) const {return ps_->getBaseShape(p_idx).get();}
};
template< typename T> template< typename T>
std::vector<T> parseStringToVector(std::string inputStr) std::vector<T> parseStringToVector(std::string inputStr)
{ {
......
...@@ -20,6 +20,7 @@ class ExplicitEuler: ...@@ -20,6 +20,7 @@ class ExplicitEuler:
self.context['interface'].append(create_access("rotation", "walberla::mesa_pd::Rot3", access="gs")) self.context['interface'].append(create_access("rotation", "walberla::mesa_pd::Rot3", access="gs"))
self.context['interface'].append(create_access("angularVelocity", "walberla::mesa_pd::Vec3", access="gs")) self.context['interface'].append(create_access("angularVelocity", "walberla::mesa_pd::Vec3", access="gs"))
self.context['interface'].append(create_access("invInertiaBF", "walberla::mesa_pd::Mat3", access="g")) self.context['interface'].append(create_access("invInertiaBF", "walberla::mesa_pd::Mat3", access="g"))
self.context['interface'].append(create_access("inertiaBF", "walberla::mesa_pd::Mat3", access="g"))
self.context['interface'].append(create_access("torque", "walberla::mesa_pd::Vec3", access="gs")) self.context['interface'].append(create_access("torque", "walberla::mesa_pd::Vec3", access="gs"))
def generate(self, module): def generate(self, module):
......
...@@ -20,6 +20,7 @@ class SemiImplicitEuler: ...@@ -20,6 +20,7 @@ class SemiImplicitEuler:
self.context['interface'].append(create_access("rotation", "walberla::mesa_pd::Rot3", access="gs")) self.context['interface'].append(create_access("rotation", "walberla::mesa_pd::Rot3", access="gs"))
self.context['interface'].append(create_access("angularVelocity", "walberla::mesa_pd::Vec3", access="gs")) self.context['interface'].append(create_access("angularVelocity", "walberla::mesa_pd::Vec3", access="gs"))
self.context['interface'].append(create_access("invInertiaBF", "walberla::mesa_pd::Mat3", access="g")) self.context['interface'].append(create_access("invInertiaBF", "walberla::mesa_pd::Mat3", access="g"))
self.context['interface'].append(create_access("inertiaBF", "walberla::mesa_pd::Mat3", access="g"))
self.context['interface'].append(create_access("torque", "walberla::mesa_pd::Vec3", access="gs")) self.context['interface'].append(create_access("torque", "walberla::mesa_pd::Vec3", access="gs"))
def generate(self, module): def generate(self, module):
......
...@@ -17,6 +17,7 @@ class VelocityVerlet: ...@@ -17,6 +17,7 @@ class VelocityVerlet:
self.context['interface'].append(create_access("rotation", "walberla::mesa_pd::Rot3", access="gs")) self.context['interface'].append(create_access("rotation", "walberla::mesa_pd::Rot3", access="gs"))
self.context['interface'].append(create_access("angularVelocity", "walberla::mesa_pd::Vec3", access="gs")) self.context['interface'].append(create_access("angularVelocity", "walberla::mesa_pd::Vec3", access="gs"))
self.context['interface'].append(create_access("invInertiaBF", "walberla::mesa_pd::Mat3", access="g")) self.context['interface'].append(create_access("invInertiaBF", "walberla::mesa_pd::Mat3", access="g"))
self.context['interface'].append(create_access("inertiaBF", "walberla::mesa_pd::Mat3", access="g"))
self.context['interface'].append(create_access("torque", "walberla::mesa_pd::Vec3", access="gs")) self.context['interface'].append(create_access("torque", "walberla::mesa_pd::Vec3", access="gs"))
self.context['interface'].append(create_access("oldTorque", "walberla::mesa_pd::Vec3", access="gs")) self.context['interface'].append(create_access("oldTorque", "walberla::mesa_pd::Vec3", access="gs"))
......
...@@ -67,6 +67,21 @@ inline Vec3 transformVectorFromBFtoWF(const size_t p_idx, Accessor& ac, const Ve ...@@ -67,6 +67,21 @@ inline Vec3 transformVectorFromBFtoWF(const size_t p_idx, Accessor& ac, const Ve
return ac.getRotation(p_idx).getMatrix() * vectorBF; return ac.getRotation(p_idx).getMatrix() * vectorBF;
} }
/**
* Transform (inverse) particle's moment of inertia from body frame coordinates (as stored by shape) to world frame.
*/
template <typename Accessor>
inline Mat3 getInvInertia(const size_t p_idx, Accessor& ac)
{
return math::transformMatrixRART(ac.getRotation(p_idx).getMatrix(), ac.getInvInertiaBF(p_idx));
}
template <typename Accessor>
inline Mat3 getInertia(const size_t p_idx, Accessor& ac)
{
return math::transformMatrixRART(ac.getRotation(p_idx).getMatrix(), ac.getInertiaBF(p_idx));
}
/** /**
* Force is applied at the center of mass. * Force is applied at the center of mass.
*/ */
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
#include <mesa_pd/data/DataTypes.h> #include <mesa_pd/data/DataTypes.h>
#include <mesa_pd/data/IAccessor.h> #include <mesa_pd/data/IAccessor.h>
{%- if bIntegrateRotation %}
#include <mesa_pd/common/ParticleFunctions.h>
{%- endif %}
namespace walberla { namespace walberla {
namespace mesa_pd { namespace mesa_pd {
...@@ -87,8 +90,12 @@ inline void ExplicitEuler::operator()(const size_t idx, ...@@ -87,8 +90,12 @@ inline void ExplicitEuler::operator()(const size_t idx,
ac.getLinearVelocity(idx)); ac.getLinearVelocity(idx));
{%- if bIntegrateRotation %} {%- if bIntegrateRotation %}
const Vec3 wdot = math::transformMatrixRART(ac.getRotation(idx).getMatrix(), // computation done in body frame: d(omega)/ dt = J^-1 ((J*omega) x omega + T), update in world frame
ac.getInvInertiaBF(idx)) * ac.getTorque(idx); // see Wachs, 2019, doi:10.1007/s00707-019-02389-9, Eq. 27
const auto omegaBF = transformVectorFromWFtoBF(idx, ac, ac.getAngularVelocity(idx));
const auto torqueBF = transformVectorFromWFtoBF(idx, ac, ac.getTorque(idx));
const Vec3 wdotBF = ac.getInvInertiaBF(idx) * ( ( ac.getInertiaBF(idx) * omegaBF ) % omegaBF + torqueBF );
const Vec3 wdot = transformVectorFromBFtoWF(idx, ac, wdotBF);
// Calculating the rotation angle // Calculating the rotation angle
const Vec3 phi( 0.5_r * wdot * dt_ * dt_ + const Vec3 phi( 0.5_r * wdot * dt_ * dt_ +
......
...@@ -87,7 +87,8 @@ inline void InitParticlesForHCSITS::operator()(size_t j, Accessor& ac, real_t dt ...@@ -87,7 +87,8 @@ inline void InitParticlesForHCSITS::operator()(size_t j, Accessor& ac, real_t dt
initializeVelocityCorrections( ac, j, ac.getDvRef(j), ac.getDwRef(j), dt ); // use applied external forces to calculate starting velocity initializeVelocityCorrections( ac, j, ac.getDvRef(j), ac.getDwRef(j), dt ); // use applied external forces to calculate starting velocity
if(!isSet(particle_flags, FIXED)){ // Update velocities with global acceleration and angular velocity with euler eqn if(!isSet(particle_flags, FIXED)){ // Update velocities with global acceleration and angular velocity with euler eqn
ac.getLinearVelocityRef(j) = ac.getLinearVelocity(j) + getGlobalAcceleration() * dt; ac.getLinearVelocityRef(j) = ac.getLinearVelocity(j) + getGlobalAcceleration() * dt;
ac.getAngularVelocityRef(j) = ac.getAngularVelocity(j) + dt * ( ac.getInvInertiaBF(j) * ( ( ac.getInertiaBF(j) * ac.getAngularVelocity(j) ) % ac.getAngularVelocity(j) ) ); const auto omegaBF = transformVectorFromWFtoBF(j, ac, ac.getAngularVelocity(j));
ac.getAngularVelocityRef(j) = ac.getAngularVelocity(j) + dt * transformVectorFromBFtoWF(j, ac, ( ac.getInvInertiaBF(j) * ( ( ac.getInertiaBF(j) * omegaBF ) % omegaBF ) ) );
} }
} }
} }
...@@ -110,7 +111,7 @@ template <typename Accessor> ...@@ -110,7 +111,7 @@ template <typename Accessor>
inline void InitParticlesForHCSITS::initializeVelocityCorrections(Accessor& ac, size_t body, Vec3& dv, Vec3& dw, real_t dt ) const inline void InitParticlesForHCSITS::initializeVelocityCorrections(Accessor& ac, size_t body, Vec3& dv, Vec3& dw, real_t dt ) const
{ {
dv = ( ac.getInvMass(body) * dt ) * ac.getForce(body); dv = ( ac.getInvMass(body) * dt ) * ac.getForce(body);
dw = dt * ( ac.getInvInertiaBF(body) * ac.getTorque(body) ); dw = dt * ( getInvInertia(body, ac) * ac.getTorque(body) );
ac.getForceRef(body) = Vec3(); ac.getForceRef(body) = Vec3();
ac.getTorqueRef(body) = Vec3(); ac.getTorqueRef(body) = Vec3();
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
#include <mesa_pd/data/DataTypes.h> #include <mesa_pd/data/DataTypes.h>
#include <mesa_pd/data/IAccessor.h> #include <mesa_pd/data/IAccessor.h>
{%- if bIntegrateRotation %}
#include <mesa_pd/common/ParticleFunctions.h>
{%- endif %}
namespace walberla { namespace walberla {
namespace mesa_pd { namespace mesa_pd {
...@@ -81,8 +84,12 @@ inline void SemiImplicitEuler::operator()(const size_t idx, ...@@ -81,8 +84,12 @@ inline void SemiImplicitEuler::operator()(const size_t idx,
ac.getPosition(idx)); ac.getPosition(idx));
{%- if bIntegrateRotation %} {%- if bIntegrateRotation %}
const Vec3 wdot = math::transformMatrixRART(ac.getRotation(idx).getMatrix(), // computation done in body frame: d(omega)/ dt = J^-1 ((J*omega) x omega + T), update in world frame
ac.getInvInertiaBF(idx)) * ac.getTorque(idx); // see Wachs, 2019, doi:10.1007/s00707-019-02389-9, Eq. 27
const auto omegaBF = transformVectorFromWFtoBF(idx, ac, ac.getAngularVelocity(idx));
const auto torqueBF = transformVectorFromWFtoBF(idx, ac, ac.getTorque(idx));
const Vec3 wdotBF = ac.getInvInertiaBF(idx) * ( ( ac.getInertiaBF(idx) * omegaBF ) % omegaBF + torqueBF );
const Vec3 wdot = transformVectorFromBFtoWF(idx, ac, wdotBF);
ac.setAngularVelocity(idx, wdot * dt_ + ac.setAngularVelocity(idx, wdot * dt_ +
ac.getAngularVelocity(idx)); ac.getAngularVelocity(idx));
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
#include <mesa_pd/data/DataTypes.h> #include <mesa_pd/data/DataTypes.h>
#include <mesa_pd/data/IAccessor.h> #include <mesa_pd/data/IAccessor.h>
{%- if bIntegrateRotation %}
#include <mesa_pd/common/ParticleFunctions.h>
{%- endif %}
namespace walberla { namespace walberla {
namespace mesa_pd { namespace mesa_pd {
...@@ -95,8 +98,14 @@ inline void VelocityVerletPreForceUpdate::operator()(const size_t p_idx, Accesso ...@@ -95,8 +98,14 @@ inline void VelocityVerletPreForceUpdate::operator()(const size_t p_idx, Accesso
real_t(0.5) * ac.getInvMass(p_idx) * ac.getOldForce(p_idx) * dt_ * dt_);