Commit 6e1c0704 authored by Martin Bauer's avatar Martin Bauer
Browse files

Merge remote-tracking branch 'origin/master' into gpu

parents 58b3e682 6f8484de
......@@ -329,38 +329,34 @@ int main( int argc, char ** argv )
SNN(*ps, domain);
if (bBarrier) WALBERLA_MPI_BARRIER();
tp["SNN"].end();
// if( i % 100 == 0 )
// {
// WALBERLA_LOG_DEVEL_ON_ROOT( "Timestep " << i << " / " << simulationSteps );
// SNNBytesSent = SNN.getBytesSent();
// SNNBytesReceived = SNN.getBytesReceived();
// SNNSends = SNN.getNumberOfSends();
// SNNReceives = SNN.getNumberOfReceives();
// RPBytesSent = RP.getBytesSent();
// RPBytesReceived = RP.getBytesReceived();
// RPSends = RP.getNumberOfSends();
// RPReceives = RP.getNumberOfReceives();
// walberla::mpi::reduceInplace(SNNBytesSent, walberla::mpi::SUM);
// walberla::mpi::reduceInplace(SNNBytesReceived, walberla::mpi::SUM);
// walberla::mpi::reduceInplace(SNNSends, walberla::mpi::SUM);
// walberla::mpi::reduceInplace(SNNReceives, walberla::mpi::SUM);
// walberla::mpi::reduceInplace(RPBytesSent, walberla::mpi::SUM);
// walberla::mpi::reduceInplace(RPBytesReceived, walberla::mpi::SUM);
// walberla::mpi::reduceInplace(RPSends, walberla::mpi::SUM);
// walberla::mpi::reduceInplace(RPReceives, walberla::mpi::SUM);
// auto cC = walberla::mpi::reduce(contactsChecked, walberla::mpi::SUM);
// auto cD = walberla::mpi::reduce(contactsDetected, walberla::mpi::SUM);
// auto cT = walberla::mpi::reduce(contactsTreated, walberla::mpi::SUM);
// WALBERLA_LOG_DEVEL_ON_ROOT( "SNN bytes communicated: " << SNNBytesSent << " / " << SNNBytesReceived );
// WALBERLA_LOG_DEVEL_ON_ROOT( "SNN communication partners: " << SNNSends << " / " << SNNReceives );
// WALBERLA_LOG_DEVEL_ON_ROOT( "RP bytes communicated: " << RPBytesSent << " / " << RPBytesReceived );
// WALBERLA_LOG_DEVEL_ON_ROOT( "RP communication partners: " << RPSends << " / " << RPReceives );
// WALBERLA_LOG_DEVEL_ON_ROOT( "contacts checked/detected/treated: " << cC << " / " << cD << " / " << cT );
// }
}
timer.end();
SNNBytesSent = SNN.getBytesSent();
SNNBytesReceived = SNN.getBytesReceived();
SNNSends = SNN.getNumberOfSends();
SNNReceives = SNN.getNumberOfReceives();
RPBytesSent = RP.getBytesSent();
RPBytesReceived = RP.getBytesReceived();
RPSends = RP.getNumberOfSends();
RPReceives = RP.getNumberOfReceives();
walberla::mpi::reduceInplace(SNNBytesSent, walberla::mpi::SUM);
walberla::mpi::reduceInplace(SNNBytesReceived, walberla::mpi::SUM);
walberla::mpi::reduceInplace(SNNSends, walberla::mpi::SUM);
walberla::mpi::reduceInplace(SNNReceives, walberla::mpi::SUM);
walberla::mpi::reduceInplace(RPBytesSent, walberla::mpi::SUM);
walberla::mpi::reduceInplace(RPBytesReceived, walberla::mpi::SUM);
walberla::mpi::reduceInplace(RPSends, walberla::mpi::SUM);
walberla::mpi::reduceInplace(RPReceives, walberla::mpi::SUM);
auto cC = walberla::mpi::reduce(contactsChecked, walberla::mpi::SUM);
auto cD = walberla::mpi::reduce(contactsDetected, walberla::mpi::SUM);
auto cT = walberla::mpi::reduce(contactsTreated, walberla::mpi::SUM);
WALBERLA_LOG_DEVEL_ON_ROOT( "SNN bytes communicated: " << SNNBytesSent << " / " << SNNBytesReceived );
WALBERLA_LOG_DEVEL_ON_ROOT( "SNN communication partners: " << SNNSends << " / " << SNNReceives );
WALBERLA_LOG_DEVEL_ON_ROOT( "RP bytes communicated: " << RPBytesSent << " / " << RPBytesReceived );
WALBERLA_LOG_DEVEL_ON_ROOT( "RP communication partners: " << RPSends << " / " << RPReceives );
WALBERLA_LOG_DEVEL_ON_ROOT( "contacts checked/detected/treated: " << cC << " / " << cD << " / " << cT );
auto timer_reduced = walberla::timing::getReduced(timer, REDUCE_TOTAL, 0);
double PUpS = 0.0;
WALBERLA_ROOT_SECTION()
......
waLBerla_add_executable ( NAME PackPerformance
FILES PackPerformance.cpp
DEPENDS core )
waLBerla_add_executable ( NAME ProbeVsExtraMessage
FILES ProbeVsExtraMessage.cpp
DEPENDS core postprocessing stencil )
//======================================================================================================================
//
// 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 PackPerformance.h
//! \author Sebastian Eibl <sebastian.eibl@fau.de>
//
//======================================================================================================================
#include "core/DataTypes.h"
#include "core/Environment.h"
#include "core/math/Vector3.h"
#include "core/mpi/BufferSystem.h"
#include "core/mpi/MPIManager.h"
#include "core/timing/TimingPool.h"
#include <array>
#include <iostream>
#include <sstream>
namespace walberla {
int main( int /*argc*/, char ** /*argv*/ )
{
const size_t numElements = 100000000;
mpi::SendBuffer sb0;
mpi::SendBuffer sb1;
mpi::SendBuffer sb2;
Vector3<real_t> v(1,2,3);
WcTimer timer0;
WcTimer timer1;
WcTimer timer2;
for (size_t i = 0; i < numElements; ++i)
{
sb0 << v;
sb1 << v;
sb2 << v;
}
WALBERLA_LOG_DEVEL_VAR(sb0.size());
sb0.clear();
sb1.clear();
sb2.clear();
timer0.start();
for (size_t i = 0; i < numElements; ++i)
{
sb0 << v;
}
timer0.end();
WALBERLA_LOG_DEVEL_VAR(sb0.size());
sb0.clear();
timer1.start();
for (size_t i = 0; i < numElements; ++i)
{
sb1 << v[0] << v[1] << v[2];
}
timer1.end();
WALBERLA_LOG_DEVEL_VAR(sb0.size());
sb0.clear();
timer2.start();
for (size_t i = 0; i < numElements; ++i)
{
auto pos = sb2.forward(sizeof(real_t) * 3);
memcpy(pos, v.data(), sizeof(real_t) * 3);
}
timer2.end();
WALBERLA_LOG_DEVEL_VAR(sb0.size());
sb0.clear();
//auto ptr0 = sb0.ptr();
//auto ptr1 = sb1.ptr();
//for (auto i = 0; i < numElements; ++i)
//{
// WALBERLA_ASSERT_EQUAL(*ptr0, *ptr1);
// ++ptr0;
// ++ptr1;
//}
WALBERLA_LOG_DEVEL("native: " << timer0.total());
WALBERLA_LOG_DEVEL("elementwise: " << timer1.total());
WALBERLA_LOG_DEVEL("memcpy: " << timer2.total());
return 0;
}
} // namespace walberla
int main( int argc, char* argv[] )
{
walberla::mpi::Environment mpiEnv( argc, argv );
WALBERLA_UNUSED(mpiEnv);
return walberla::main( argc, argv );
}
......@@ -37,6 +37,22 @@
namespace walberla {
class CustomBufferSystem : public mpi::BufferSystem
{
public:
explicit CustomBufferSystem( const MPI_Comm & communicator, int tag = 0 )
: mpi::BufferSystem(communicator, tag)
{}
auto& recvBuffer ( walberla::mpi::MPIRank rank )
{
auto it = recvInfos_.find(rank);
WALBERLA_CHECK_UNEQUAL(it, recvInfos_.end(), recvInfos_.size());
return it->second.buffer;
}
auto& getRecvInfos() {return recvInfos_;}
};
class MPIInfo
{
public:
......@@ -44,32 +60,41 @@ public:
int getNeighborRank(const stencil::Direction& dir);
private:
shared_ptr<mpi::MPIManager> manager_;
Vector3<uint_t> procs_;
Vector3<bool> periodicity_;
Vector3<int> pos_;
std::array<int, 27> ranks_;
};
MPIInfo::MPIInfo( const Vector3<uint_t>& procs, const Vector3<bool>& periodicity )
: procs_(procs)
: manager_(mpi::MPIManager::instance())
, procs_(procs)
, periodicity_(periodicity)
{
mpi::MPIManager::instance()->createCartesianComm(procs[0], procs[1], procs[2], periodicity[0], periodicity[1], periodicity[2]);
mpi::MPIManager::instance()->cartesianCoord(pos_.data());
manager_->createCartesianComm(procs[0], procs[1], procs[2], periodicity[0], periodicity[1], periodicity[2]);
manager_->cartesianCoord(pos_.data());
for (auto dirIt = stencil::D3Q27::beginNoCenter(); dirIt != stencil::D3Q27::end(); ++dirIt)
{
auto neighborCoord = pos_;
neighborCoord[0] += stencil::cx[*dirIt];
neighborCoord[1] += stencil::cy[*dirIt];
neighborCoord[2] += stencil::cz[*dirIt];
if (!periodicity_[0] && (neighborCoord[0] < 0)) ranks_[*dirIt] = -1;
if (!periodicity_[1] && (neighborCoord[1] < 0)) ranks_[*dirIt] = -1;
if (!periodicity_[2] && (neighborCoord[2] < 0)) ranks_[*dirIt] = -1;
if (!periodicity_[0] && (neighborCoord[0] >= int_c(procs_[0]))) ranks_[*dirIt] = -1;
if (!periodicity_[1] && (neighborCoord[1] >= int_c(procs_[1]))) ranks_[*dirIt] = -1;
if (!periodicity_[2] && (neighborCoord[2] >= int_c(procs_[2]))) ranks_[*dirIt] = -1;
ranks_[*dirIt] = manager_->cartesianRank(uint_c(neighborCoord[0]), uint_c(neighborCoord[1]), uint_c(neighborCoord[2]));
}
}
inline
int MPIInfo::getNeighborRank( const stencil::Direction& dir )
{
auto neighborCoord = pos_;
neighborCoord[0] += stencil::cx[dir];
neighborCoord[1] += stencil::cy[dir];
neighborCoord[2] += stencil::cz[dir];
if (neighborCoord[0] < 0) return -1;
if (neighborCoord[1] < 0) return -1;
if (neighborCoord[2] < 0) return -1;
if (neighborCoord[0] >= int_c(procs_[0])) return -1;
if (neighborCoord[1] >= int_c(procs_[1])) return -1;
if (neighborCoord[2] >= int_c(procs_[2])) return -1;
return mpi::MPIManager::instance()->cartesianRank(uint_c(neighborCoord[0]), uint_c(neighborCoord[1]), uint_c(neighborCoord[2]));
return ranks_[dir];
}
template <typename Stencil>
......@@ -82,15 +107,13 @@ void communicate( MPIInfo& mpiInfo,
std::vector<char> sendBuf(messageSize);
std::vector<char> recvBuf(messageSize);
WcTimer& timer = tp[iProbe ? "IProbe" : "twoMessage"];
mpi::BufferSystem bs( mpi::MPIManager::instance()->comm() );
CustomBufferSystem bs( mpi::MPIManager::instance()->comm() );
bs.useIProbe(iProbe);
for( uint_t i =0; i < iterations; ++i )
{
timer.start();
WALBERLA_MPI_BARRIER();
tp["pack"].start();
for (auto dirIt = Stencil::beginNoCenter(); dirIt != Stencil::end(); ++dirIt)
{
auto recvRank = mpiInfo.getNeighborRank( *dirIt );
......@@ -98,19 +121,29 @@ void communicate( MPIInfo& mpiInfo,
bs.sendBuffer(recvRank) << sendBuf;
WALBERLA_ASSERT_EQUAL(bs.sendBuffer(recvRank).size(), messageSize + sizeof(size_t));
}
tp["pack"].end();
WALBERLA_MPI_BARRIER();
tp["communicate"].start();
bs.setReceiverInfoFromSendBufferState(false, true);
bs.sendAll();
for( auto it = bs.begin(); it != bs.end(); ++it )
{
WALBERLA_ASSERT_EQUAL(it.buffer().size(), messageSize + sizeof(size_t));
it.buffer() >> recvBuf;
WALBERLA_ASSERT_EQUAL(recvBuf.size(), messageSize);
WALBERLA_ASSERT(it.buffer().isEmpty());
}
tp["communicate"].end();
timer.end();
WALBERLA_MPI_BARRIER();
tp["unpack"].start();
auto& recvInfos = bs.getRecvInfos();
for (auto recvIt = recvInfos.begin(); recvIt != recvInfos.end(); ++recvIt)
{
auto& rb = recvIt->second.buffer;
rb >> recvBuf;
WALBERLA_ASSERT(rb.isEmpty());
}
tp["unpack"].end();
}
}
......@@ -166,25 +199,27 @@ int main( int argc, char ** argv )
MPIInfo mpiInfo(procs, periodicity);
WcTimingPool tp;
WcTimingPool tp_twoMessages;
WcTimingPool tp_probe;
WALBERLA_MPI_BARRIER();
if (stencil == "D3Q27")
{
communicate<stencil::D3Q27>(mpiInfo, iterations, messageSize, false, tp);
communicate<stencil::D3Q27>(mpiInfo, iterations, messageSize, true, tp);
communicate<stencil::D3Q27>(mpiInfo, iterations, messageSize, false, tp_twoMessages);
communicate<stencil::D3Q27>(mpiInfo, iterations, messageSize, true, tp_probe);
} else if (stencil == "D3Q19")
{
communicate<stencil::D3Q19>(mpiInfo, iterations, messageSize, false, tp);
communicate<stencil::D3Q19>(mpiInfo, iterations, messageSize, true, tp);
communicate<stencil::D3Q19>(mpiInfo, iterations, messageSize, false, tp_twoMessages);
communicate<stencil::D3Q19>(mpiInfo, iterations, messageSize, true, tp_probe);
} else if (stencil == "D3Q7")
{
communicate<stencil::D3Q7>(mpiInfo, iterations, messageSize, false, tp);
communicate<stencil::D3Q7>(mpiInfo, iterations, messageSize, true, tp);
communicate<stencil::D3Q7>(mpiInfo, iterations, messageSize, false, tp_twoMessages);
communicate<stencil::D3Q7>(mpiInfo, iterations, messageSize, true, tp_probe);
} else
{
WALBERLA_ABORT("stencil not supported: " << stencil);
}
WALBERLA_LOG_INFO_ON_ROOT(tp);
WALBERLA_LOG_INFO_ON_ROOT(tp_twoMessages);
WALBERLA_LOG_INFO_ON_ROOT(tp_probe);
WALBERLA_ROOT_SECTION()
{
......@@ -216,7 +251,8 @@ int main( int argc, char ** argv )
stringProperties["SLURM_TASKS_PER_NODE"] = envToString(std::getenv( "SLURM_TASKS_PER_NODE" ));
auto runId = postprocessing::storeRunInSqliteDB( "ProbeVsTwoMessages.sqlite", integerProperties, stringProperties, realProperties );
postprocessing::storeTimingPoolInSqliteDB( "ProbeVsTwoMessages.sqlite", runId, tp, "Timings" );
postprocessing::storeTimingPoolInSqliteDB( "ProbeVsTwoMessages.sqlite", runId, tp_twoMessages, "twoMessages" );
postprocessing::storeTimingPoolInSqliteDB( "ProbeVsTwoMessages.sqlite", runId, tp_probe, "probe" );
}
return 0;
......
......@@ -10,6 +10,7 @@ waLBerla_python_file_generates(UniformGridGPU.py
UniformGridGPU_PackInfo.cu UniformGridGPU_PackInfo.h
UniformGridGPU_MacroSetter.cpp UniformGridGPU_MacroSetter.h
UniformGridGPU_MacroGetter.cpp UniformGridGPU_MacroGetter.h
UniformGridGPU_Defines.h
)
foreach(config srt trt mrt smagorinsky entropic )
......
......@@ -35,6 +35,7 @@
#include "UniformGridGPU_Communication.h"
#include "UniformGridGPU_MacroSetter.h"
#include "UniformGridGPU_MacroGetter.h"
#include "UniformGridGPU_Defines.h"
using namespace walberla;
......@@ -332,7 +333,10 @@ int main( int argc, char **argv )
if ( pythonCallbackResults.isCallable())
{
pythonCallbackResults.data().exposeValue( "mlupsPerProcess", mlupsPerProcess );
pythonCallbackResults.data().exposeValue( "githash", WALBERLA_GIT_SHA1 );
pythonCallbackResults.data().exposeValue( "stencil", infoStencil );
pythonCallbackResults.data().exposeValue( "configName", infoConfigName );
pythonCallbackResults.data().exposeValue( "cse_global", infoCseGlobal );
pythonCallbackResults.data().exposeValue( "cse_pdfs", infoCsePdfs );
// Call Python function to report results
pythonCallbackResults();
}
......
......@@ -55,6 +55,15 @@ options_dict = {
}
}
info_header = """
#include "stencil/D3Q{q}.h"\nusing Stencil_T = walberla::stencil::D3Q{q};
const char * infoStencil = "{stencil}";
const char * infoConfigName = "{configName}";
const bool infoCseGlobal = {cse_global};
const bool infoCsePdfs = {cse_pdfs};
"""
with CodeGeneration() as ctx:
accessor = StreamPullTwoFieldsAccessor()
#accessor = StreamPushTwoFieldsAccessor()
......@@ -109,3 +118,12 @@ with CodeGeneration() as ctx:
# communication
generate_pack_info_from_kernel(ctx, 'UniformGridGPU_PackInfo', update_rule, target='gpu')
infoHeaderParams = {
'stencil': stencil_str,
'q': q,
'configName': ctx.config,
'cse_global': int(options['optimization']['cse_global']),
'cse_pdfs': int(options['optimization']['cse_pdfs']),
}
ctx.write_file("UniformGridGPU_Defines.h", info_header.format(**infoHeaderParams))
......@@ -225,6 +225,7 @@ int main( int argc, char **argv )
bool useGui = parameters.getParameter<bool>( "useGui", false );
if( useGui )
{
#ifdef WALBERLA_ENABLE_GUI
cuda::fieldCpy< PdfField_T, cuda::GPUField< real_t > >( blocks, pdfFieldCpuID, pdfFieldGpuID );
timeLoop.addFuncAfterTimeStep( cuda::fieldCpyFunctor<PdfField_T, cuda::GPUField<real_t> >( blocks, pdfFieldCpuID, pdfFieldGpuID ), "copy to CPU" );
GUI gui( timeLoop, blocks, argc, argv);
......@@ -235,6 +236,9 @@ int main( int argc, char **argv )
return nullptr;
});
gui.run();
#else
WALBERLA_ABORT_NO_DEBUG_INFO("Application was built without GUI. Set useGui to false or re-compile with GUI.")
#endif
}
else
{
......@@ -264,7 +268,10 @@ int main( int argc, char **argv )
if ( pythonCallbackResults.isCallable())
{
pythonCallbackResults.data().exposeValue( "mlupsPerProcess", mlupsPerProcess );
pythonCallbackResults.data().exposeValue( "githash", WALBERLA_GIT_SHA1 );
pythonCallbackResults.data().exposeValue( "stencil", infoStencil );
pythonCallbackResults.data().exposeValue( "configName", infoConfigName );
pythonCallbackResults.data().exposeValue( "cse_global", infoCseGlobal );
pythonCallbackResults.data().exposeValue( "cse_pdfs", infoCsePdfs );
// Call Python function to report results
pythonCallbackResults();
}
......
......@@ -53,6 +53,16 @@ options_dict = {
}
}
info_header = """
#include "stencil/D3Q{q}.h"\nusing Stencil_T = walberla::stencil::D3Q{q};
const char * infoStencil = "{stencil}";
const char * infoConfigName = "{configName}";
const bool infoCseGlobal = {cse_global};
const bool infoCsePdfs = {cse_pdfs};
"""
with CodeGeneration() as ctx:
accessors = {
'Even': AAEvenTimeStepAccessor(),
......@@ -105,5 +115,11 @@ with CodeGeneration() as ctx:
generate_pack_info_from_kernel(ctx, 'UniformGridGPU_AA_PackInfoPull', update_rules['Odd'], kind='pull', target='gpu')
generate_pack_info_from_kernel(ctx, 'UniformGridGPU_AA_PackInfoPush', update_rules['Odd'], kind='push', target='gpu')
ctx.write_file("UniformGridGPU_AA_Defines.h",
'#include "stencil/D3Q{0}.h"\nusing Stencil_T = walberla::stencil::D3Q{0}; \n '.format(q))
infoHeaderParams = {
'stencil': stencil_str,
'q': q,
'configName': ctx.config,
'cse_global': int(options['optimization']['cse_global']),
'cse_pdfs': int(options['optimization']['cse_pdfs']),
}
ctx.write_file("UniformGridGPU_AA_Defines.h", info_header.format(**infoHeaderParams))
......@@ -89,15 +89,15 @@ int main( int argc, char ** argv )
WALBERLA_LOG_DEVEL(timestep);
linkedCells.clear();
storage->forEachParticle(true, kernel::SelectAll(), ac, ipilc, ac, linkedCells);
storage->forEachParticle(true, kernel::SelectAll(), ac, vvPreForce, ac);
storage->forEachParticle(true, kernel::SelectLocal(), ac, vvPreForce, ac);
linkedCells.forEachParticlePairHalf(true, kernel::SelectAll(), ac, lj, ac);
const real_t coeff = real_t(0.2);
storage->forEachParticle(true,
kernel::SelectAll(),
kernel::SelectLocal(),
ac,
[coeff](const size_t idx, auto& access){ access.setForce(idx, -coeff*access.getPosition(idx) + access.getForce(idx)); },
ac);
storage->forEachParticle(true, kernel::SelectAll(), ac, vvPostForce, ac);
storage->forEachParticle(true, kernel::SelectLocal(), ac, vvPostForce, ac);
vtkWriter->write();
}
......
......@@ -29,6 +29,7 @@
#include <mesa_pd/data/DataTypes.h>
#include <mesa_pd/data/Flags.h>
#include <mesa_pd/data/ParticleStorage.h>
#include <mesa_pd/mpi/notifications/reset.h>
#include <core/mpi/BufferSystem.h>
#include <core/logging/Logging.h>
......@@ -100,6 +101,7 @@ void ReduceProperty::operator()(data::ParticleStorage& ps) const
}
sb << Notification( p );
reset<Notification>( p );
} else
{
//local particles should receive the property and sum it up
......
......@@ -28,6 +28,7 @@
#include <mesa_pd/data/ContactHistory.h>
#include <mesa_pd/data/DataTypes.h>
#include <mesa_pd/mpi/notifications/reset.h>
#include <core/mpi/BufferDataTypeExtensions.h>
#include <core/mpi/Datatype.h>
......@@ -56,6 +57,12 @@ public:
const data::Particle& p_;
};
template <>
void reset<ContactHistoryNotification>(data::Particle& p)
{
p.setNewContactHistory(std::map<walberla::id_t, walberla::mesa_pd::data::ContactHistory>());
}
void reduce(data::Particle&& p, const ContactHistoryNotification::Parameters& objparam)
{
auto& ch = p.getNewContactHistoryRef();
......
......@@ -29,6 +29,7 @@
#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>
......@@ -55,6 +56,13 @@ public:
const data::Particle& p_;
};
template <>
void reset<ForceTorqueNotification>(data::Particle& p)
{
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_;
......
......@@ -196,7 +196,10 @@ public:
inline friend mpi::GenericRecvBuffer< ET > & operator>>( mpi::GenericRecvBuffer< ET > & buf, GenericAABB< T > & aabb )
{
buf.readDebugMarker( "bb" );
buf >> aabb.minCorner_ >> aabb.maxCorner_;
static_assert ( std::is_trivially_copyable< GenericAABB< T > >::value,
"type has to be trivially copyable for the memcpy to work correctly" );
auto pos = buf.skip(sizeof(GenericAABB< T >));
std::memcpy(&aabb, pos, sizeof(GenericAABB< T >));
WALBERLA_ASSERT( aabb.checkInvariant() );
return buf;
}
......
......@@ -1883,7 +1883,11 @@ template< typename T, // Element type of SendBuffer
mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, const GenericAABB< VT > & aabb )
{
buf.addDebugMarker( "bb" );
return buf << aabb.minCorner() << aabb.maxCorner();