# PhasicFlow: src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.cpp Source File
PhasicFlow is an open-source parallel DEM (discrete element method) package for simulating granular flow. It is developed in C++ and can be exectued on both GPU (like CUDA) and CPU.

sphereInteraction.cpp
Go to the documentation of this file.
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
template<typename cFM,typename gMM,template <class, class, class> class cLT>
bool pFlow::sphereInteraction<cFM,gMM, cLT>::createSphereInteraction()
{
realVector_D rhoD("densities", this->densities());
auto modelDict = this->subDict("model");
forceModel_ = makeUnique<ContactForceModel>(
this->numMaterials(),
rhoD.deviceView(),
modelDict );
uint32 nPrtcl = sphParticles_.size();
contactSearch_ = contactSearch::create(
subDict("contactSearch"),
sphParticles_.extendedDomain().domainBox(),
sphParticles_,
geometryMotion_,
timers());
ppContactList_ = makeUnique<ContactListType>(nPrtcl+1);
pwContactList_ = makeUnique<ContactListType>(nPrtcl/5+1);
return true;
}
template<typename cFM,typename gMM,template <class, class, class> class cLT>
bool pFlow::sphereInteraction<cFM,gMM, cLT>::sphereSphereInteraction()
{
auto lastItem = ppContactList_().loopCount();
// create the kernel functor
pFlow::sphereInteractionKernels::ppInteractionFunctor
ppInteraction(
this->dt(),
this->forceModel_(),
ppContactList_(), // to be read
sphParticles_.diameter().deviceViewAll(),
sphParticles_.propertyId().deviceViewAll(),
sphParticles_.pointPosition().deviceViewAll(),
sphParticles_.velocity().deviceViewAll(),
sphParticles_.rVelocity().deviceViewAll(),
sphParticles_.contactForce().deviceViewAll(),
sphParticles_.contactTorque().deviceViewAll()
);
Kokkos::parallel_for(
"ppInteraction",
rpPPInteraction(0,lastItem),
ppInteraction
);
Kokkos::fence();
return true;
}
template<typename cFM,typename gMM,template <class, class, class> class cLT>
bool pFlow::sphereInteraction<cFM,gMM, cLT>::sphereWallInteraction()
{
uint32 lastItem = pwContactList_().loopCount();
uint32 iter = this->currentIter();
real t = this->currentTime();
real dt = this->dt();
pFlow::sphereInteractionKernels::pwInteractionFunctor
pwInteraction(
dt,
this->forceModel_(),
pwContactList_(),
geometryMotion_.getTriangleAccessor(),
geometryMotion_.getModel(iter, t, dt) ,
sphParticles_.diameter().deviceViewAll() ,
sphParticles_.propertyId().deviceViewAll(),
sphParticles_.pointPosition().deviceViewAll(),
sphParticles_.velocity().deviceViewAll(),
sphParticles_.rVelocity().deviceViewAll() ,
sphParticles_.contactForce().deviceViewAll(),
sphParticles_.contactTorque().deviceViewAll() ,
geometryMotion_.triMotionIndex().deviceViewAll(),
geometryMotion_.propertyId().deviceViewAll(),
geometryMotion_.contactForceWall().deviceViewAll()
);
Kokkos::parallel_for(
"",
rpPWInteraction(0,lastItem),
pwInteraction
);
Kokkos::fence();
return true;
}
template<typename cFM,typename gMM,template <class, class, class> class cLT>
pFlow::sphereInteraction<cFM,gMM, cLT>::sphereInteraction
(
systemControl& control,
const particles& prtcl,
const geometry& geom
)
:
interaction(control, prtcl, geom),
geometryMotion_(dynamic_cast<const GeometryMotionModel&>(geom)),
sphParticles_(dynamic_cast<const sphereParticles&>(prtcl)),
boundaryInteraction_(sphParticles_,geometryMotion_),
ppInteractionTimer_("sphere-sphere interaction (internal)", &this->timers()),
pwInteractionTimer_("sphere-wall interaction (internal)", &this->timers()),
boundaryInteractionTimer_("sphere-sphere interaction (boundary)",&this->timers()),
contactListMangementTimer_("list management (interal)", &this->timers()),
contactListMangementBoundaryTimer_("list management (boundary)", &this->timers())
{
if(!createSphereInteraction())
{
fatalExit;
}
for(uint32 i=0; i<6; i++)
{
activeBoundaries_[i] = boundaryInteraction_[i].ppPairsAllocated();
}
}
template<typename cFM,typename gMM,template <class, class, class> class cLT>
bool pFlow::sphereInteraction<cFM,gMM, cLT>::beforeIteration()
{
return true;
}
template<typename cFM,typename gMM,template <class, class, class> class cLT>
bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
{
timeInfo ti = this->TimeInfo();
auto iter = ti.iter();
auto t = ti.t();
auto dt = ti.dt();
auto& contactSearchRef = contactSearch_();
bool broadSearch = contactSearchRef.enterBroadSearch(ti);
bool broadSearchBoundary = contactSearchRef.enterBroadSearchBoundary(ti);
sphParticles_.diameter().updateBoundaries(DataDirection::SlaveToMaster);
sphParticles_.velocity().updateBoundaries(DataDirection::SlaveToMaster);
sphParticles_.rVelocity().updateBoundaries(DataDirection::SlaveToMaster);
sphParticles_.propertyId().updateBoundaries(DataDirection::SlaveToMaster);
if(broadSearch)
{
contactListMangementTimer_.start();
ComputationTimer().start();
ppContactList_().beforeBroadSearch();
pwContactList_().beforeBroadSearch();
ComputationTimer().end();
contactListMangementTimer_.pause();
}
if(broadSearchBoundary)
{
contactListMangementBoundaryTimer_.start();
ComputationTimer().start();
for(uint32 i=0; i<6u; i++)
{
if(activeBoundaries_[i])
{
auto& BI = boundaryInteraction_[i];
BI.ppPairs().beforeBroadSearch();
BI.pwPairs().beforeBroadSearch();
}
}
ComputationTimer().end();
contactListMangementBoundaryTimer_.pause();
}
if( sphParticles_.numActive()<=0)return true;
ComputationTimer().start();
if( !contactSearchRef.broadSearch(
ti,
ppContactList_(),
pwContactList_()) )
{
fatalErrorInFunction<<
"unable to perform broadSearch.\n";
fatalExit;
}
for(uint32 i=0; i<6u; i++)
{
if(activeBoundaries_[i])
{
auto& BI = boundaryInteraction_[i];
if(!contactSearchRef.boundaryBroadSearch(
i,
ti,
BI.ppPairs(),
BI.pwPairs())
)
{
fatalErrorInFunction<<
"failed to perform broadSearch for boundary index "<<i<<endl;
return false;
}
}
}
ComputationTimer().end();
if(broadSearch && contactSearchRef.performedSearch())
{
contactListMangementTimer_.resume();
ComputationTimer().start();
ppContactList_().afterBroadSearch();
pwContactList_().afterBroadSearch();
ComputationTimer().end();
contactListMangementTimer_.end();
}
if(broadSearchBoundary && contactSearchRef.performedSearchBoundary())
{
contactListMangementBoundaryTimer_.resume();
ComputationTimer().start();
for(uint32 i=0; i<6u; i++)
{
if(activeBoundaries_[i])
{
auto& BI = boundaryInteraction_[i];
BI.ppPairs().afterBroadSearch();
BI.pwPairs().afterBroadSearch();
}
}
ComputationTimer().end();
contactListMangementBoundaryTimer_.end();
}
auto requireStep = boundariesMask<6>(true);
const auto& cfModel = this->forceModel_();
uint32 step=1;
boundaryInteractionTimer_.start();
ComputationTimer().start();
while(requireStep.anyElement(true) && step <= 10)
{
for(uint32 i=0; i<6u; i++)
{
if(requireStep[i] )
{
requireStep[i] = boundaryInteraction_[i].sphereSphereInteraction(
dt,
this->forceModel_(),
step
);
}
}
step++;
}
ComputationTimer().end();
boundaryInteractionTimer_.pause();
ppInteractionTimer_.start();
ComputationTimer().start();
sphereSphereInteraction();
ComputationTimer().end();
ppInteractionTimer_.end();
pwInteractionTimer_.start();
ComputationTimer().start();
sphereWallInteraction();
ComputationTimer().start();
pwInteractionTimer_.end();
{
boundaryInteractionTimer_.resume();
ComputationTimer().start();
auto requireStep = boundariesMask<6>(true);
uint32 step = 11;
const auto& cfModel = this->forceModel_();
while( requireStep.anyElement(true) && step < 20 )
{
for(uint32 i=0; i<6u; i++)
{
if(requireStep[i])
{
requireStep[i] = boundaryInteraction_[i].sphereSphereInteraction(
dt,
cfModel,
step
);
}
}
step++;
}
ComputationTimer().end();
boundaryInteractionTimer_.end();
}
return true;
}
template<typename cFM,typename gMM,template <class, class, class> class cLT>
bool pFlow::sphereInteraction<cFM,gMM, cLT>::afterIteration()
{
return true;
}
template<typename cFM,typename gMM,template <class, class, class> class cLT>
bool pFlow::sphereInteraction<cFM,gMM, cLT>::hearChanges
(
real t,
real dt,
uint32 iter,
const message& msg,
const anyList& varList
)
{
if(msg.equivalentTo(message::ITEM_REARRANGE))
{
notImplementedFunction;
}
return true;
}
pFlow::sphereInteraction::sphereWallInteraction
bool sphereWallInteraction()
Definition: sphereInteraction.cpp:85
pFlow::sphereInteractionKernels::ppInteractionFunctor
Definition: sphereInteractionKernels.hpp:33
pFlow::message::equivalentTo
bool equivalentTo(EVENT evnt) const
Definition: message.hpp:131
notImplementedFunction
#define notImplementedFunction
Report that a function is yet not implemented.
Definition: error.hpp:84
pFlow::sphereInteraction::beforeIteration
bool beforeIteration() override
This is called in time loop, before iterate. (overriden from demComponent)
Definition: sphereInteraction.cpp:156
pFlow::message
Definition: message.hpp:33
pFlow::real
float real
Definition: builtinTypes.hpp:45
fatalExit
#define fatalExit
Fatal exit.
Definition: error.hpp:98
pFlow::sphereInteraction::afterIteration
bool afterIteration() override
This is called in time loop, after iterate. (overriden from demComponent)
Definition: sphereInteraction.cpp:337
pFlow::Timer::start
void start()
Definition: Timer.hpp:105
pFlow::sphereInteraction::createSphereInteraction
bool createSphereInteraction()
Definition: sphereInteraction.cpp:22
pFlow::uint32
unsigned int uint32
Definition: builtinTypes.hpp:56
pFlow::sphereInteraction::GeometryMotionModel
geometryMotionModel GeometryMotionModel
Definition: sphereInteraction.hpp:47
pFlow::systemControl
Definition: systemControl.hpp:41
pFlow::endl
iOstream & endl(iOstream &os)
Add newline and flush stream.
Definition: iOstream.hpp:341
pFlow::sphereInteraction::rpPWInteraction
rpPPInteraction rpPWInteraction
range policy for p-w interaction execution
Definition: sphereInteraction.hpp:122
pFlow::sphereInteraction::sphereInteraction
sphereInteraction(systemControl &control, const particles &prtcl, const geometry &geom)
Constructor from components.
Definition: sphereInteraction.cpp:127
pFlow::timeInfo
Definition: timeInfo.hpp:28
pFlow::sphereInteractionKernels::pwInteractionFunctor
Definition: sphereInteractionKernels.hpp:170
pFlow::periodicBoundarySIKernels::sphereSphereInteraction
void sphereSphereInteraction(real dt, const ContactListType &cntctList, const ContactForceModel &forceModel, const realx3 &transferVec, const deviceScatteredFieldAccess< realx3 > &thisPoints, const deviceScatteredFieldAccess< realx3 > &mirrorPoints, const deviceViewType1D< real > &diam, const deviceViewType1D< uint32 > &propId, const deviceViewType1D< realx3 > &vel, const deviceViewType1D< realx3 > &rVel, const deviceViewType1D< realx3 > &cForce, const deviceViewType1D< realx3 > &cTorque)
Definition: periodicBoundarySIKernels.hpp:8
pFlow::VectorSingle::deviceView
INLINE_FUNCTION_H auto deviceView() const
Device view range [0, size)
Definition: VectorSingle.cpp:263
pFlow::sphereParticles
Class for managing spherical particles.
Definition: sphereParticles.hpp:42
pFlow::Timer::end
void end()
Definition: Timer.hpp:129
pFlow::anyList
Definition: anyList.hpp:35
pFlow::particles
Definition: particles.hpp:33
fatalErrorInFunction
#define fatalErrorInFunction
Report a fatal error and function name and exit the application.
Definition: error.hpp:77
pFlow::timeInfo::dt
const real & dt() const
Definition: timeInfo.hpp:51
pFlow::VectorSingle
Definition: VectorSingle.hpp:44
pFlow::boundariesMask< 6 >
pFlow::sphereInteraction::rpPPInteraction
Kokkos::RangePolicy< Kokkos::IndexType< uint32 >, Kokkos::Schedule< Kokkos::Dynamic > > rpPPInteraction
range policy for p-p interaction execution
Definition: sphereInteraction.hpp:119
pFlow::timeInfo::t
const real & t() const
Definition: timeInfo.hpp:47
pFlow::timeInfo::iter
const uint32 & iter() const
Definition: timeInfo.hpp:55
pFlow::geometry
Base class for geometry for managing tri-surfaces, geometry motion, and surface physical properties.
Definition: geometry.hpp:44
pFlow::sphereInteraction::iterate
bool iterate() override
This is called in time loop.
Definition: sphereInteraction.cpp:162
pFlow::sphereInteraction::hearChanges
bool hearChanges(real t, real dt, uint32 iter, const message &msg, const anyList &varList) override
Check for changes in the point structures. (overriden from observer)
Definition: sphereInteraction.cpp:344
pFlow::interaction
Definition: interaction.hpp:38
pFlow::ComputationTimer
MPITimer & ComputationTimer()
Definition: MPITimer.cpp:85
pFlow::sphereInteraction::sphereSphereInteraction
bool sphereSphereInteraction()
Definition: sphereInteraction.cpp:53