diff --git a/python/mesa_pd.py b/python/mesa_pd.py index c80bcf232a49016c87a03030b790ffb72ea426fb..42572d41ffaaf44f7edb932c918678ae8d311b33 100755 --- a/python/mesa_pd.py +++ b/python/mesa_pd.py @@ -108,6 +108,11 @@ if __name__ == '__main__': mpd.add(mpi.ClearGhostOwnerSync()) mpd.add(mpi.ClearNextNeighborSync()) mpd.add(mpi.Notifications(ps)) + ftn = mpd.add(mpi.PropertyNotification('ForceTorqueNotification')) + ftn.add_property('force', 'mesa_pd::Vec3', 'Vec3(real_t(0))') + ftn.add_property('torque', 'mesa_pd::Vec3', 'Vec3(real_t(0))') + hfn = mpd.add(mpi.PropertyNotification('HeatFluxNotification')) + hfn.add_property('heatFlux', 'real_t', 'real_t(0)') mpd.add(mpi.ReduceContactHistory()) mpd.add(mpi.ReduceProperty()) mpd.add(mpi.ShapePackUnpack(ps)) diff --git a/python/mesa_pd/mpi/Notifications.py b/python/mesa_pd/mpi/Notifications.py index 4a87ee426c931d7c6627ddea582584a511e74061..5be06cbf48583a1b677ef0dcad0612102112b46c 100644 --- a/python/mesa_pd/mpi/Notifications.py +++ b/python/mesa_pd/mpi/Notifications.py @@ -9,8 +9,6 @@ class Notifications: def generate(self, module): ctx = {'module': module, 'particle' : self.ps.get_context()} - generate_file(module['module_path'], 'mpi/notifications/ForceTorqueNotification.templ.h', ctx) - generate_file(module['module_path'], 'mpi/notifications/HeatFluxNotification.templ.h', ctx) generate_file(module['module_path'], 'mpi/notifications/ParseMessage.templ.h', ctx) generate_file(module['module_path'], 'mpi/notifications/ParticleCopyNotification.templ.h', ctx) generate_file(module['module_path'], 'mpi/notifications/ParticleGhostCopyNotification.templ.h', ctx) diff --git a/python/mesa_pd/mpi/PropertyNotification.py b/python/mesa_pd/mpi/PropertyNotification.py new file mode 100644 index 0000000000000000000000000000000000000000..f7bced94f832e9b2f9ecde2b5136e22b7af0d554 --- /dev/null +++ b/python/mesa_pd/mpi/PropertyNotification.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +from ..utility import find, generate_file, TerminalColor + + +class PropertyNotification: + def __init__(self, name): + self.context = {'name': name, 'properties': []} + + def add_property(self, name, type, reset_value): + prop = find(lambda x: x['name'] == name, self.context['properties']) + if (prop == None): + self.context['properties'].append({'name': name, 'type': type, 'resetValue': reset_value}) + else: + if not (prop['type'] == type and prop['name'] == name and prop['resetValue'] == reset_value): + new_prop = {'name': name, 'type': type, 'resetValue': reset_value} + raise RuntimeError( + f"{TerminalColor.RED} property definition differs from previous one:\nPREVIOUS {prop}\nNEW {new_prop} {TerminalColor.DEFAULT}") + print(f"{TerminalColor.YELLOW} reusing property: {name} {TerminalColor.DEFAULT}") + + def generate(self, module): + ctx = {'module': module, **self.context} + generate_file(module['module_path'], 'mpi/notifications/PropertyNotification.templ.h', ctx, f'mpi/notifications/{self.context["name"]}.h') diff --git a/python/mesa_pd/mpi/__init__.py b/python/mesa_pd/mpi/__init__.py index 37f0854ad44a0da7adb8420cf7f11578028d8d5c..e74f708e8376e0db1f56a421f37a2ab9bcf45017 100644 --- a/python/mesa_pd/mpi/__init__.py +++ b/python/mesa_pd/mpi/__init__.py @@ -4,6 +4,7 @@ from .BroadcastProperty import BroadcastProperty from .ClearGhostOwnerSync import ClearGhostOwnerSync from .ClearNextNeighborSync import ClearNextNeighborSync from .Notifications import Notifications +from .PropertyNotification import PropertyNotification from .ReduceContactHistory import ReduceContactHistory from .ReduceProperty import ReduceProperty from .ShapePackUnpack import ShapePackUnpack @@ -14,6 +15,7 @@ from .SyncNextNeighborsNoGhosts import SyncNextNeighborsNoGhosts __all__ = ['BroadcastProperty', 'ClearGhostOwnerSync', 'ClearNextNeighborSync', + 'PropertyNotification', 'ReduceContactHistory', 'ReduceProperty', 'ShapePackUnpack', diff --git a/python/mesa_pd/templates/mpi/notifications/HeatFluxNotification.templ.h b/python/mesa_pd/templates/mpi/notifications/HeatFluxNotification.templ.h deleted file mode 100644 index ce463a214544c48f460bed15997e1a3373e63484..0000000000000000000000000000000000000000 --- a/python/mesa_pd/templates/mpi/notifications/HeatFluxNotification.templ.h +++ /dev/null @@ -1,114 +0,0 @@ -//====================================================================================================================== -// -// 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 HeatFluxNotification.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/notifications/NotificationType.h> -#include <mesa_pd/mpi/notifications/reset.h> - -#include <core/mpi/Datatype.h> -#include <core/mpi/RecvBuffer.h> -#include <core/mpi/SendBuffer.h> - -namespace walberla { -namespace mesa_pd { - -/** - * Trasmits force and torque information. - */ -class HeatFluxNotification -{ -public: - struct Parameters - { - id_t uid_; - real_t heatFlux_; - }; - - inline explicit HeatFluxNotification( const data::Particle& p ) : p_(p) {} - - const data::Particle& p_; -}; - -template <> -void reset<HeatFluxNotification>(data::Particle& p) -{ - p.setHeatFlux( real_t(0) ); -} - -void reduce(data::Particle&& p, const HeatFluxNotification::Parameters& objparam) -{ - p.getHeatFluxRef() += objparam.heatFlux_; -} - -void update(data::Particle&& p, const HeatFluxNotification::Parameters& objparam) -{ - p.setHeatFlux( objparam.heatFlux_ ); -} - -} // 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::HeatFluxNotification& obj ) -{ - buf.addDebugMarker( "hf" ); - buf << obj.p_.getUid(); - buf << obj.p_.getHeatFlux(); - return buf; -} - -template< typename T> // Element type of RecvBuffer -mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, mesa_pd::HeatFluxNotification::Parameters& objparam ) -{ - buf.readDebugMarker( "hf" ); - buf >> objparam.uid_; - buf >> objparam.heatFlux_; - return buf; -} - -template< > -struct BufferSizeTrait< mesa_pd::HeatFluxNotification > { - static const bool constantSize = true; - static const uint_t size = BufferSizeTrait<id_t>::size + - BufferSizeTrait<real_t>::size + - mpi::BUFFER_DEBUG_OVERHEAD; -}; - -} // mpi -} // walberla diff --git a/python/mesa_pd/templates/mpi/notifications/ForceTorqueNotification.templ.h b/python/mesa_pd/templates/mpi/notifications/PropertyNotification.templ.h similarity index 69% rename from python/mesa_pd/templates/mpi/notifications/ForceTorqueNotification.templ.h rename to python/mesa_pd/templates/mpi/notifications/PropertyNotification.templ.h index 6bfa6412b1a7d5e1d8661c36868f14b76192f69a..701f21ea910476a3ac9e9449be91a6a9c5b4ed46 100644 --- a/python/mesa_pd/templates/mpi/notifications/ForceTorqueNotification.templ.h +++ b/python/mesa_pd/templates/mpi/notifications/PropertyNotification.templ.h @@ -13,7 +13,7 @@ // 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 ParticlePropertyNotification.h +//! \file {{name}}.h //! \author Sebastian Eibl <sebastian.eibl@fau.de> // //====================================================================================================================== @@ -41,38 +41,42 @@ namespace mesa_pd { /** * Trasmits force and torque information. */ -class ForceTorqueNotification +class {{name}} { public: struct Parameters { id_t uid_; - Vec3 force_; - Vec3 torque_; + {%- for prop in properties %} + {{prop.type}} {{prop.name}}_; + {%- endfor %} }; - inline explicit ForceTorqueNotification( const data::Particle& p ) : p_(p) {} + inline explicit {{name}}( const data::Particle& p ) : p_(p) {} const data::Particle& p_; }; template <> -void reset<ForceTorqueNotification>(data::Particle& p) +void reset<{{name}}>(data::Particle& p) { - p.setForce( Vec3(real_t(0)) ); - p.setTorque( Vec3(real_t(0)) ); + {%- for prop in properties %} + p.set{{prop.name | capFirst}}( {{prop.resetValue}} ); + {%- endfor %} } -void reduce(data::Particle&& p, const ForceTorqueNotification::Parameters& objparam) +void reduce(data::Particle&& p, const {{name}}::Parameters& objparam) { - p.getForceRef() += objparam.force_; - p.getTorqueRef() += objparam.torque_; + {%- for prop in properties %} + p.get{{prop.name | capFirst}}Ref() += objparam.{{prop.name}}_; + {%- endfor %} } -void update(data::Particle&& p, const ForceTorqueNotification::Parameters& objparam) +void update(data::Particle&& p, const {{name}}::Parameters& objparam) { - p.setForce( objparam.force_ ); - p.setTorque( objparam.torque_ ); + {%- for prop in properties %} + p.set{{prop.name | capFirst}}( objparam.{{prop.name}}_ ); + {%- endfor %} } } // namespace mesa_pd @@ -89,31 +93,34 @@ 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::ForceTorqueNotification& obj ) +mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, const mesa_pd::{{name}}& obj ) { - buf.addDebugMarker( "ft" ); + buf.addDebugMarker( "pn" ); buf << obj.p_.getUid(); - buf << obj.p_.getForce(); - buf << obj.p_.getTorque(); + {%- for prop in properties %} + buf << obj.p_.get{{prop.name | capFirst}}(); + {%- endfor %} return buf; } template< typename T> // Element type of RecvBuffer -mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, mesa_pd::ForceTorqueNotification::Parameters& objparam ) +mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, mesa_pd::{{name}}::Parameters& objparam ) { - buf.readDebugMarker( "ft" ); + buf.readDebugMarker( "pn" ); buf >> objparam.uid_; - buf >> objparam.force_; - buf >> objparam.torque_; + {%- for prop in properties %} + buf >> objparam.{{prop.name}}_; + {%- endfor %} return buf; } template< > -struct BufferSizeTrait< mesa_pd::ForceTorqueNotification > { +struct BufferSizeTrait< mesa_pd::{{name}} > { static const bool constantSize = true; static const uint_t size = BufferSizeTrait<id_t>::size + - BufferSizeTrait<mesa_pd::Vec3>::size + - BufferSizeTrait<mesa_pd::Vec3>::size + + {%- for prop in properties %} + BufferSizeTrait<{{prop.type}}>::size + + {%- endfor %} mpi::BUFFER_DEBUG_OVERHEAD; }; diff --git a/src/mesa_pd/mpi/notifications/ForceTorqueNotification.h b/src/mesa_pd/mpi/notifications/ForceTorqueNotification.h index d19d0d084635528194d048820d9d70785d03940a..2a41c9d4f34fa786c54fd75cf86b750aaf0abfdc 100644 --- a/src/mesa_pd/mpi/notifications/ForceTorqueNotification.h +++ b/src/mesa_pd/mpi/notifications/ForceTorqueNotification.h @@ -13,7 +13,7 @@ // 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 ParticlePropertyNotification.h +//! \file ForceTorqueNotification.h //! \author Sebastian Eibl <sebastian.eibl@fau.de> // //====================================================================================================================== @@ -47,8 +47,8 @@ public: struct Parameters { id_t uid_; - Vec3 force_; - Vec3 torque_; + mesa_pd::Vec3 force_; + mesa_pd::Vec3 torque_; }; inline explicit ForceTorqueNotification( const data::Particle& p ) : p_(p) {} @@ -59,19 +59,19 @@ public: template <> void reset<ForceTorqueNotification>(data::Particle& p) { - p.setForce( Vec3(real_t(0)) ); + p.setForce( Vec3(real_t(0)) ); p.setTorque( Vec3(real_t(0)) ); } void reduce(data::Particle&& p, const ForceTorqueNotification::Parameters& objparam) { - p.getForceRef() += objparam.force_; + p.getForceRef() += objparam.force_; p.getTorqueRef() += objparam.torque_; } void update(data::Particle&& p, const ForceTorqueNotification::Parameters& objparam) { - p.setForce( objparam.force_ ); + p.setForce( objparam.force_ ); p.setTorque( objparam.torque_ ); } @@ -91,7 +91,7 @@ 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::ForceTorqueNotification& obj ) { - buf.addDebugMarker( "ft" ); + buf.addDebugMarker( "pn" ); buf << obj.p_.getUid(); buf << obj.p_.getForce(); buf << obj.p_.getTorque(); @@ -101,7 +101,7 @@ mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, cons template< typename T> // Element type of RecvBuffer mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, mesa_pd::ForceTorqueNotification::Parameters& objparam ) { - buf.readDebugMarker( "ft" ); + buf.readDebugMarker( "pn" ); buf >> objparam.uid_; buf >> objparam.force_; buf >> objparam.torque_; diff --git a/src/mesa_pd/mpi/notifications/HeatFluxNotification.h b/src/mesa_pd/mpi/notifications/HeatFluxNotification.h index 884a684e9aadf477c9e33a1c2cb9905aeefc5322..a2ab05d07154697dc5c38d1ddf3a94767599a3db 100644 --- a/src/mesa_pd/mpi/notifications/HeatFluxNotification.h +++ b/src/mesa_pd/mpi/notifications/HeatFluxNotification.h @@ -63,7 +63,7 @@ void reset<HeatFluxNotification>(data::Particle& p) void reduce(data::Particle&& p, const HeatFluxNotification::Parameters& objparam) { - p.getHeatFluxRef() += objparam.heatFlux_; + p.getHeatFluxRef() += objparam.heatFlux_; } void update(data::Particle&& p, const HeatFluxNotification::Parameters& objparam) @@ -87,7 +87,7 @@ 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::HeatFluxNotification& obj ) { - buf.addDebugMarker( "hf" ); + buf.addDebugMarker( "pn" ); buf << obj.p_.getUid(); buf << obj.p_.getHeatFlux(); return buf; @@ -96,7 +96,7 @@ mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, cons template< typename T> // Element type of RecvBuffer mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, mesa_pd::HeatFluxNotification::Parameters& objparam ) { - buf.readDebugMarker( "hf" ); + buf.readDebugMarker( "pn" ); buf >> objparam.uid_; buf >> objparam.heatFlux_; return buf; diff --git a/tests/mesa_pd/mpi/ReduceProperty.cpp b/tests/mesa_pd/mpi/ReduceProperty.cpp index 50c5b77836e842f6ba88cb4695c0bccf87c5389d..3f8138ac942f553831adf3854aeca0539822540b 100644 --- a/tests/mesa_pd/mpi/ReduceProperty.cpp +++ b/tests/mesa_pd/mpi/ReduceProperty.cpp @@ -21,6 +21,7 @@ #include <mesa_pd/data/ParticleStorage.h> #include <mesa_pd/domain/BlockForestDomain.h> #include <mesa_pd/mpi/notifications/ForceTorqueNotification.h> +#include <mesa_pd/mpi/notifications/HeatFluxNotification.h> #include <mesa_pd/mpi/ReduceProperty.h> #include <mesa_pd/mpi/SyncNextNeighbors.h> @@ -86,16 +87,23 @@ void main( int argc, char ** argv ) if (pIt != ps.end()) { pIt->getForceRef() += Vec3(real_c(walberla::mpi::MPIManager::instance()->rank())); + pIt->getTorqueRef() += Vec3(real_c(walberla::mpi::MPIManager::instance()->rank())); + pIt->getHeatFluxRef() += real_c(walberla::mpi::MPIManager::instance()->rank()); } RP.operator()<ForceTorqueNotification>(ps); + RP.operator()<HeatFluxNotification>(ps); if (walberla::mpi::MPIManager::instance()->rank() == 0) { WALBERLA_CHECK_FLOAT_EQUAL( pIt->getForce(), Vec3(real_t(28)) ); + WALBERLA_CHECK_FLOAT_EQUAL( pIt->getTorque(), Vec3(real_t(28)) ); + WALBERLA_CHECK_FLOAT_EQUAL( pIt->getHeatFlux(), real_t(28) ); } else { WALBERLA_CHECK_FLOAT_EQUAL( pIt->getForce(), Vec3(0) ); + WALBERLA_CHECK_FLOAT_EQUAL( pIt->getTorque(), Vec3(0) ); + WALBERLA_CHECK_FLOAT_EQUAL( pIt->getHeatFlux(), real_t(0) ); } }