From 3bd71973ed4eb974dd70674cafdd305c60cde81f Mon Sep 17 00:00:00 2001
From: Sebastian Eibl <sebastian.eibl@fau.de>
Date: Mon, 27 Jan 2020 15:58:36 +0100
Subject: [PATCH] [BUGFIX] data handling now also copies ON_OWNERSHIP_CHANGE
 properties

---
 python/mesa_pd/data/ParticleStorage.py        |   2 +-
 .../ParticleCopyNotification.templ.h          |  12 +-
 .../domain/BlockForestDataHandling.cpp        |  10 +-
 .../mpi/notifications/NotificationType.h      |   1 +
 .../notifications/ParticleCopyNotification.h  | 163 ++++++++++++++++++
 5 files changed, 176 insertions(+), 12 deletions(-)
 create mode 100644 src/mesa_pd/mpi/notifications/ParticleCopyNotification.h

diff --git a/python/mesa_pd/data/ParticleStorage.py b/python/mesa_pd/data/ParticleStorage.py
index d6bca7942..7f9813a06 100644
--- a/python/mesa_pd/data/ParticleStorage.py
+++ b/python/mesa_pd/data/ParticleStorage.py
@@ -39,7 +39,7 @@ class ParticleStorage(Container):
       generateFile(path, 'mpi/notifications/ForceTorqueNotification.templ.h', context)
       generateFile(path, 'mpi/notifications/HeatFluxNotification.templ.h', context)
       generateFile(path, 'mpi/notifications/ParseMessage.templ.h', context)
-      #generateFile(path, 'mpi/notifications/ParticleCopyNotification.templ.h', context)
+      generateFile(path, 'mpi/notifications/ParticleCopyNotification.templ.h', context)
       generateFile(path, 'mpi/notifications/ParticleGhostCopyNotification.templ.h', context)
       generateFile(path, 'mpi/notifications/NewGhostParticleNotification.templ.h', context)
       generateFile(path, 'mpi/notifications/ParticleMigrationNotification.templ.h', context)
diff --git a/python/mesa_pd/templates/mpi/notifications/ParticleCopyNotification.templ.h b/python/mesa_pd/templates/mpi/notifications/ParticleCopyNotification.templ.h
index caea40288..505dfbccc 100644
--- a/python/mesa_pd/templates/mpi/notifications/ParticleCopyNotification.templ.h
+++ b/python/mesa_pd/templates/mpi/notifications/ParticleCopyNotification.templ.h
@@ -39,9 +39,9 @@ namespace walberla {
 namespace mesa_pd {
 
 /**
- * A complete particle copy for a new ghost particle.
+ * A complete particle copy.
  *
- * Copies all properties marked ON_GHOST_CREATION or ALWAYS.
+ * Copies all properties that are not marked NEVER.
  */
 class ParticleCopyNotification
 {
@@ -49,7 +49,7 @@ public:
    struct Parameters
    {
       {%- for prop in properties %}
-      {%- if prop.syncMode in ["ON_GHOST_CREATION", "ALWAYS"] %}
+      {%- if not prop.syncMode == "NEVER" %}
       {{prop.type}} {{prop.name}} {{'{'}}{{prop.defValue}}{{'}'}};
       {%- endif %}
       {%- endfor %}
@@ -65,7 +65,7 @@ inline data::ParticleStorage::iterator createNewParticle(data::ParticleStorage&
 
    auto pIt = ps.create(data.uid);
    {%- for prop in properties %}
-   {%- if prop.syncMode in ["ON_GHOST_CREATION", "ALWAYS"] %}
+   {%- if not prop.syncMode == "NEVER" %}
    pIt->set{{prop.name | capFirst}}(data.{{prop.name}});
    {%- endif %}
    {%- endfor %}
@@ -96,7 +96,7 @@ mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, cons
 {
    buf.addDebugMarker( "cn" );
    {%- for prop in properties %}
-   {%- if prop.syncMode in ["ON_GHOST_CREATION", "ALWAYS"] %}
+   {%- if not prop.syncMode == "NEVER" %}
    buf << obj.particle_.get{{prop.name | capFirst}}();
    {%- endif %}
    {%- endfor %}
@@ -108,7 +108,7 @@ mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, mesa_pd:
 {
    buf.readDebugMarker( "cn" );
    {%- for prop in properties %}
-   {%- if prop.syncMode in ["ON_GHOST_CREATION", "ALWAYS"] %}
+   {%- if not prop.syncMode == "NEVER" %}
    buf >> objparam.{{prop.name}};
    {%- endif %}
    {%- endfor %}
diff --git a/src/mesa_pd/domain/BlockForestDataHandling.cpp b/src/mesa_pd/domain/BlockForestDataHandling.cpp
index d60dda116..1a75c1384 100644
--- a/src/mesa_pd/domain/BlockForestDataHandling.cpp
+++ b/src/mesa_pd/domain/BlockForestDataHandling.cpp
@@ -23,7 +23,7 @@
 #include <mesa_pd/data/DataTypes.h>
 #include <mesa_pd/data/ParticleStorage.h>
 
-#include <mesa_pd/mpi/notifications/ParticleGhostCopyNotification.h>
+#include <mesa_pd/mpi/notifications/ParticleCopyNotification.h>
 
 #include "blockforest/BlockDataHandling.h"
 #include "blockforest/BlockForest.h"
@@ -97,7 +97,7 @@ void BlockForestDataHandling::serialize( IBlock * const block,
       //skip globals
       if (data::particle_flags::isSet( pIt->getFlags(), data::particle_flags::GLOBAL)) continue;
 
-      buffer << ParticleGhostCopyNotification( *pIt );
+      buffer << ParticleCopyNotification( *pIt );
       ++numOfParticles;
    }
 
@@ -140,7 +140,7 @@ void BlockForestDataHandling::serializeCoarseToFine( Block * const block, const
 
       if( childAABB.contains( pIt->getPosition()) )
       {
-         buffer << ParticleGhostCopyNotification( *pIt );
+         buffer << ParticleCopyNotification( *pIt );
          ++numOfParticles;
       }
    }
@@ -164,7 +164,7 @@ void BlockForestDataHandling::serializeFineToCoarse( Block * const block, const
       //skip globals
       if (data::particle_flags::isSet( pIt->getFlags(), data::particle_flags::GLOBAL)) continue;
 
-      buffer << ParticleGhostCopyNotification( *pIt );
+      buffer << ParticleCopyNotification( *pIt );
       ++numOfParticles;
    }
 
@@ -200,7 +200,7 @@ void BlockForestDataHandling::deserializeImpl( IBlock * const block, const Block
 
    while( numBodies > 0 )
    {
-      typename ParticleGhostCopyNotification::Parameters objparam;
+      typename ParticleCopyNotification::Parameters objparam;
       buffer >> objparam;
 
       auto pIt = createNewParticle(*ps_, objparam);
diff --git a/src/mesa_pd/mpi/notifications/NotificationType.h b/src/mesa_pd/mpi/notifications/NotificationType.h
index 6b9b751ad..66cf5bf95 100644
--- a/src/mesa_pd/mpi/notifications/NotificationType.h
+++ b/src/mesa_pd/mpi/notifications/NotificationType.h
@@ -39,6 +39,7 @@ enum NotificationType : uint8_t
 {
    PARTICLE_DELETION_NOTIFICATION = 1,
    PARTICLE_REMOVAL_NOTIFICATION,
+   PARTICLE_COPY_NOTIFICATION,
    PARTICLE_GHOST_COPY_NOTIFICATION,
    PARTICLE_FORCE_NOTIFICATION,
    PARTICLE_UPDATE_NOTIFICATION,
diff --git a/src/mesa_pd/mpi/notifications/ParticleCopyNotification.h b/src/mesa_pd/mpi/notifications/ParticleCopyNotification.h
new file mode 100644
index 000000000..aa47b020b
--- /dev/null
+++ b/src/mesa_pd/mpi/notifications/ParticleCopyNotification.h
@@ -0,0 +1,163 @@
+//======================================================================================================================
+//
+//  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 ParticleCopyNotification.h
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+//======================================================================================================================
+//
+//  THIS FILE IS GENERATED - PLEASE CHANGE THE TEMPLATE !!!
+//
+//======================================================================================================================
+
+#pragma once
+
+#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>
+#include <core/mpi/RecvBuffer.h>
+#include <core/mpi/SendBuffer.h>
+
+namespace walberla {
+namespace mesa_pd {
+
+/**
+ * A complete particle copy.
+ *
+ * Copies all properties that are not marked NEVER.
+ */
+class ParticleCopyNotification
+{
+public:
+   struct Parameters
+   {
+      walberla::id_t uid {UniqueID<data::Particle>::invalidID()};
+      walberla::mesa_pd::Vec3 position {real_t(0)};
+      walberla::real_t interactionRadius {real_t(0)};
+      walberla::mesa_pd::data::particle_flags::FlagT flags {};
+      int owner {-1};
+      std::unordered_set<walberla::mpi::MPIRank> ghostOwners {};
+      size_t shapeID {};
+      walberla::mesa_pd::Rot3 rotation {};
+      walberla::mesa_pd::Vec3 angularVelocity {real_t(0)};
+      walberla::mesa_pd::Vec3 linearVelocity {real_t(0)};
+      walberla::real_t invMass {real_t(1)};
+      walberla::mesa_pd::Vec3 oldForce {real_t(0)};
+      walberla::mesa_pd::Vec3 oldTorque {real_t(0)};
+      uint_t type {0};
+      std::map<walberla::id_t, walberla::mesa_pd::data::ContactHistory> oldContactHistory {};
+      walberla::real_t temperature {real_t(0)};
+   };
+
+   inline explicit ParticleCopyNotification( const data::Particle& particle ) : particle_(particle) {}
+   const data::Particle& particle_;
+};
+
+inline data::ParticleStorage::iterator createNewParticle(data::ParticleStorage& ps, const ParticleCopyNotification::Parameters& data)
+{
+   WALBERLA_ASSERT_EQUAL(ps.find(data.uid), ps.end(), "Particle with same uid already existent!");
+
+   auto pIt = ps.create(data.uid);
+   pIt->setUid(data.uid);
+   pIt->setPosition(data.position);
+   pIt->setInteractionRadius(data.interactionRadius);
+   pIt->setFlags(data.flags);
+   pIt->setOwner(data.owner);
+   pIt->setGhostOwners(data.ghostOwners);
+   pIt->setShapeID(data.shapeID);
+   pIt->setRotation(data.rotation);
+   pIt->setAngularVelocity(data.angularVelocity);
+   pIt->setLinearVelocity(data.linearVelocity);
+   pIt->setInvMass(data.invMass);
+   pIt->setOldForce(data.oldForce);
+   pIt->setOldTorque(data.oldTorque);
+   pIt->setType(data.type);
+   pIt->setOldContactHistory(data.oldContactHistory);
+   pIt->setTemperature(data.temperature);
+   return pIt;
+}
+
+template<>
+struct NotificationTrait<ParticleCopyNotification>
+{
+   static const NotificationType id = PARTICLE_COPY_NOTIFICATION;
+};
+
+}  // namespace mesa_pd
+}  // namespace walberla
+
+//======================================================================================================================
+//
+//  Send/Recv Buffer Serialization Specialization
+//
+//======================================================================================================================
+
+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 mesa_pd::ParticleCopyNotification& obj )
+{
+   buf.addDebugMarker( "cn" );
+   buf << obj.particle_.getUid();
+   buf << obj.particle_.getPosition();
+   buf << obj.particle_.getInteractionRadius();
+   buf << obj.particle_.getFlags();
+   buf << obj.particle_.getOwner();
+   buf << obj.particle_.getGhostOwners();
+   buf << obj.particle_.getShapeID();
+   buf << obj.particle_.getRotation();
+   buf << obj.particle_.getAngularVelocity();
+   buf << obj.particle_.getLinearVelocity();
+   buf << obj.particle_.getInvMass();
+   buf << obj.particle_.getOldForce();
+   buf << obj.particle_.getOldTorque();
+   buf << obj.particle_.getType();
+   buf << obj.particle_.getOldContactHistory();
+   buf << obj.particle_.getTemperature();
+   return buf;
+}
+
+template< typename T>    // Element type  of RecvBuffer
+mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, mesa_pd::ParticleCopyNotification::Parameters& objparam )
+{
+   buf.readDebugMarker( "cn" );
+   buf >> objparam.uid;
+   buf >> objparam.position;
+   buf >> objparam.interactionRadius;
+   buf >> objparam.flags;
+   buf >> objparam.owner;
+   buf >> objparam.ghostOwners;
+   buf >> objparam.shapeID;
+   buf >> objparam.rotation;
+   buf >> objparam.angularVelocity;
+   buf >> objparam.linearVelocity;
+   buf >> objparam.invMass;
+   buf >> objparam.oldForce;
+   buf >> objparam.oldTorque;
+   buf >> objparam.type;
+   buf >> objparam.oldContactHistory;
+   buf >> objparam.temperature;
+   return buf;
+}
+
+} // mpi
+} // walberla
\ No newline at end of file
-- 
GitLab