Merge pull request #2 from hamidrezanorouzi/MPIdev

Mp idev
This commit is contained in:
Hamidreza Norouzi
2024-05-22 10:08:38 +03:30
committed by GitHub
133 changed files with 2662 additions and 820 deletions

View File

@ -35,12 +35,10 @@ Licence:
#include "commandLine.hpp" #include "commandLine.hpp"
//#include "readControlDict.hpp" //#include "readControlDict.hpp"
using namespace pFlow;
int main( int argc, char* argv[] ) int main( int argc, char* argv[] )
{ {
commandLine cmds( pFlow::commandLine cmds(
"iterateGeometry", "iterateGeometry",
"Performs simulation without particles, only geometry is solved"); "Performs simulation without particles, only geometry is solved");
@ -55,8 +53,8 @@ commandLine cmds(
// this should be palced in each main // this should be palced in each main
processors::initProcessors(argc, argv); pFlow::processors::initProcessors(argc, argv);
initialize_pFlowProcessors(); pFlow::initialize_pFlowProcessors();
#include "initialize_Control.hpp" #include "initialize_Control.hpp"
#include "setProperty.hpp" #include "setProperty.hpp"
@ -71,7 +69,7 @@ initialize_pFlowProcessors();
// this should be palced in each main // this should be palced in each main
#include "finalize.hpp" #include "finalize.hpp"
processors::finalizeProcessors(); pFlow::processors::finalizeProcessors();
} }

View File

@ -20,6 +20,6 @@ Licence:
// //
REPORT(0)<<"\nReading sphere particles . . ."<<END_REPORT; REPORT(0)<<"\nReading sphere particles . . ."<<END_REPORT;
sphereParticles sphParticles(Control, proprties); pFlow::sphereParticles sphParticles(Control, proprties);
WARNING<<"Particle insertion has not been set yet!"<<END_WARNING; WARNING<<"Particle insertion has not been set yet!"<<END_WARNING;

View File

@ -36,7 +36,7 @@ Licence:
#include "systemControl.hpp" #include "systemControl.hpp"
#include "commandLine.hpp" #include "commandLine.hpp"
using namespace pFlow;
/** /**
* DEM solver for simulating granular flow of cohesion-less particles. * DEM solver for simulating granular flow of cohesion-less particles.
@ -47,7 +47,7 @@ using namespace pFlow;
int main( int argc, char* argv[]) int main( int argc, char* argv[])
{ {
commandLine cmds( pFlow::commandLine cmds(
"sphereGranFlow", "sphereGranFlow",
"DEM solver for non-cohesive spherical particles with particle insertion " "DEM solver for non-cohesive spherical particles with particle insertion "
"mechanism and moving geometry"); "mechanism and moving geometry");
@ -57,8 +57,8 @@ bool isCoupling = false;
if(!cmds.parse(argc, argv)) return 0; if(!cmds.parse(argc, argv)) return 0;
// this should be palced in each main // this should be palced in each main
processors::initProcessors(argc, argv); pFlow::processors::initProcessors(argc, argv);
initialize_pFlowProcessors(); pFlow::initialize_pFlowProcessors();
#include "initialize_Control.hpp" #include "initialize_Control.hpp"
#include "setProperty.hpp" #include "setProperty.hpp"
@ -82,7 +82,7 @@ initialize_pFlowProcessors();
// this should be palced in each main // this should be palced in each main
#include "finalize.hpp" #include "finalize.hpp"
processors::finalizeProcessors(); pFlow::processors::finalizeProcessors();
} }

View File

@ -20,7 +20,7 @@ Licence:
// //
REPORT(0)<<"\nReading sphere particles . . ."<<END_REPORT; REPORT(0)<<"\nReading sphere particles . . ."<<END_REPORT;
sphereParticles sphParticles(Control, proprties); pFlow::sphereParticles sphParticles(Control, proprties);
// //
REPORT(0)<<"\nCreating particle insertion object . . ."<<END_REPORT; REPORT(0)<<"\nCreating particle insertion object . . ."<<END_REPORT;
@ -36,12 +36,12 @@ REPORT(0)<<"\nCreating particle insertion object . . ."<<END_REPORT;
sphParticles.shapes() sphParticles.shapes()
);*/ );*/
auto sphInsertion = sphereInsertion( auto sphInsertion = pFlow::sphereInsertion(
sphParticles, sphParticles,
sphParticles.spheres()); sphParticles.spheres());
REPORT(0)<<"\nCreating interaction model for sphere-sphere contact and sphere-wall contact . . ."<<END_REPORT; REPORT(0)<<"\nCreating interaction model for sphere-sphere contact and sphere-wall contact . . ."<<END_REPORT;
auto interactionPtr = interaction::create( auto interactionPtr = pFlow::interaction::create(
Control, Control,
sphParticles, sphParticles,
surfGeometry surfGeometry

View File

@ -40,12 +40,8 @@ Licence:
#include "interaction.hpp" #include "interaction.hpp"
#include "Insertions.hpp" #include "Insertions.hpp"
//#include "readControlDict.hpp" //#include "readControlDict.hpp"
using namespace pFlow;
/** /**
* DEM solver for simulating granular flow of cohesion-less particles. * DEM solver for simulating granular flow of cohesion-less particles.
* *
@ -55,7 +51,7 @@ using namespace pFlow;
int main( int argc, char* argv[]) int main( int argc, char* argv[])
{ {
commandLine cmds( pFlow::commandLine cmds(
"sphereGranFlow", "sphereGranFlow",
"DEM solver for non-cohesive spherical particles with particle insertion " "DEM solver for non-cohesive spherical particles with particle insertion "
"mechanism and moving geometry"); "mechanism and moving geometry");
@ -65,13 +61,12 @@ bool isCoupling = false;
if(!cmds.parse(argc, argv)) return 0; if(!cmds.parse(argc, argv)) return 0;
// this should be palced in each main // this should be palced in each main
processors::initProcessors(argc, argv); pFlow::processors::initProcessors(argc, argv);
initialize_pFlowProcessors(); pFlow::initialize_pFlowProcessors();
#include "initialize_Control.hpp" #include "initialize_Control.hpp"
#include "setProperty.hpp" #include "setProperty.hpp"
#include "setSurfaceGeometry.hpp" #include "setSurfaceGeometry.hpp"
#include "createDEMComponents.hpp" #include "createDEMComponents.hpp"
@ -117,7 +112,7 @@ initialize_pFlowProcessors();
// this should be palced in each main // this should be palced in each main
#include "finalize.hpp" #include "finalize.hpp"
processors::finalizeProcessors(); pFlow::processors::finalizeProcessors();
} }

View File

@ -249,7 +249,9 @@ pFlow::geometry::geometry
if( this->numSurfaces() != motionComponentName_.size() ) if( this->numSurfaces() != motionComponentName_.size() )
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Number of surfaces is not equal to number of motion component names"<<endl; "Number of surfaces ("<< this->numSurfaces() <<
") is not equal to number of motion component names("<<
motionComponentName_.size()<<")"<<endl;
fatalExit; fatalExit;
} }

View File

@ -1,4 +1,3 @@
#include "geometryMotion.hpp"
/*------------------------------- phasicFlow --------------------------------- /*------------------------------- phasicFlow ---------------------------------
O C enter of O C enter of
O O E ngineering and O O E ngineering and
@ -70,6 +69,28 @@ bool pFlow::geometryMotion<MotionModel>::findMotionIndex()
return true; return true;
} }
namespace pFlow::GMotion
{
template<typename ModelInterface>
void moveGeometry(
real dt,
uint32 nPoints,
const ModelInterface& mModel,
const deviceViewType1D<uint32>& pointMIndexD,
const deviceViewType1D<realx3>& pointsD
)
{
Kokkos::parallel_for(
"geometryMotion<MotionModel>::movePoints",
deviceRPolicyStatic(0, nPoints),
LAMBDA_HD(uint32 i){
auto newPos = mModel.transferPoint(pointMIndexD[i], pointsD[i], dt);
pointsD[i] = newPos;
});
Kokkos::fence();
}
}
template<typename MotionModel> template<typename MotionModel>
bool pFlow::geometryMotion<MotionModel>::moveGeometry() bool pFlow::geometryMotion<MotionModel>::moveGeometry()
@ -84,8 +105,15 @@ template<typename MotionModel>
auto& pointMIndexD= pointMotionIndex_.deviceViewAll(); auto& pointMIndexD= pointMotionIndex_.deviceViewAll();
auto& pointsD = points().deviceViewAll(); auto& pointsD = points().deviceViewAll();
pFlow::GMotion::moveGeometry(
dt,
numPoints(),
motionModel_.getModelInterface(iter, t, dt),
pointMotionIndex_.deviceViewAll(),
points().deviceViewAll()
);
Kokkos::parallel_for( /*Kokkos::parallel_for(
"geometryMotion<MotionModel>::movePoints", "geometryMotion<MotionModel>::movePoints",
deviceRPolicyStatic(0, numPoints()), deviceRPolicyStatic(0, numPoints()),
LAMBDA_HD(uint32 i){ LAMBDA_HD(uint32 i){
@ -93,7 +121,7 @@ template<typename MotionModel>
pointsD[i] = newPos; pointsD[i] = newPos;
}); });
Kokkos::fence(); Kokkos::fence();*/
// move the motion components // move the motion components
motionModel_.move(iter, t,dt); motionModel_.move(iter, t,dt);

View File

@ -7,8 +7,8 @@ contactSearch/methods/cellBased/NBS/NBS.cpp
contactSearch/methods/cellBased/NBS/cellsWallLevel0.cpp contactSearch/methods/cellBased/NBS/cellsWallLevel0.cpp
contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp
contactSearch/boundaries/twoPartContactSearch/twoPartContactSearchKernels.cpp #contactSearch/boundaries/twoPartContactSearch/twoPartContactSearchKernels.cpp
contactSearch/boundaries/twoPartContactSearch/twoPartContactSearch.cpp #contactSearch/boundaries/twoPartContactSearch/twoPartContactSearch.cpp
contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.cpp contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.cpp
contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearch.cpp contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearch.cpp
contactSearch/boundaries/periodicBoundaryContactSearch/wallBoundaryContactSearch.cpp contactSearch/boundaries/periodicBoundaryContactSearch/wallBoundaryContactSearch.cpp

View File

@ -138,7 +138,7 @@ public:
start, start,
end, end,
newPair); newPair);
idx0!=-1) idx0!=static_cast<uint32>(-1))
{ {
values_[idx] = values0_[idx0]; values_[idx] = values0_[idx0];
} }
@ -147,7 +147,7 @@ public:
start, start,
end, end,
newPair); newPair);
idx0!=-1) idx0!= static_cast<uint32>(-1) )
{ {
values_[idx] = values0_[idx0]; values_[idx] = values0_[idx0];

View File

@ -95,7 +95,8 @@ public:
// swap conainer and values // swap conainer and values
swapViews(values0_, values_); swapViews(values0_, values_);
swapViews(container0_, this->container_); swapViews(container0_, this->container_);
return UnsortedPairs::beforeBroadSearch(); UnsortedPairs::beforeBroadSearch();
return true;
} }
bool afterBroadSearch() bool afterBroadSearch()
@ -110,7 +111,7 @@ public:
rpFillPairs(0,this->capacity()), rpFillPairs(0,this->capacity()),
*this); *this);
Kokkos::fence(); Kokkos::fence();
return true; return true;
} }
@ -123,7 +124,7 @@ public:
INLINE_FUNCTION_HD INLINE_FUNCTION_HD
bool getValue(const PairType& p, ValueType& val)const bool getValue(const PairType& p, ValueType& val)const
{ {
if(auto idx = this->find(p); idx!=-1) if(auto idx = this->find(p); idx!=static_cast<uint32>(-1))
{ {
val = getValue(idx); val = getValue(idx);
return true; return true;
@ -140,7 +141,7 @@ public:
INLINE_FUNCTION_HD INLINE_FUNCTION_HD
bool setValue(const PairType& p, const ValueType& val)const bool setValue(const PairType& p, const ValueType& val)const
{ {
if(uint32 idx = this->find(p); idx!=-1) if(uint32 idx = this->find(p); idx!=static_cast<uint32>(-1))
{ {
setValue(idx, val); setValue(idx, val);
return true;; return true;;
@ -155,7 +156,7 @@ public:
{ {
if( uint32 idx0 = if( uint32 idx0 =
container0_.find(this->getPair(idx)); container0_.find(this->getPair(idx));
idx0!=-1 ) idx0!= static_cast<uint32>(-1) )
{ {
values_[idx] = values0_[idx0]; values_[idx] = values0_[idx0];
} }

View File

@ -105,7 +105,7 @@ public:
uint32 insert(idType i, idType j)const uint32 insert(idType i, idType j)const
{ {
if(auto insertResult = container_.insert(PairType(i,j)); insertResult.failed()) if(auto insertResult = container_.insert(PairType(i,j)); insertResult.failed())
return -1; return static_cast<uint32>(-1);
else else
return insertResult.index(); return insertResult.index();
@ -115,7 +115,7 @@ public:
uint32 insert(const PairType& p)const uint32 insert(const PairType& p)const
{ {
if(auto insertResult = container_.insert(p); insertResult.failed()) if(auto insertResult = container_.insert(p); insertResult.failed())
return -1; return static_cast<uint32>(-1);
else else
return insertResult.index(); return insertResult.index();
@ -154,7 +154,7 @@ public:
idx != Kokkos::UnorderedMapInvalidIndex ) idx != Kokkos::UnorderedMapInvalidIndex )
return idx; return idx;
else else
return -1; return static_cast<uint32>(-1);
} }
INLINE_FUNCTION_HD INLINE_FUNCTION_HD

View File

@ -76,10 +76,6 @@ public:
*this) *this)
{ {
/*auto method = dict().getVal<word>("method");
auto nbDict = dict().subDict(method+"Info");*/
real minD; real minD;
real maxD; real maxD;
this->Particles().boundingSphereMinMax(minD, maxD); this->Particles().boundingSphereMinMax(minD, maxD);
@ -110,9 +106,6 @@ public:
wVertices, wVertices,
wNormals wNormals
); );
REPORT(2)<<"Contact search algorithm for particle-particle is "<<
Green_Text(ppwContactSearch_().typeName())<<END_REPORT;
} }
@ -167,7 +160,8 @@ public:
csPairContainerType& pwPairs, csPairContainerType& pwPairs,
bool force = false)override bool force = false)override
{ {
Particles().boundingSphere().updateBoundaries(DataDirection::SlaveToMaster); if(i==0u)
Particles().boundingSphere().updateBoundaries(DataDirection::SlaveToMaster);
return csBoundaries_[i].broadSearch( return csBoundaries_[i].broadSearch(
iter, iter,
t, t,
@ -190,6 +184,23 @@ public:
{ {
return ppwContactSearch_().performedSearch(); return ppwContactSearch_().performedSearch();
} }
uint32 updateInterval()const override
{
return ppwContactSearch_().updateInterval();
}
real sizeRatio()const override
{
return ppwContactSearch_().sizeRatio();
}
real cellExtent()const override
{
return ppwContactSearch_().cellExtent();
}
}; };

View File

@ -50,13 +50,13 @@ pFlow::boundaryContactSearch::create(
if( boundaryBasevCtorSelector_.search(bType) ) if( boundaryBasevCtorSelector_.search(bType) )
{ {
REPORT(2)<<"Creating contact search boundary "<< Green_Text(bType)<< pOutput.space(4)<<"Creating contact search boundary "<< Green_Text(bType)<<
" for "<<boundary.name()<<endl; " for "<<boundary.name()<<endl;
return boundaryBasevCtorSelector_[bType](dict, boundary, cSearch); return boundaryBasevCtorSelector_[bType](dict, boundary, cSearch);
} }
else if(boundaryBasevCtorSelector_.search(altBType)) else if(boundaryBasevCtorSelector_.search(altBType))
{ {
REPORT(2)<<"Creating contact search boundary "<< Green_Text(altBType)<< pOutput.space(4)<<"Creating contact search boundary "<< Green_Text(altBType)<<
" for "<<boundary.name()<<endl; " for "<<boundary.name()<<endl;
return boundaryBasevCtorSelector_[altBType](dict, boundary, cSearch); return boundaryBasevCtorSelector_[altBType](dict, boundary, cSearch);
} }

View File

@ -72,11 +72,6 @@ public:
return contactSearch_; return contactSearch_;
} }
void fill(const std::any &val) override
{
return;
}
bool hearChanges( bool hearChanges(
real t, real t,
real dt, real dt,

View File

@ -80,14 +80,14 @@ pFlow::uint32 pFlow::pweBndryContactSearchKernels::broadSearchPP
if(!searchCells.inCellRange(ind))continue; if(!searchCells.inCellRange(ind))continue;
uint32 thisI = head(ind.x(),ind.y(),ind.z()); uint32 thisI = head(ind.x(),ind.y(),ind.z());
while (thisI!=-1) while (thisI!=static_cast<uint32>(-1))
{ {
auto d_n = sizeRatio*diams[thisI]; auto d_n = sizeRatio*diams[thisI];
// first item is for this boundary and second itme, for mirror // first item is for this boundary and second itme, for mirror
if(sphereSphereCheckB(p_m, points[thisI], d_m, d_n)&& if(sphereSphereCheckB(p_m, points[thisI], d_m, d_n)&&
ppPairs.insert(thisI,mrrI) == -1) ppPairs.insert(thisI,mrrI) == static_cast<uint32>(-1))
{ {
getFullUpdate++; getFullUpdate++;
} }

View File

@ -113,7 +113,10 @@ pFlow::uint32 pFlow::wallBoundaryContactSearch::findPairsElementRangeCount
uint32 nNotInserted = 0; uint32 nNotInserted = 0;
uint32 nThis = pPoints.size(); uint32 nThis = pPoints.size();
const auto& numElements = numElements_;
const auto& elementBox = elementBox_;
const auto& validBox = validBox_;
Kokkos::parallel_reduce( Kokkos::parallel_reduce(
"pFlow::wallBoundaryContactSearch::findPairsElementRangeCount", "pFlow::wallBoundaryContactSearch::findPairsElementRangeCount",
deviceRPolicyDynamic(0,nThis), deviceRPolicyDynamic(0,nThis),
@ -123,11 +126,11 @@ pFlow::uint32 pFlow::wallBoundaryContactSearch::findPairsElementRangeCount
int32x3 ind; int32x3 ind;
if( searchCells.pointIndexInDomain(p, ind) ) if( searchCells.pointIndexInDomain(p, ind) )
{ {
for(uint32 nTri=0; nTri<numElements_; nTri++) for(uint32 nTri=0; nTri<numElements; nTri++)
{ {
if( validBox_[nTri]== 0)continue; if( validBox[nTri]== 0)continue;
if( elementBox_[nTri].isInside(ind)&& if( elementBox[nTri].isInside(ind)&&
pairs.insert(i,nTri+baseTriIndex) == -1) pairs.insert(i,nTri+baseTriIndex) == static_cast<uint32>(-1))
{ {
notInsertedUpdate++; notInsertedUpdate++;
} }

View File

@ -52,7 +52,8 @@ pFlow::processorBoundaryContactSearch::processorBoundaryContactSearch(
: :
boundaryContactSearch(dict, boundary, cSearch), boundaryContactSearch(dict, boundary, cSearch),
diameter_(cSearch.Particles().boundingSphere()), diameter_(cSearch.Particles().boundingSphere()),
masterSearch_(this->isBoundaryMaster()) masterSearch_(this->isBoundaryMaster()),
sizeRatio_(dict.getVal<real>("sizeRatio"))
{ {
if(masterSearch_) if(masterSearch_)
@ -65,7 +66,8 @@ pFlow::processorBoundaryContactSearch::processorBoundaryContactSearch(
ppContactSearch_ = makeUnique<twoPartContactSearch>( ppContactSearch_ = makeUnique<twoPartContactSearch>(
searchBox_, searchBox_,
maxD); maxD,
sizeRatio_);
} }
else else
{ {
@ -96,7 +98,8 @@ bool pFlow::processorBoundaryContactSearch::broadSearch
thisPoints, thisPoints,
thisDiams, thisDiams,
neighborProcPoints, neighborProcPoints,
neighborProcDiams neighborProcDiams,
name()
); );
//pOutput<<"ppSize "<< ppPairs.size()<<endl; //pOutput<<"ppSize "<< ppPairs.size()<<endl;
return true; return true;

View File

@ -39,6 +39,8 @@ private:
bool masterSearch_; bool masterSearch_;
real sizeRatio_;
void setSearchBox(); void setSearchBox();
public: public:

View File

@ -64,7 +64,9 @@ bool pFlow::twoPartContactSearch::broadSearchPP
const realx3& transferVec const realx3& transferVec
) )
{ {
if(points1.empty())return true;
if(points2.empty()) return true;
buildList(points1); buildList(points1);
uint32 nNotInserted = 1; uint32 nNotInserted = 1;
@ -114,7 +116,8 @@ bool pFlow::twoPartContactSearch::broadSearchPP
const deviceScatteredFieldAccess<realx3> &points1, const deviceScatteredFieldAccess<realx3> &points1,
const deviceScatteredFieldAccess<real> &diams1, const deviceScatteredFieldAccess<real> &diams1,
const realx3Vector_D& points2, const realx3Vector_D& points2,
const realVector_D& diams2 const realVector_D& diams2,
const word& name
) )
{ {
buildList(points1); buildList(points1);
@ -148,9 +151,9 @@ bool pFlow::twoPartContactSearch::broadSearchPP
auto oldCap = ppPairs.capacity(); auto oldCap = ppPairs.capacity();
ppPairs.increaseCapacityBy(len); ppPairs.increaseCapacityBy(len);
INFORMATION<< "Particle-particle contact pair container capacity increased from "<< INFORMATION<< "Particle-particle contact pair container capacity increased from "<<
oldCap << " to "<<ppPairs.capacity()<<" in peiodicBoundaryContactSearch."<<END_INFO; oldCap << " to "<<ppPairs.capacity()<<" in boundary contact search in "<< name <<END_INFO;
} }

View File

@ -85,7 +85,8 @@ public:
const deviceScatteredFieldAccess<realx3> &points1, const deviceScatteredFieldAccess<realx3> &points1,
const deviceScatteredFieldAccess<real> &diams1, const deviceScatteredFieldAccess<real> &diams1,
const realx3Vector_D& points2, const realx3Vector_D& points2,
const realVector_D& diams2); const realVector_D& diams2,
const word& name);
const auto& searchCells()const const auto& searchCells()const
{ {

View File

@ -20,9 +20,7 @@ pFlow::twoPartContactSearchKernels::buildNextHead(
deviceViewType1D<uint32>& next deviceViewType1D<uint32>& next
) )
{ {
if (points.empty())
return;
uint32 n = points.size(); uint32 n = points.size();
Kokkos::parallel_for( Kokkos::parallel_for(
@ -89,14 +87,14 @@ pFlow::twoPartContactSearchKernels::broadSearchPP(
continue; continue;
uint32 thisI = head(ind.x(), ind.y(), ind.z()); uint32 thisI = head(ind.x(), ind.y(), ind.z());
while (thisI != -1) while (thisI != static_cast<uint32>(-1))
{ {
auto d_n = sizeRatio * diams[thisI]; auto d_n = sizeRatio * diams[thisI];
// first item is for this boundary and second itme, // first item is for this boundary and second itme,
// for mirror // for mirror
if(sphereSphereCheckB(p_m, points[thisI], d_m, d_n)&& if(sphereSphereCheckB(p_m, points[thisI], d_m, d_n)&&
ppPairs.insert(thisI,mrrI) == -1) ppPairs.insert(thisI,mrrI) == static_cast<uint32>(-1))
{ {
getFullUpdate++; getFullUpdate++;
} }
@ -163,14 +161,14 @@ pFlow::twoPartContactSearchKernels::broadSearchPP(
} }
uint32 i1 = head(ind.x(), ind.y(), ind.z()); uint32 i1 = head(ind.x(), ind.y(), ind.z());
while (i1 != -1) while (i1 != static_cast<uint32>(-1))
{ {
auto d_n = sizeRatio * diams1[i1]; auto d_n = sizeRatio * diams1[i1];
// first item is for this boundary and second itme, // first item is for this boundary and second itme,
// for mirror // for mirror
if(sphereSphereCheckB(p_m, points1[i1], d_m, d_n)&& if(sphereSphereCheckB(p_m, points1[i1], d_m, d_n)&&
ppPairs.insert(i1,i2) == -1) ppPairs.insert(i1,i2) == static_cast<uint32>(-1))
{ {
getFullUpdate++; getFullUpdate++;
} }

View File

@ -55,13 +55,11 @@ pFlow::uniquePtr<pFlow::contactSearch> pFlow::contactSearch::create(
word baseMethName = dict.getVal<word>("method"); word baseMethName = dict.getVal<word>("method");
auto model = angleBracketsNames("ContactSearch", baseMethName); auto model = angleBracketsNames("ContactSearch", baseMethName);
REPORT(1)<<"Selecting contact search model . . ."<<END_REPORT;
pOutput.space(2)<<"Selecting contact search model "<<Green_Text(model)<<endl;
if( dictionaryvCtorSelector_.search(model)) if( dictionaryvCtorSelector_.search(model))
{ {
auto objPtr = dictionaryvCtorSelector_[model] (dict, extDomain, prtcl, geom, timers); auto objPtr = dictionaryvCtorSelector_[model] (dict, extDomain, prtcl, geom, timers);
REPORT(2)<<"Model "<< Green_Text(model)<<" is created."<< END_REPORT;
return objPtr; return objPtr;
} }
else else

View File

@ -140,6 +140,15 @@ public:
virtual virtual
bool performedBroadSearch()const = 0; bool performedBroadSearch()const = 0;
virtual
uint32 updateInterval()const = 0;
virtual
real sizeRatio()const = 0;
virtual
real cellExtent()const = 0;
static static
uniquePtr<contactSearch> create( uniquePtr<contactSearch> create(
const dictionary& dict, const dictionary& dict,

View File

@ -134,6 +134,16 @@ public:
{ {
return 1; return 1;
} }
real sizeRatio()const
{
return sizeRatio_;
}
real cellExtent()const
{
return cellExtent_;
}
auto getCellIterator([[maybe_unused]] uint32 lvl)const auto getCellIterator([[maybe_unused]] uint32 lvl)const
{ {

View File

@ -43,7 +43,7 @@ while( m != mapperNBS::NoPos)
auto lm = m; auto lm = m;
if(lm>ln) Swap(lm,ln); if(lm>ln) Swap(lm,ln);
if( pairs.insert(lm,ln) == -1) if( pairs.insert(lm,ln) == static_cast<uint32>(-1))
{ {
getFullUpdate++; getFullUpdate++;
} }
@ -86,7 +86,7 @@ while( m != mapperNBS::NoPos)
auto ln = n; auto ln = n;
auto lm = m; auto lm = m;
if(lm>ln) Swap(lm,ln); if(lm>ln) Swap(lm,ln);
if( pairs.insert(lm,ln) == -1) if( pairs.insert(lm,ln) == static_cast<uint32>(-1))
{ {
getFullUpdate++; getFullUpdate++;
} }

View File

@ -85,21 +85,26 @@ bool pFlow::cellsWallLevel0::broadSearch
bool pFlow::cellsWallLevel0::build(const cells & searchBox) bool pFlow::cellsWallLevel0::build(const cells & searchBox)
{ {
const auto& points = points_;
const auto& vertices = vertices_;
const auto& elementBox = elementBox_;
const auto cellExtent = cellExtent_;
Kokkos::parallel_for( Kokkos::parallel_for(
"pFlow::cellsWallLevel0::build", "pFlow::cellsWallLevel0::build",
deviceRPolicyStatic(0,numElements_), deviceRPolicyStatic(0,numElements_),
CLASS_LAMBDA_HD(uint32 i) LAMBDA_HD(uint32 i)
{ {
auto v = vertices_[i]; auto v = vertices[i];
auto p1 = points_[v.x()]; auto p1 = points[v.x()];
auto p2 = points_[v.y()]; auto p2 = points[v.y()];
auto p3 = points_[v.z()]; auto p3 = points[v.z()];
realx3 minP; realx3 minP;
realx3 maxP; realx3 maxP;
searchBox.extendBox(p1, p2, p3, cellExtent_, minP, maxP); searchBox.extendBox(p1, p2, p3, cellExtent, minP, maxP);
elementBox_[i] = iBoxType(searchBox.pointIndex(minP), searchBox.pointIndex(maxP)); elementBox[i] = iBoxType(searchBox.pointIndex(minP), searchBox.pointIndex(maxP));
}); });
Kokkos::fence(); Kokkos::fence();
@ -153,7 +158,12 @@ pFlow::int32 pFlow::cellsWallLevel0::findPairsElementRangeCount
{ {
uint32 getFull =0; uint32 getFull =0;
const auto& elementBox = elementBox_;
const auto& normals = normals_;
const auto& points = points_;
const auto& vertices = vertices_;
const auto cellExtent = cellExtent_;
Kokkos::parallel_reduce( Kokkos::parallel_reduce(
"pFlow::cellsWallLevel0::findPairsElementRangeCount", "pFlow::cellsWallLevel0::findPairsElementRangeCount",
tpPWContactSearch(numElements_, Kokkos::AUTO), tpPWContactSearch(numElements_, Kokkos::AUTO),
@ -163,10 +173,10 @@ pFlow::int32 pFlow::cellsWallLevel0::findPairsElementRangeCount
const uint32 iTri = teamMember.league_rank(); const uint32 iTri = teamMember.league_rank();
const auto triBox = elementBox_[iTri]; const auto triBox = elementBox[iTri];
const auto triPlane = infinitePlane( const auto triPlane = infinitePlane(
normals_[iTri], normals[iTri],
points_[vertices_[iTri].x()]); points[vertices[iTri].x()]);
uint32 getFull2 = 0; uint32 getFull2 = 0;
@ -186,11 +196,12 @@ pFlow::int32 pFlow::cellsWallLevel0::findPairsElementRangeCount
while( n != particleMap.NoPos) while( n != particleMap.NoPos)
{ {
// id is wall id the pair is (particle id, wall id) // id is wall id the pair is (particle id, wall id)
if( abs(triPlane.pointFromPlane(pPoints[n]))< pDiams[n]*sizeRatio*cellExtent_) if( abs(triPlane.pointFromPlane(pPoints[n]))< pDiams[n]*sizeRatio*cellExtent)
{ {
if( pairs.insert( if( pairs.insert(
static_cast<csIdType>(n), static_cast<csIdType>(n),
static_cast<csIdType>(iTri) ) == -1 ) static_cast<csIdType>(iTri) ) == static_cast<csIdType>(-1)
)
innerUpdate++; innerUpdate++;
} }
n = particleMap.next(n); n = particleMap.next(n);

View File

@ -113,6 +113,21 @@ public:
return false; return false;
} }
uint32 updateInterval()const
{
return updateInterval_;
}
real sizeRatio()const
{
return getMethod().sizeRatio();
}
real cellExtent()const
{
return getMethod().cellExtent();
}
}; };

View File

@ -71,15 +71,14 @@ pFlow::uniquePtr<pFlow::interaction> pFlow::interaction::create
clType); clType);
gSettings::sleepMiliSeconds(
REPORT(1)<<"Creating interaction "<<Green_Text(interactionModel)<<" . . ."<<END_REPORT; 100*(pFlowProcessors().localSize()-pFlowProcessors().localRank()-1));
pOutput.space(2)<<"Creating interaction "<<Green_Text(interactionModel)<<" . . ."<<END_REPORT;
if( systemControlvCtorSelector_.search(interactionModel) ) if( systemControlvCtorSelector_.search(interactionModel) )
{ {
auto objPtr = auto objPtr =
systemControlvCtorSelector_[interactionModel] systemControlvCtorSelector_[interactionModel]
(control, prtcl, geom); (control, prtcl, geom);
return objPtr; return objPtr;
} }
else else

View File

@ -1,3 +1,4 @@
#include "boundarySphereInteraction.hpp"
/*------------------------------- phasicFlow --------------------------------- /*------------------------------- phasicFlow ---------------------------------
O C enter of O C enter of
O O E ngineering and O O E ngineering and
@ -18,6 +19,20 @@ Licence:
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
template <typename cFM, typename gMM>
void pFlow::boundarySphereInteraction<cFM, gMM>::allocatePPPairs()
{
ppPairs_.reset(nullptr);
ppPairs_ = makeUnique<ContactListType>(1);
}
template <typename cFM, typename gMM>
void pFlow::boundarySphereInteraction<cFM, gMM>::allocatePWPairs()
{
pwPairs_.reset(nullptr);
pwPairs_ = makeUnique<ContactListType>(1);
}
template <typename cFM, typename gMM> template <typename cFM, typename gMM>
pFlow::boundarySphereInteraction<cFM, gMM>::boundarySphereInteraction( pFlow::boundarySphereInteraction<cFM, gMM>::boundarySphereInteraction(
@ -28,8 +43,6 @@ pFlow::boundarySphereInteraction<cFM, gMM>::boundarySphereInteraction(
geometryMotion_(geomMotion), geometryMotion_(geomMotion),
sphParticles_(sphPrtcls) sphParticles_(sphPrtcls)
{ {
ppPairs_ = makeUnique<ContactListType>(1);
pwPairs_ = makeUnique<ContactListType>(1);
} }
template <typename cFM, typename gMM> template <typename cFM, typename gMM>
@ -56,7 +69,7 @@ pFlow::boundarySphereInteraction<cFM, gMM>::create(
if (boundaryBasevCtorSelector_.search(boundaryTypeName)) if (boundaryBasevCtorSelector_.search(boundaryTypeName))
{ {
REPORT(2) << "Creating boundry type " << Green_Text(boundaryTypeName) << pOutput.space(4) << "Creating boundry type " << Green_Text(boundaryTypeName) <<
" for boundary " << boundary.name() << " . . ." << END_REPORT; " for boundary " << boundary.name() << " . . ." << END_REPORT;
return boundaryBasevCtorSelector_[boundaryTypeName]( return boundaryBasevCtorSelector_[boundaryTypeName](
boundary, boundary,
@ -67,7 +80,7 @@ pFlow::boundarySphereInteraction<cFM, gMM>::create(
{ {
// if boundary condition is not implemented, the default is used // if boundary condition is not implemented, the default is used
REPORT(2) << "Creating boundry type " << Green_Text(altBTypeName) << pOutput.space(4) << "Creating boundry type " << Green_Text(altBTypeName) <<
" for boundary " << boundary.name() << " . . ." << END_REPORT; " for boundary " << boundary.name() << " . . ." << END_REPORT;
return boundaryBasevCtorSelector_[altBTypeName]( return boundaryBasevCtorSelector_[altBTypeName](
boundary, boundary,

View File

@ -22,7 +22,7 @@ Licence:
#include "virtualConstructor.hpp" #include "virtualConstructor.hpp"
#include "generalBoundary.hpp" #include "generalBoundary.hpp"
#include "unsortedContactList.hpp" #include "sortedContactList.hpp"
#include "sphereParticles.hpp" #include "sphereParticles.hpp"
namespace pFlow namespace pFlow
@ -51,7 +51,7 @@ public:
using IndexType = uint32; using IndexType = uint32;
using ContactListType = using ContactListType =
unsortedContactList<ModelStorage, DefaultExecutionSpace, IdType>; sortedContactList<ModelStorage, DefaultExecutionSpace, IdType>;
private: private:
@ -60,9 +60,15 @@ private:
/// const reference to sphere particles /// const reference to sphere particles
const sphereParticles& sphParticles_; const sphereParticles& sphParticles_;
uniquePtr<ContactListType> ppPairs_; uniquePtr<ContactListType> ppPairs_ = nullptr;
uniquePtr<ContactListType> pwPairs_; uniquePtr<ContactListType> pwPairs_ = nullptr;
protected:
void allocatePPPairs();
void allocatePWPairs();
public: public:
@ -124,15 +130,30 @@ public:
return pwPairs_(); return pwPairs_();
} }
bool ppPairsAllocated()const
{
if( ppPairs_)return true;
return false;
}
bool pwPairsAllocated()const
{
if( pwPairs_)return true;
return false;
}
virtual virtual
bool sphereSphereInteraction( bool sphereSphereInteraction(
real dt, real dt,
const ContactForceModel& cfModel) const ContactForceModel& cfModel,
uint32 step)
{ {
// for default boundary, no thing to be done // for default boundary, no thing to be done
return true; return false;
} }
bool hearChanges bool hearChanges
( (
real t, real t,
@ -149,11 +170,6 @@ public:
return true; return true;
} }
void fill(const std::any& val)override
{
notImplementedFunction;
}
static static
uniquePtr<BoundarySphereInteractionType> create( uniquePtr<BoundarySphereInteractionType> create(
const boundaryBase& boundary, const boundaryBase& boundary,

View File

@ -10,7 +10,7 @@ pFlow::boundarySphereInteractionList<CFModel, gMModel>::boundarySphereInteractio
ListPtr<boundarySphereInteraction<CFModel,gMModel>>(6), ListPtr<boundarySphereInteraction<CFModel,gMModel>>(6),
boundaries_(sphPrtcls.pStruct().boundaries()) boundaries_(sphPrtcls.pStruct().boundaries())
{ {
//gSettings::sleepMiliSeconds(1000*pFlowProcessors().localRank());
for(uint32 i=0; i<6; i++) for(uint32 i=0; i<6; i++)
{ {
this->set( this->set(

View File

@ -30,7 +30,10 @@ pFlow::periodicBoundarySphereInteraction<cFM, gMM>::periodicBoundarySphereIntera
{ {
if(boundary.thisBoundaryIndex()%2==1) if(boundary.thisBoundaryIndex()%2==1)
{ {
masterInteraction_ = true; masterInteraction_ = true;
this->allocatePPPairs();
this->allocatePWPairs();
} }
else else
{ {
@ -42,10 +45,11 @@ template <typename cFM, typename gMM>
bool pFlow::periodicBoundarySphereInteraction<cFM, gMM>::sphereSphereInteraction bool pFlow::periodicBoundarySphereInteraction<cFM, gMM>::sphereSphereInteraction
( (
real dt, real dt,
const ContactForceModel &cfModel const ContactForceModel &cfModel,
uint32 step
) )
{ {
if(!masterInteraction_) return true; if(!masterInteraction_) return false;
pFlow::periodicBoundarySIKernels::sphereSphereInteraction( pFlow::periodicBoundarySIKernels::sphereSphereInteraction(
dt, dt,
@ -61,5 +65,5 @@ bool pFlow::periodicBoundarySphereInteraction<cFM, gMM>::sphereSphereInteraction
this->sphParticles().contactForce().deviceViewAll(), this->sphParticles().contactForce().deviceViewAll(),
this->sphParticles().contactTorque().deviceViewAll()); this->sphParticles().contactTorque().deviceViewAll());
return true; return false;
} }

View File

@ -83,7 +83,8 @@ public:
bool sphereSphereInteraction( bool sphereSphereInteraction(
real dt, real dt,
const ContactForceModel& cfModel)override; const ContactForceModel& cfModel,
uint32 step)override;
}; };

View File

@ -32,42 +32,126 @@ pFlow::MPI::processorBoundarySphereInteraction<cFM, gMM>::processorBoundarySpher
geomMotion geomMotion
), ),
masterInteraction_(boundary.isBoundaryMaster()) masterInteraction_(boundary.isBoundaryMaster())
{} ,
inter_("inter"),
send_("send"),
recv_("recv"),
add_("add")
{
if(masterInteraction_)
{
this->allocatePPPairs();
this->allocatePWPairs();
}
}
template <typename cFM, typename gMM> template <typename cFM, typename gMM>
bool pFlow::MPI::processorBoundarySphereInteraction<cFM, gMM>::sphereSphereInteraction bool pFlow::MPI::processorBoundarySphereInteraction<cFM, gMM>::sphereSphereInteraction
( (
real dt, real dt,
const ContactForceModel &cfModel const ContactForceModel &cfModel,
uint32 step
) )
{ {
return true;
if(!masterInteraction_) return true;
const auto & sphPar = this->sphParticles(); // master processor calculates the contact force/torque and sends data back to the
uint32 thisIndex = this->boundary().thisBoundaryIndex(); // neighbor processor (slave processor).
pOutput<<"beofre sphereSphereInteraction"<<endl; // slave processor recieves the data and adds the data to the internalField
pFlow::MPI::processorBoundarySIKernels::sphereSphereInteraction( if(masterInteraction_)
dt, {
this->ppPairs(), if(step==1)return true;
cfModel,
this->boundary().thisPoints(),
sphPar.diameter().deviceViewAll(),
sphPar.propertyId().deviceViewAll(),
sphPar.velocity().deviceViewAll(),
sphPar.rVelocity().deviceViewAll(),
sphPar.contactForce().deviceViewAll(),
sphPar.contactTorque().deviceViewAll(),
this->boundary().neighborProcPoints().deviceViewAll(),
sphPar.diameter().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.propertyId().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.velocity().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.rVelocity().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.contactForce().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.contactTorque().BoundaryField(thisIndex).neighborProcField().deviceViewAll()
);
pOutput<<"after sphereSphereInteraction"<<endl; const auto & sphPar = this->sphParticles();
uint32 thisIndex = this->boundary().thisBoundaryIndex();
const auto& cfBndry = static_cast<const processorBoundaryField<realx3>&> (
sphPar.contactForce().BoundaryField(thisIndex));
return true; const auto& ctBndry = static_cast<const processorBoundaryField<realx3>&> (
sphPar.contactTorque().BoundaryField(thisIndex));
if(step == 2 )
{
iter++;
inter_.start();
pFlow::MPI::processorBoundarySIKernels::sphereSphereInteraction(
dt,
this->ppPairs(),
cfModel,
this->boundary().thisPoints(),
sphPar.diameter().deviceViewAll(),
sphPar.propertyId().deviceViewAll(),
sphPar.velocity().deviceViewAll(),
sphPar.rVelocity().deviceViewAll(),
sphPar.contactForce().deviceViewAll(),
sphPar.contactTorque().deviceViewAll(),
this->boundary().neighborProcPoints().deviceViewAll(),
sphPar.diameter().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.propertyId().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.velocity().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.rVelocity().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
cfBndry.neighborProcField().deviceViewAll(),
ctBndry.neighborProcField().deviceViewAll()
);
inter_.end();
return true;
}
else if(step == 3 )
{
send_.start();
cfBndry.sendBackData();
ctBndry.sendBackData();
send_.end();
return true;
}
if(iter % 1000 == 0u)
{
pOutput<<"inter "<< inter_.totalTime()<<endl;
pOutput<<"send "<< send_.totalTime()<<endl<<endl;;
}
return false;
}
else
{
const auto & sphPar = this->sphParticles();
uint32 thisIndex = this->boundary().thisBoundaryIndex();
const auto& cfBndry = static_cast<const processorBoundaryField<realx3>&>(
sphPar.contactForce().BoundaryField(thisIndex));
const auto& ctBndry = static_cast<const processorBoundaryField<realx3>&> (
sphPar.contactTorque().BoundaryField(thisIndex));
if(step==1)
{
recv_.start();
cfBndry.recieveBackData();
ctBndry.recieveBackData();
recv_.end();
return false;
}
else if(step == 2)
{
iter++;
return true;
}
else if(step == 3)
{
add_.start();
cfBndry.addBufferToInternalField();
ctBndry.addBufferToInternalField();
add_.end();
return true;
}
if(iter % 1000 == 0u)
{
pOutput<<"recive "<< recv_.totalTime()<<endl;
pOutput<<"add "<< add_.totalTime()<<endl<<endl;
}
return false;
}
return false;
} }

View File

@ -21,6 +21,7 @@ Licence:
#define __processorBoundarySphereInteraction_hpp__ #define __processorBoundarySphereInteraction_hpp__
#include "boundarySphereInteraction.hpp" #include "boundarySphereInteraction.hpp"
#include "processorBoundaryField.hpp"
namespace pFlow::MPI namespace pFlow::MPI
{ {
@ -56,6 +57,12 @@ private:
bool masterInteraction_; bool masterInteraction_;
Timer inter_;
Timer send_;
Timer recv_;
Timer add_;
uint32 iter=0;
public: public:
TypeInfoTemplate22("boundarySphereInteraction", "processor",ContactForceModel, MotionModel); TypeInfoTemplate22("boundarySphereInteraction", "processor",ContactForceModel, MotionModel);
@ -78,7 +85,8 @@ public:
bool sphereSphereInteraction( bool sphereSphereInteraction(
real dt, real dt,
const ContactForceModel& cfModel)override; const ContactForceModel& cfModel,
uint32 step)override;
}; };

View File

@ -26,7 +26,6 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::createSphereInteraction()
auto modelDict = this->subDict("model"); auto modelDict = this->subDict("model");
REPORT(1)<<"Createing contact force model . . ."<<END_REPORT;
forceModel_ = makeUnique<ContactForceModel>( forceModel_ = makeUnique<ContactForceModel>(
this->numMaterials(), this->numMaterials(),
rhoD.deviceView(), rhoD.deviceView(),
@ -46,8 +45,6 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::createSphereInteraction()
pwContactList_ = makeUnique<ContactListType>(nPrtcl/5+1); pwContactList_ = makeUnique<ContactListType>(nPrtcl/5+1);
return true; return true;
} }
@ -140,7 +137,9 @@ pFlow::sphereInteraction<cFM,gMM, cLT>::sphereInteraction
ppInteractionTimer_("sphere-sphere interaction", &this->timers()), ppInteractionTimer_("sphere-sphere interaction", &this->timers()),
pwInteractionTimer_("sphere-wall interaction", &this->timers()), pwInteractionTimer_("sphere-wall interaction", &this->timers()),
contactListMangementTimer_("contact-list management", &this->timers()), contactListMangementTimer_("contact-list management", &this->timers()),
boundaryInteractionTimer_("interaction for boundary", &this->timers()) boundaryContactSearchTimer_("contact search for boundary", &this->timers()),
boundaryInteractionTimer_("interaction for boundary", &this->timers()),
contactListBoundaryTimer_("contact-list management for boundary", &this->timers())
{ {
if(!createSphereInteraction()) if(!createSphereInteraction())
@ -182,11 +181,14 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
contactListMangementTimer_.pause(); contactListMangementTimer_.pause();
} }
contactListBoundaryTimer_.start();
for(uint32 i=0; i<6u; i++) for(uint32 i=0; i<6u; i++)
{ {
boundaryInteraction_[i].ppPairs().beforeBroadSearch(); auto& BI = boundaryInteraction_[i];
boundaryInteraction_[i].pwPairs().beforeBroadSearch(); if(BI.ppPairsAllocated()) BI.ppPairs().beforeBroadSearch();
if(BI.pwPairsAllocated()) BI.pwPairs().beforeBroadSearch();
} }
contactListBoundaryTimer_.pause();
if( sphParticles_.numActive()<=0)return true; if( sphParticles_.numActive()<=0)return true;
@ -203,21 +205,27 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
fatalExit; fatalExit;
} }
boundaryContactSearchTimer_.start();
for(uint32 i=0; i<6u; i++) for(uint32 i=0; i<6u; i++)
{ {
if( !contactSearch_().boundaryBroadSearch( auto& BI =boundaryInteraction_[i];
i, if(BI.ppPairsAllocated())
iter,
t,
dt,
boundaryInteraction_[i].ppPairs(),
boundaryInteraction_[i].pwPairs()))
{ {
fatalErrorInFunction<< if( !contactSearch_().boundaryBroadSearch(
"failed to perform broadSearch for boundary index "<<i<<endl; i,
return false; iter,
} t,
dt,
BI.ppPairs(),
BI.pwPairs()))
{
fatalErrorInFunction<<
"failed to perform broadSearch for boundary index "<<i<<endl;
return false;
}
}
} }
boundaryContactSearchTimer_.end();
if(broadSearch && contactSearch_().performedBroadSearch()) if(broadSearch && contactSearch_().performedBroadSearch())
{ {
@ -227,12 +235,44 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
contactListMangementTimer_.end(); contactListMangementTimer_.end();
} }
contactListBoundaryTimer_.resume();
for(uint32 i=0; i<6u; i++) for(uint32 i=0; i<6u; i++)
{ {
boundaryInteraction_[i].ppPairs().afterBroadSearch(); auto& BI = boundaryInteraction_[i];
boundaryInteraction_[i].pwPairs().afterBroadSearch(); if(BI.ppPairsAllocated()) BI.ppPairs().afterBroadSearch();
if(BI.pwPairsAllocated()) BI.pwPairs().afterBroadSearch();
} }
contactListBoundaryTimer_.end();
{
boundaryInteractionTimer_.start();
std::array<bool,6> requireStep{
boundaryInteraction_[0].isBoundaryMaster(),
boundaryInteraction_[1].isBoundaryMaster(),
boundaryInteraction_[2].isBoundaryMaster(),
boundaryInteraction_[3].isBoundaryMaster(),
boundaryInteraction_[4].isBoundaryMaster(),
boundaryInteraction_[5].isBoundaryMaster()};
int step = 1;
const auto& cfModel = this->forceModel_();
while( std::any_of(requireStep.begin(), requireStep.end(), [](bool v) { return v==true; }))
{
for(uint32 i=0; i<6u; i++)
{
if(step==1u || requireStep[i] )
{
requireStep[i] = boundaryInteraction_[i].sphereSphereInteraction(
dt,
this->forceModel_(),
step
);
}
}
step++;
}
boundaryInteractionTimer_.pause();
}
ppInteractionTimer_.start(); ppInteractionTimer_.start();
sphereSphereInteraction(); sphereSphereInteraction();
ppInteractionTimer_.end(); ppInteractionTimer_.end();
@ -242,14 +282,36 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
sphereWallInteraction(); sphereWallInteraction();
pwInteractionTimer_.end(); pwInteractionTimer_.end();
boundaryInteractionTimer_.start();
for(uint32 i=0; i<6u; i++)
{ {
boundaryInteraction_[i].sphereSphereInteraction( boundaryInteractionTimer_.resume();
dt, std::array<bool,6> requireStep{
this->forceModel_()); !boundaryInteraction_[0].isBoundaryMaster(),
!boundaryInteraction_[1].isBoundaryMaster(),
!boundaryInteraction_[2].isBoundaryMaster(),
!boundaryInteraction_[3].isBoundaryMaster(),
!boundaryInteraction_[4].isBoundaryMaster(),
!boundaryInteraction_[5].isBoundaryMaster()};
int step = 2;
const auto& cfModel = this->forceModel_();
while(std::any_of(requireStep.begin(), requireStep.end(), [](bool v) { return v==true; }))
{
for(uint32 i=0; i<6u; i++)
{
if(requireStep[i])
{
requireStep[i] = boundaryInteraction_[i].sphereSphereInteraction(
dt,
this->forceModel_(),
step
);
}
}
step++;
} }
boundaryInteractionTimer_.end(); boundaryInteractionTimer_.end();
}
return true; return true;
} }

View File

@ -96,9 +96,12 @@ private:
/// timer for managing contact lists (only inernal points) /// timer for managing contact lists (only inernal points)
Timer contactListMangementTimer_; Timer contactListMangementTimer_;
Timer boundaryContactSearchTimer_;
/// timer for boundary interaction time /// timer for boundary interaction time
Timer boundaryInteractionTimer_; Timer boundaryInteractionTimer_;
Timer contactListBoundaryTimer_;
bool createSphereInteraction(); bool createSphereInteraction();

View File

@ -261,7 +261,7 @@ struct pwInteractionFunctor
int32 propId_i = propId_[i]; int32 propId_i = propId_[i];
int32 wPropId_j = wPropId_[tj]; int32 wPropId_j = wPropId_[tj];
realx3 FCn, FCt, Mri, Mrj, Mij, Mji; realx3 FCn, FCt, Mri, Mrj, Mij;
//output<< "before "<<history.overlap_t_<<endl; //output<< "before "<<history.overlap_t_<<endl;
// calculates contact force // calculates contact force
forceModel_.contactForce( forceModel_.contactForce(

View File

@ -62,7 +62,7 @@ public:
INLINE_FUNCTION_HD INLINE_FUNCTION_HD
realx3 linVelocityPoint(const realx3 &)const realx3 linVelocityPoint(const realx3 &)const
{ {
return zero3; return realx3(0);
} }
INLINE_FUNCTION_HD INLINE_FUNCTION_HD

View File

@ -76,8 +76,6 @@ protected:
{ {
return true; return true;
} }
void impl_setTime(uint32 iter, real t, real dt)const;
public: public:
@ -90,6 +88,7 @@ public:
const dictionary& dict, const dictionary& dict,
repository* owner); repository* owner);
using fileDictionary::write;
bool write(iOstream& os, const IOPattern& iop)const override; bool write(iOstream& os, const IOPattern& iop)const override;
@ -98,6 +97,9 @@ public:
{ {
return rotatingAxis({0,0,0}, {1,0,0}, 0.0); return rotatingAxis({0,0,0}, {1,0,0}, 0.0);
} }
// TODO: make this method protected
void impl_setTime(uint32 iter, real t, real dt)const;
}; };
} // pFlow } // pFlow

View File

@ -84,6 +84,8 @@ public:
repository* owner); repository* owner);
using fileDictionary::write;
bool write(iOstream& os, const IOPattern& iop)const override; bool write(iOstream& os, const IOPattern& iop)const override;
static static

View File

@ -82,7 +82,6 @@ protected:
return true; return true;
} }
void impl_setTime(uint32 iter, real t, real dt)const;
public: public:
@ -99,15 +98,20 @@ public:
/// Destructor /// Destructor
~vibratingMotion()override = default; ~vibratingMotion()override = default;
using fileDictionary::write;
bool write(iOstream& os, const IOPattern& iop)const override; bool write(iOstream& os, const IOPattern& iop)const override;
static static
auto noneComponent() auto noneComponent()
{ {
return vibrating(); return vibrating();
} }
// TODO: make this protected
void impl_setTime(uint32 iter, real t, real dt)const;
}; };
} // pFlow } // pFlow

View File

@ -60,7 +60,7 @@ pFlow::collisionCheck::checkPoint(const realx3& p, const real d) const
{ {
uint32 n = head_(i, j, k); uint32 n = head_(i, j, k);
while( n != -1) while( n != static_cast<uint32>(-1))
{ {
if( ((position_[n]-p).length() - 0.5*(diameters_[n]+d )) <= 0.0 ) if( ((position_[n]-p).length() - 0.5*(diameters_[n]+d )) <= 0.0 )
{ {
@ -85,7 +85,7 @@ pFlow::collisionCheck::mapLastAddedParticle()
"size mismatch of next and position"<<endl; "size mismatch of next and position"<<endl;
return false; return false;
} }
next_.push_back(-1); next_.push_back(static_cast<uint32>(-1));
const auto& p = position_[n]; const auto& p = position_[n];
if(!searchBox_.isInside(p)) if(!searchBox_.isInside(p))

View File

@ -74,9 +74,6 @@ pFlow::insertion::pStruct() const
return particles_.pStruct(); return particles_.pStruct();
} }
bool bool
pFlow::insertion::readInsertionDict() pFlow::insertion::readInsertionDict()
{ {

View File

@ -32,7 +32,9 @@ class pointStructure;
/** /**
* Base class for particle insertion * Base class for particle insertion
*/ */
class insertion : public fileDictionary class insertion
:
public fileDictionary
{ {
private: private:
@ -118,6 +120,8 @@ public:
/*/// read from iIstream /*/// read from iIstream
virtual bool read(iIstream& is) = 0;*/ virtual bool read(iIstream& is) = 0;*/
using fileDictionary::write;
/// write to iOstream /// write to iOstream
bool write(iOstream& os, const IOPattern& iop)const override ; bool write(iOstream& os, const IOPattern& iop)const override ;
}; };

View File

@ -389,7 +389,9 @@ pFlow::sphereParticles::sphereParticles(
intPredictTimer_( intPredictTimer_(
"Integration-predict", &this->timers() ), "Integration-predict", &this->timers() ),
intCorrectTimer_( intCorrectTimer_(
"Integration-correct", &this->timers() ) "Integration-correct", &this->timers() ),
fieldUpdateTimer_(
"fieldUpdate", &this->timers() )
{ {
auto intMethod = control.settingsDict().getVal<word>("integrationMethod"); auto intMethod = control.settingsDict().getVal<word>("integrationMethod");
@ -514,13 +516,14 @@ bool pFlow::sphereParticles::beforeIteration()
rVelIntegration_().predict(dt,rVelocity_, rAcceleration_); rVelIntegration_().predict(dt,rVelocity_, rAcceleration_);
intPredictTimer_.end(); intPredictTimer_.end();
fieldUpdateTimer_.start();
propertyId_.updateBoundariesSlaveToMasterIfRequested(); propertyId_.updateBoundariesSlaveToMasterIfRequested();
diameter_.updateBoundariesSlaveToMasterIfRequested(); diameter_.updateBoundariesSlaveToMasterIfRequested();
mass_.updateBoundariesSlaveToMasterIfRequested(); mass_.updateBoundariesSlaveToMasterIfRequested();
I_.updateBoundariesSlaveToMasterIfRequested(); I_.updateBoundariesSlaveToMasterIfRequested();
rVelocity_.updateBoundariesSlaveToMasterIfRequested(); rVelocity_.updateBoundariesSlaveToMasterIfRequested();
rAcceleration_.updateBoundariesSlaveToMasterIfRequested(); rAcceleration_.updateBoundariesSlaveToMasterIfRequested();
fieldUpdateTimer_.end();
return true; return true;
} }

View File

@ -79,10 +79,10 @@ private:
/// timer for integration computations (correction step) /// timer for integration computations (correction step)
Timer intCorrectTimer_; Timer intCorrectTimer_;
Timer fieldUpdateTimer_;
private: private:
bool initializeParticles();
bool getParticlesInfoFromShape( bool getParticlesInfoFromShape(
const wordVector& shapeNames, const wordVector& shapeNames,
@ -119,11 +119,14 @@ public:
*/ */
/*bool insertParticles /*bool insertParticles
( (
const realx3Vector& position, const realx3Vector& position,
const wordVector& shapes, const wordVector& shapes,
const setFieldList& setField const setFieldList& setField
) override ;*/ ) override ;*/
// TODO: make this method private later
bool initializeParticles();
/// const reference to shapes object /// const reference to shapes object
const auto& spheres() const const auto& spheres() const
{ {

View File

@ -38,6 +38,7 @@ pFlow::dynamicPointStructure::dynamicPointStructure
*this, *this,
zero3 zero3
), ),
velocityUpdateTimer_("velocity boundary update", &timers()),
integrationMethod_ integrationMethod_
( (
control.settingsDict().getVal<word>("integrationMethod") control.settingsDict().getVal<word>("integrationMethod")
@ -81,11 +82,11 @@ pFlow::dynamicPointStructure::dynamicPointStructure
bool pFlow::dynamicPointStructure::beforeIteration() bool pFlow::dynamicPointStructure::beforeIteration()
{ {
return pointStructure::beforeIteration(); if(!pointStructure::beforeIteration())return false;
/*real dt = this->dt(); velocityUpdateTimer_.start();
velocity_.updateBoundariesSlaveToMasterIfRequested();
auto& acc = time().lookupObject<realx3PointField_D>("acceleration"); velocityUpdateTimer_.end();
return predict(dt, acc);*/ return true;
} }
bool pFlow::dynamicPointStructure::iterate() bool pFlow::dynamicPointStructure::iterate()

View File

@ -44,6 +44,8 @@ private:
uniquePtr<integration> integrationVel_ = nullptr; uniquePtr<integration> integrationVel_ = nullptr;
Timer velocityUpdateTimer_;
/// @brief integration method for velocity and position /// @brief integration method for velocity and position
word integrationMethod_; word integrationMethod_;

View File

@ -74,7 +74,8 @@ pFlow::particles::particles(systemControl& control)
dynPointStruct_, dynPointStruct_,
zero3 zero3
), ),
idHandler_(particleIdHandler::create(dynPointStruct_)) idHandler_(particleIdHandler::create(dynPointStruct_)),
baseFieldBoundaryUpdateTimer_("baseFieldBoundaryUpdate",&timers())
{ {
this->addToSubscriber(dynPointStruct_); this->addToSubscriber(dynPointStruct_);
@ -84,18 +85,18 @@ pFlow::particles::particles(systemControl& control)
bool bool
pFlow::particles::beforeIteration() pFlow::particles::beforeIteration()
{ {
zeroForce();
zeroTorque();
if( !dynPointStruct_.beforeIteration()) if( !dynPointStruct_.beforeIteration())
{ {
return false; return false;
} }
zeroForce();
zeroTorque();
baseFieldBoundaryUpdateTimer_.start();
shapeIndex_.updateBoundariesSlaveToMasterIfRequested(); shapeIndex_.updateBoundariesSlaveToMasterIfRequested();
accelertion_.updateBoundariesSlaveToMasterIfRequested(); accelertion_.updateBoundariesSlaveToMasterIfRequested();
idHandler_().updateBoundariesSlaveToMasterIfRequested(); idHandler_().updateBoundariesSlaveToMasterIfRequested();
baseFieldBoundaryUpdateTimer_.end();
return true; return true;
} }

View File

@ -54,6 +54,8 @@ private:
/// handling new ids for new particles /// handling new ids for new particles
uniquePtr<particleIdHandler> idHandler_ = nullptr; uniquePtr<particleIdHandler> idHandler_ = nullptr;
Timer baseFieldBoundaryUpdateTimer_;
/// messages for this objects /// messages for this objects
static inline const message defaultMessage_{ message::DEFAULT }; static inline const message defaultMessage_{ message::DEFAULT };

View File

@ -15,8 +15,11 @@ pFlow::regularParticleIdHandler::regularParticleIdHandler
pFlow::Pair<pFlow::uint32, pFlow::uint32> pFlow::Pair<pFlow::uint32, pFlow::uint32>
pFlow::regularParticleIdHandler::getIdRange(uint32 nNewParticles) pFlow::regularParticleIdHandler::getIdRange(uint32 nNewParticles)
{ {
if(nNewParticles==0) return {0,0};
uint32 startId; uint32 startId;
if(maxId_==-1) if(maxId_== static_cast<uint32>(-1))
{ {
startId = 0; startId = 0;
} }
@ -37,7 +40,7 @@ bool pFlow::regularParticleIdHandler::initialIdCheck()
uint32 maxId = max( *this ); uint32 maxId = max( *this );
/// particles should get ids from 0 to size-1 /// particles should get ids from 0 to size-1
if(maxId == -1) if(maxId == static_cast<uint32>(-1))
{ {
fillSequence(*this,0u); fillSequence(*this,0u);
maxId_ = size()-1; maxId_ = size()-1;

View File

@ -31,7 +31,7 @@ class regularParticleIdHandler
{ {
private: private:
uint32 maxId_ = -1; uint32 maxId_ = static_cast<uint32>(-1);
bool initialIdCheck()override; bool initialIdCheck()override;
public: public:

View File

@ -132,7 +132,7 @@ public:
return true; return true;
} }
} }
idx = -1; idx = static_cast<uint32>(-1);
return false; return false;
} }
@ -144,6 +144,8 @@ public:
// - IO // - IO
using fileDictionary::write;
bool write(iOstream& os)const override; bool write(iOstream& os)const override;
}; };

View File

@ -59,6 +59,7 @@ Timer/Timers.cpp
containers/Vector/Vectors.cpp containers/Vector/Vectors.cpp
containers/VectorHD/wordVectorHost.cpp
containers/VectorHD/VectorSingles.cpp containers/VectorHD/VectorSingles.cpp
containers/Field/Fields.cpp containers/Field/Fields.cpp
containers/symArrayHD/symArrays.cpp containers/symArrayHD/symArrays.cpp
@ -94,6 +95,8 @@ structuredData/pointStructure/selectors/selectorStridedRange/selectorStridedRang
structuredData/pointStructure/selectors/selectorRandomPoints/selectorRandomPoints.cpp structuredData/pointStructure/selectors/selectorRandomPoints/selectorRandomPoints.cpp
structuredData/pointStructure/selectors/selectBox/selectBox.cpp structuredData/pointStructure/selectors/selectBox/selectBox.cpp
structuredData/pointStructure/selectors/selectorGeometric/selectorGeometrics.cpp structuredData/pointStructure/selectors/selectorGeometric/selectorGeometrics.cpp
structuredData/pointStructure/pointStructure/pointSorting/mortonIndexing.cpp
structuredData/pointStructure/pointStructure/pointSorting/pointSorting.cpp
triSurface/subSurface.cpp triSurface/subSurface.cpp
triSurface/triSurface.cpp triSurface/triSurface.cpp

View File

@ -421,10 +421,10 @@ binarySearch(
) )
{ {
if (end <= start) if (end <= start)
return -1; return static_cast<uint32>(-1);
if (auto res = binarySearch_(view.data() + start, end - start, val); if (auto res = binarySearch_(view.data() + start, end - start, val);
res != -1) res != static_cast<uint32>(-1))
{ {
return res + start; return res + start;
} }

View File

@ -41,6 +41,12 @@ bool pFlow::MPI::MPISimulationDomain::createBoundaryDicts()
auto& mpiBoundaries = this->subDict("MPIBoundaries"); auto& mpiBoundaries = this->subDict("MPIBoundaries");
real neighborLength = boundaries.getVal<real>("neighborLength"); real neighborLength = boundaries.getVal<real>("neighborLength");
auto boundaryExtntionLengthRatio = max(
boundaries.getValOrSet<real>("boundaryExtntionLengthRatio", 0.1),
0.0);
auto updateIntercal = max(
boundaries.getValOrSet<uint32>("updateInterval", 1u),
1u);
auto neighbors = findPlaneNeighbors(); auto neighbors = findPlaneNeighbors();
@ -61,6 +67,15 @@ bool pFlow::MPI::MPISimulationDomain::createBoundaryDicts()
"in dictionary "<< boundaries.globalName()<<endl; "in dictionary "<< boundaries.globalName()<<endl;
return false; return false;
} }
if(!bDict.addOrReplace("updateInterval", updateIntercal))
{
fatalErrorInFunction<<"error in adding updateIntercal to "<< bName <<
"in dictionary "<< boundaries.globalName()<<endl;
}
bDict.addOrReplace("boundaryExtntionLengthRatio", boundaryExtntionLengthRatio);
if( thisDomainActive_ ) if( thisDomainActive_ )
{ {
if( neighbors[i] == -1 ) if( neighbors[i] == -1 )

View File

@ -1,3 +1,4 @@
#include "processorBoundaryField.hpp"
/*------------------------------- phasicFlow --------------------------------- /*------------------------------- phasicFlow ---------------------------------
O C enter of O C enter of
O O E ngineering and O O E ngineering and
@ -90,8 +91,10 @@ pFlow::MPI::processorBoundaryField<T, MemorySpace>::processorBoundaryField(
boundary.mirrorBoundaryIndex() boundary.mirrorBoundaryIndex()
) )
{ {
this->addEvent(message::BNDR_PROCTRANS1). this->addEvent(message::BNDR_PROCTRANSFER_SEND).
addEvent(message::BNDR_PROCTRANS2); addEvent(message::BNDR_PROCTRANSFER_RECIEVE).
addEvent(message::BNDR_PROCTRANSFER_WAITFILL).
addEvent(message::BNDR_PROC_SIZE_CHANGED);
} }
template<class T, class MemorySpace> template<class T, class MemorySpace>
@ -109,4 +112,139 @@ const typename pFlow::MPI::processorBoundaryField<T, MemorySpace>::
{ {
checkDataRecieved(); checkDataRecieved();
return reciever_.buffer(); return reciever_.buffer();
}
template<class T, class MemorySpace>
bool pFlow::MPI::processorBoundaryField<T, MemorySpace>::hearChanges(
real t,
real dt,
uint32 iter,
const message& msg,
const anyList& varList
)
{
BoundaryFieldType::hearChanges(t,dt,iter, msg,varList);
if(msg.equivalentTo(message::BNDR_PROC_SIZE_CHANGED))
{
auto newProcSize = varList.getObject<uint32>("size");
reciever_.resize(newProcSize);
}
if(msg.equivalentTo(message::BNDR_PROCTRANSFER_SEND))
{
const auto& indices = varList.getObject<uint32Vector_D>(
message::eventName(message::BNDR_PROCTRANSFER_SEND)
);
if constexpr( isDeviceAccessible<execution_space>())
{
FieldAccessType transferData(
indices.size(),
indices.deviceViewAll(),
this->internal().deviceViewAll()
);
sender_.sendData(pFlowProcessors(),transferData);
}
else
{
FieldAccessType transferData(
indices.size(),
indices.hostViewAll(),
this->internal().deviceViewAll()
);
sender_.sendData(pFlowProcessors(),transferData);
}
}
else if(msg.equivalentTo(message::BNDR_PROCTRANSFER_RECIEVE))
{
uint32 numRecieved = varList.getObject<uint32>(
message::eventName(message::BNDR_PROCTRANSFER_RECIEVE)
);
reciever_.recieveData(pFlowProcessors(), numRecieved);
}
else if(msg.equivalentTo(message::BNDR_PROCTRANSFER_WAITFILL))
{
uint32 numRecieved = reciever_.waitBufferForUse();
if(msg.equivalentTo(message::CAP_CHANGED))
{
auto newCap = varList.getObject<uint32>(
message::eventName(message::CAP_CHANGED));
this->internal().field().reserve(newCap);
}
if(msg.equivalentTo(message::SIZE_CHANGED))
{
auto newSize = varList.getObject<uint32>(
message::eventName(message::SIZE_CHANGED));
this->internal().field().resize(newSize);
}
const auto& indices = varList.getObject<uint32IndexContainer>(
message::eventName(message::ITEM_INSERT));
this->internal().field().insertSetElement(indices, reciever_.buffer().deviceView());
return true;
}
return true;
}
template <class T, class MemorySpace>
void pFlow::MPI::processorBoundaryField<T, MemorySpace>::sendBackData() const
{
reciever_.sendBackData(pFlowProcessors());
dataRecieved_ = false;
}
template <class T, class MemorySpace>
void pFlow::MPI::processorBoundaryField<T, MemorySpace>::recieveBackData() const
{
sender_.recieveBackData(pFlowProcessors(), this->size());
}
template <class T, class MemorySpace>
void pFlow::MPI::processorBoundaryField<T, MemorySpace>::addBufferToInternalField()const
{
using RPolicy = Kokkos::RangePolicy<
execution_space,
Kokkos::Schedule<Kokkos::Static>,
Kokkos::IndexType<pFlow::uint32>>;
sender_.waitBufferForUse();
const auto& buffView = sender_.buffer().deviceViewAll();
const auto& field = this->internal().deviceViewAll();
if constexpr( isDeviceAccessible<execution_space> )
{
const auto& indices = this->indexList().deviceViewAll();
Kokkos::parallel_for(
"dataSender::recieveBackData",
RPolicy(0,this->size()),
LAMBDA_HD(uint32 i)
{
field[indices[i]] += buffView[i];
}
);
Kokkos::fence();
}
else
{
const auto& indices = this->boundary().indexListHost().deviceViewAll();
Kokkos::parallel_for(
"dataSender::recieveBackData",
RPolicy(0,this->size()),
LAMBDA_HD(uint32 i)
{
field[indices[i]] += buffView[i];
}
);
Kokkos::fence();
}
} }

View File

@ -83,25 +83,25 @@ public:
ProcVectorType& neighborProcField() override; ProcVectorType& neighborProcField() override;
const ProcVectorType& neighborProcField()const override; const ProcVectorType& neighborProcField()const override;
void fill(const T& val)override
{
reciever_.fill(val);
}
bool hearChanges bool hearChanges(
(
real t, real t,
real dt, real dt,
uint32 iter, uint32 iter,
const message& msg, const message& msg,
const anyList& varList const anyList& varList
) override ) override;
{
BoundaryFieldType::hearChanges(t,dt,iter, msg,varList); void sendBackData()const;
if(msg.equivalentTo(message::BNDR_DELETE)) void recieveBackData()const;
{
// do nothing; void addBufferToInternalField()const;
}
return true;
}
}; };

View File

@ -19,16 +19,14 @@ Licence:
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
#include "boundaryProcessor.hpp" #include "boundaryProcessor.hpp"
#include "boundaryProcessorKernels.hpp"
#include "dictionary.hpp" #include "dictionary.hpp"
#include "mpiCommunication.hpp" #include "mpiCommunication.hpp"
#include "boundaryBaseKernels.hpp" #include "boundaryBaseKernels.hpp"
#include "internalPoints.hpp" #include "internalPoints.hpp"
#include "Time.hpp"
#include "anyList.hpp"
void
pFlow::MPI::boundaryProcessor::checkSize() const
{
}
void void
pFlow::MPI::boundaryProcessor::checkDataRecieved() const pFlow::MPI::boundaryProcessor::checkDataRecieved() const
@ -69,6 +67,7 @@ pFlow::MPI::boundaryProcessor::boundaryProcessor(
bool bool
pFlow::MPI::boundaryProcessor::beforeIteration(uint32 iterNum, real t, real dt) pFlow::MPI::boundaryProcessor::beforeIteration(uint32 iterNum, real t, real dt)
{ {
thisNumPoints_ = size(); thisNumPoints_ = size();
auto req = MPI_REQUEST_NULL; auto req = MPI_REQUEST_NULL;
@ -92,13 +91,23 @@ pFlow::MPI::boundaryProcessor::beforeIteration(uint32 iterNum, real t, real dt)
); );
MPI_Request_free(&req); MPI_Request_free(&req);
anyList varList;
message msg;
varList.emplaceBack(msg.addAndName(message::BNDR_PROC_SIZE_CHANGED), neighborProcNumPoints_);
if( !notify(iterNum, t, dt, msg, varList) )
{
fatalErrorInFunction;
return false;
}
return true; return true;
} }
pFlow::uint32 pFlow::uint32
pFlow::MPI::boundaryProcessor::neighborProcSize() const pFlow::MPI::boundaryProcessor::neighborProcSize() const
{ {
checkSize();
return neighborProcNumPoints_; return neighborProcNumPoints_;
} }
@ -117,7 +126,7 @@ pFlow::MPI::boundaryProcessor::neighborProcPoints() const
} }
bool bool
pFlow::MPI::boundaryProcessor::updataBoundary(int step) pFlow::MPI::boundaryProcessor::updataBoundaryData(int step)
{ {
if (step == 1) if (step == 1)
{ {
@ -132,8 +141,10 @@ pFlow::MPI::boundaryProcessor::updataBoundary(int step)
return true; return true;
} }
bool pFlow::MPI::boundaryProcessor::transferData(int step) bool pFlow::MPI::boundaryProcessor::transferData(uint32 iter, int step)
{ {
if(!boundaryListUpdate(iter))return false;
if(step==1) if(step==1)
{ {
uint32 s = size(); uint32 s = size();
@ -141,23 +152,21 @@ bool pFlow::MPI::boundaryProcessor::transferData(int step)
transferFlags.fill(0u); transferFlags.fill(0u);
const auto& transferD = transferFlags.deviceViewAll(); const auto& transferD = transferFlags.deviceViewAll();
auto points = thisPoints(); deviceScatteredFieldAccess<realx3> points = thisPoints();
auto p = boundaryPlane().infPlane(); auto p = boundaryPlane().infPlane();
numToTransfer_ = 0; numToTransfer_ = 0;
Kokkos::parallel_reduce
Kokkos::parallel_reduce
( (
"boundaryProcessor::afterIteration", "boundaryProcessor::afterIteration",
deviceRPolicyStatic(0,s), deviceRPolicyStatic(0,s),
LAMBDA_HD(uint32 i, uint32& transferToUpdate) boundaryProcessorKernels::markNegative(
{ boundaryPlane().infPlane(),
if(p.pointInNegativeSide(points(i))) transferFlags.deviceViewAll(),
{ thisPoints()
transferD(i)=1; ),
transferToUpdate++;
}
},
numToTransfer_ numToTransfer_
); );
@ -193,37 +202,103 @@ bool pFlow::MPI::boundaryProcessor::transferData(int step)
thisBoundaryIndex(), thisBoundaryIndex(),
pFlowProcessors().localCommunicator(), pFlowProcessors().localCommunicator(),
&req), true ); &req), true );
//pOutput<<"sent "<< numToTransfer_<<endl;
CheckMPI(recv( CheckMPI(recv(
numToRecieve_, numToRecieve_,
neighborProcessorNo(), neighborProcessorNo(),
mirrorBoundaryIndex(), mirrorBoundaryIndex(),
pFlowProcessors().localCommunicator(), pFlowProcessors().localCommunicator(),
StatusesIgnore), true); StatusesIgnore), true);
//pOutput<<"recieved "<<numToRecieve_<<endl;
MPI_Request_free(&req); MPI_Request_free(&req);
return true; return true;
} }
else if(step ==2 ) else if(step ==2 )
{ {
if( transferIndices_.empty() )return true;
pointFieldAccessType transferPoints( pointFieldAccessType transferPoints(
transferIndices_.size(), transferIndices_.size(),
transferIndices_.deviceViewAll(), transferIndices_.deviceViewAll(),
internal().pointPositionDevice()); internal().pointPositionDevice());
sender_.sendData(pFlowProcessors(), transferPoints); sender_.sendData(pFlowProcessors(), transferPoints);
message msg;
anyList varList;
varList.emplaceBack(
msg.addAndName(message::BNDR_PROCTRANSFER_SEND),
transferIndices_);
if(!notify(
internal().time().currentIter(),
internal().time().currentTime(),
internal().time().dt(),
msg,
varList))
{
fatalErrorInFunction;
return false;
}
return true; return true;
} }
else if(step == 3) else if(step == 3)
{ {
if(numToRecieve_ == 0u) return false;
reciever_.recieveData(pFlowProcessors(), numToRecieve_); reciever_.recieveData(pFlowProcessors(), numToRecieve_);
message msg;
anyList varList;
varList.emplaceBack(
msg.addAndName(message::BNDR_PROCTRANSFER_RECIEVE),
numToRecieve_);
if(!notify(
internal().time().currentIter(),
internal().time().currentTime(),
internal().time().dt(),
msg,
varList))
{
fatalErrorInFunction;
return false;
}
return true; return true;
} }
else if(step == 4) else if(step == 4)
{ {
if(numToRecieve_ == 0u) return false;
reciever_.waitBufferForUse(); reciever_.waitBufferForUse();
//
// points should be inserted first
message msg(message::BNDR_PROCTRANSFER_WAITFILL);
anyList varList;
internal().insertPointsOnly(reciever_.buffer(), msg, varList);
const auto& indices = varList.getObject<uint32IndexContainer>(message::eventName(message::ITEM_INSERT));
auto indView = deviceViewType1D<uint32>(indices.deviceView().data(), indices.deviceView().size());
uint32Vector_D newIndices("newIndices", indView);
if(! appendNewIndices(newIndices))
{
fatalErrorInFunction;
return false;
}
if(!notify(
internal().time().currentIter(),
internal().time().currentTime(),
internal().time().dt(),
msg,
varList))
{
fatalErrorInFunction;
return false;
}
return false; return false;
} }

View File

@ -33,9 +33,11 @@ namespace pFlow::MPI
: public boundaryBase : public boundaryBase
{ {
public: public:
using pointFieldAccessType = typename boundaryBase::pointFieldAccessType; using pointFieldAccessType = typename boundaryBase::pointFieldAccessType;
private: private:
uint32 neighborProcNumPoints_ = 0; uint32 neighborProcNumPoints_ = 0;
uint32 thisNumPoints_ = 0; uint32 thisNumPoints_ = 0;
@ -54,8 +56,6 @@ namespace pFlow::MPI
uint32Vector_D transferIndices_{"transferIndices"}; uint32Vector_D transferIndices_{"transferIndices"};
void checkSize() const;
void checkDataRecieved() const; void checkDataRecieved() const;
/// @brief Update processor boundary data for this processor /// @brief Update processor boundary data for this processor
@ -66,9 +66,9 @@ namespace pFlow::MPI
/// allow processor boundaries to exchange data in two steps. /// allow processor boundaries to exchange data in two steps.
/// The first step is a buffered non-blocking send and the second /// The first step is a buffered non-blocking send and the second
/// step is non-blocking recieve to get data. /// step is non-blocking recieve to get data.
bool updataBoundary(int step) override; bool updataBoundaryData(int step) override;
bool transferData(int step) override; bool transferData(uint32 iter, int step) override;
public: public:
TypeInfo("boundary<processor>"); TypeInfo("boundary<processor>");
@ -104,6 +104,18 @@ namespace pFlow::MPI
/// @brief Return a const reference to point positions in the /// @brief Return a const reference to point positions in the
/// neighbor processor boundary. /// neighbor processor boundary.
const realx3Vector_D &neighborProcPoints() const override; const realx3Vector_D &neighborProcPoints() const override;
uint32 numToTransfer()const override
{
return numToTransfer_;
}
uint32 numToRecieve()const override
{
return numToRecieve_;
}
}; };
} // namespace pFlow::MPI } // namespace pFlow::MPI

View File

@ -0,0 +1,56 @@
/*------------------------------- 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.
-----------------------------------------------------------------------------*/
#include "phasicFlowKokkos.hpp"
#include "infinitePlane.hpp"
#include "scatteredFieldAccess.hpp"
namespace pFlow::boundaryProcessorKernels
{
struct markNegative
{
markNegative(const infinitePlane& pl,
const deviceViewType1D<uint32>& f,
const deviceScatteredFieldAccess<realx3>& p
)
:
plane_(pl),
flags_(f),
points_(p)
{}
infinitePlane plane_;
deviceViewType1D<uint32> flags_;
deviceScatteredFieldAccess<realx3> points_;
INLINE_FUNCTION_HD
void operator()(uint32 i, uint32& transferToUpdate)const
{
if(plane_.pointInNegativeSide(points_(i)))
{
flags_(i)=1;
transferToUpdate++;
}
}
};
}

View File

@ -59,15 +59,28 @@ public:
return buffer_.size(); return buffer_.size();
} }
void sendBackData(
const localProcessors& processors)const
{
CheckMPI(
Isend(
buffer_.getSpan(),
fromProc_,
tag_,
processors.localCommunicator(),
&recvRequest_
),
true
);
}
void recieveData( void recieveData(
const localProcessors& processors, const localProcessors& processors,
uint32 numToRecv uint32 numToRecv
) )
{ {
waitBufferForUse(); resize(numToRecv);
buffer_.clear();
buffer_.resize(numToRecv);
CheckMPI( CheckMPI(
Irecv( Irecv(
buffer_.getSpan(), buffer_.getSpan(),
@ -80,16 +93,39 @@ public:
); );
} }
inline
auto& buffer() auto& buffer()
{ {
return buffer_; return buffer_;
} }
inline
const auto& buffer()const const auto& buffer()const
{ {
return buffer_; return buffer_;
} }
inline
void fill(const T& val)
{
waitBufferForUse();
buffer_.fill(val);
}
inline
uint32 size()const
{
return buffer_.size();
}
inline
void resize(uint32 newSize)
{
waitBufferForUse();
buffer_.clear();
buffer_.resize(newSize);
}
}; };
} }

View File

@ -26,7 +26,7 @@ public:
private: private:
BufferVectorType buffer_; mutable BufferVectorType buffer_;
int toProc_; int toProc_;
@ -103,6 +103,33 @@ public:
} }
bool recieveBackData(
const localProcessors& processors,
uint32 numToRecieve
)const
{
// make sure the buffer is ready to be used and free
// the previous request (if any).
waitBufferForUse();
// clear the buffer to prevent data copy if capacity increases
buffer_.clear();
buffer_.resize(numToRecieve);
CheckMPI(
Irecv(
buffer_.getSpan(),
toProc_,
tag_,
processors.localCommunicator(),
&sendRequest_
),
true
);
return true;
}
auto& buffer() auto& buffer()
{ {
return buffer_; return buffer_;
@ -113,6 +140,18 @@ public:
return buffer_; return buffer_;
} }
inline
void fill(const T& val)
{
waitBufferForUse();
buffer_.fill(val);
}
uint32 size()const
{
return buffer_.size();
}
bool sendComplete() bool sendComplete()
{ {
int test; int test;
@ -127,6 +166,14 @@ public:
} }
} }
inline
void resize(uint32 newSize)
{
waitBufferForUse();
buffer_.clear();
buffer_.resize(newSize);
}
}; };
} }

View File

@ -146,11 +146,11 @@ template <typename T, typename C> class is_direct_constructible {
static auto test(int, std::true_type) -> decltype( static auto test(int, std::true_type) -> decltype(
// NVCC warns about narrowing conversions here // NVCC warns about narrowing conversions here
#ifdef __CUDACC__ #ifdef __CUDACC__
#pragma diag_suppress 2361 #pragma nv_diag_suppress 2361
#endif #endif
TT { std::declval<CC>() } TT { std::declval<CC>() }
#ifdef __CUDACC__ #ifdef __CUDACC__
#pragma diag_default 2361 #pragma nv_diag_default 2361
#endif #endif
, ,
std::is_move_assignable<TT>()); std::is_move_assignable<TT>());

View File

@ -24,6 +24,7 @@ Licence:
#include "types.hpp" #include "types.hpp"
#include "VectorSingle.hpp" #include "VectorSingle.hpp"
#include "wordVectorHost.hpp"
#include "Vector.hpp" #include "Vector.hpp"
#include "streams.hpp" #include "streams.hpp"

View File

@ -31,5 +31,4 @@ template class pFlow::Field<pFlow::real>;
template class pFlow::Field<pFlow::realx3>; template class pFlow::Field<pFlow::realx3>;
template class pFlow::Field<pFlow::word, pFlow::HostSpace>;

View File

@ -39,6 +39,7 @@ inline bool pFlow::ListPtr<T>::copy(const ListPtrType& src)
} }
template<typename T> template<typename T>
inline
T* pFlow::ListPtr<T>::ptr(size_t i) T* pFlow::ListPtr<T>::ptr(size_t i)
{ {
@ -51,6 +52,7 @@ T* pFlow::ListPtr<T>::ptr(size_t i)
} }
template<typename T> template<typename T>
inline
const T* pFlow::ListPtr<T>::ptr const T* pFlow::ListPtr<T>::ptr
( (
size_t i size_t i
@ -66,6 +68,7 @@ const T* pFlow::ListPtr<T>::ptr
} }
template<typename T> template<typename T>
inline
auto pFlow::ListPtr<T>::pos auto pFlow::ListPtr<T>::pos
( (
size_t i size_t i
@ -84,6 +87,7 @@ auto pFlow::ListPtr<T>::pos
} }
template<typename T> template<typename T>
inline
auto pFlow::ListPtr<T>::pos auto pFlow::ListPtr<T>::pos
( (
size_t i size_t i
@ -102,6 +106,7 @@ auto pFlow::ListPtr<T>::pos
} }
template<typename T> template<typename T>
inline
pFlow::ListPtr<T>::ListPtr pFlow::ListPtr<T>::ListPtr
( (
const ListPtrType& src const ListPtrType& src
@ -119,6 +124,7 @@ pFlow::ListPtr<T>::ListPtr
template<typename T> template<typename T>
inline
pFlow::ListPtr<T>& pFlow::ListPtr<T>::operator= pFlow::ListPtr<T>& pFlow::ListPtr<T>::operator=
( (
const ListPtrType& rhs const ListPtrType& rhs
@ -144,6 +150,7 @@ pFlow::ListPtr<T>& pFlow::ListPtr<T>::operator=
} }
template<typename T> template<typename T>
inline
pFlow::uniquePtr<T> pFlow::ListPtr<T>::set pFlow::uniquePtr<T> pFlow::ListPtr<T>::set
( (
size_t i, T* ptr size_t i, T* ptr
@ -155,6 +162,7 @@ pFlow::uniquePtr<T> pFlow::ListPtr<T>::set
template<typename T> template<typename T>
inline
pFlow::uniquePtr<T> pFlow::ListPtr<T>::set pFlow::uniquePtr<T> pFlow::ListPtr<T>::set
( (
size_t i, size_t i,
@ -179,6 +187,7 @@ pFlow::uniquePtr<T> pFlow::ListPtr<T>::set
template<typename T> template<typename T>
template<typename... Args> template<typename... Args>
inline
pFlow::uniquePtr<T> pFlow::ListPtr<T>::setSafe pFlow::uniquePtr<T> pFlow::ListPtr<T>::setSafe
( (
size_t i, size_t i,
@ -190,6 +199,7 @@ pFlow::uniquePtr<T> pFlow::ListPtr<T>::setSafe
} }
template<typename T> template<typename T>
inline
void pFlow::ListPtr<T>::push_back void pFlow::ListPtr<T>::push_back
( (
T* ptr T* ptr
@ -199,6 +209,7 @@ void pFlow::ListPtr<T>::push_back
} }
template<typename T> template<typename T>
inline
void pFlow::ListPtr<T>::push_back(uniquePtr<T>&& ptr) void pFlow::ListPtr<T>::push_back(uniquePtr<T>&& ptr)
{ {
list_.push_back( ptr.release() ); list_.push_back( ptr.release() );
@ -206,13 +217,15 @@ void pFlow::ListPtr<T>::push_back(uniquePtr<T>&& ptr)
template<typename T> template<typename T>
template<typename... Args> template<typename... Args>
inline
void pFlow::ListPtr<T>::push_backSafe(Args&&... args) void pFlow::ListPtr<T>::push_backSafe(Args&&... args)
{ {
auto ptr=makeUnique<T>(std::forward<Args>(args)...) ; uniquePtr<T> ptr = makeUnique<T>(std::forward<Args>(args)...) ;
push_back(ptr); push_back(ptr);
} }
template<typename T> template<typename T>
inline
T& pFlow::ListPtr<T>::operator[] T& pFlow::ListPtr<T>::operator[]
( (
size_t i size_t i
@ -231,6 +244,7 @@ T& pFlow::ListPtr<T>::operator[]
} }
template<typename T> template<typename T>
inline
const T& pFlow::ListPtr<T>::operator[] const T& pFlow::ListPtr<T>::operator[]
( (
size_t i size_t i
@ -248,18 +262,21 @@ const T& pFlow::ListPtr<T>::operator[]
} }
template<typename T> template<typename T>
inline
size_t pFlow::ListPtr<T>::size()const size_t pFlow::ListPtr<T>::size()const
{ {
return list_.size(); return list_.size();
} }
template<typename T> template<typename T>
inline
auto pFlow::ListPtr<T>::empty() const auto pFlow::ListPtr<T>::empty() const
{ {
return list_.emtpy(); return list_.emtpy();
} }
template<typename T> template<typename T>
inline
pFlow::uniquePtr<T> pFlow::ListPtr<T>::release pFlow::uniquePtr<T> pFlow::ListPtr<T>::release
( (
size_t i size_t i
@ -273,15 +290,14 @@ pFlow::uniquePtr<T> pFlow::ListPtr<T>::release
template<typename T> template<typename T>
inline
void pFlow::ListPtr<T>::clear() void pFlow::ListPtr<T>::clear()
{ {
int i =0;
for( auto iter = list_.begin(); iter != list_.end(); ++iter ) for( auto iter = list_.begin(); iter != list_.end(); ++iter )
{ {
if(*iter != nullptr) if(*iter != nullptr)
{ {
delete *iter; delete *iter;
*iter = nullptr; *iter = nullptr;
} }
@ -291,6 +307,7 @@ void pFlow::ListPtr<T>::clear()
} }
template<typename T> template<typename T>
inline
void pFlow::ListPtr<T>::clear void pFlow::ListPtr<T>::clear
( (
size_t i size_t i

View File

@ -55,30 +55,14 @@ void pFlow::VectorSingle<T,MemorySpace>::changeCapacity
bool withInit bool withInit
) )
{ {
if constexpr( isTriviallyCopyable_ )
if(withInit)
{ {
if(withInit) resizeInit(view_, actualCap);
{
resizeInit(view_, actualCap);
}
else
{
resizeNoInit(view_, actualCap);
}
}
else if constexpr( isHostAccessible_ )
{
viewType newView(view_.label(), actualCap);
for(auto i=0u; i<min(size_,actualCap); i++)
{
newView(i) = view_(i);
}
view_ = newView;
} }
else else
{ {
static_assert("changeCapacity is not a valid operation for non-trivially-copyable data type on device memory"); resizeNoInit(view_, actualCap);
} }
} }
@ -91,17 +75,8 @@ pFlow::uint32 pFlow::VectorSingle<T,MemorySpace>::reallocateCapacitySize
uint32 s uint32 s
) )
{ {
if constexpr (isTriviallyCopyable_) reallocNoInit(view_, cap);
{ return setSize(s);
reallocNoInit(view_, cap);
}
else
{
viewType newView(view_.label(), cap);
view_ = newView;
}
return setSize(s);
} }
template<typename T, typename MemorySpace> template<typename T, typename MemorySpace>
@ -209,21 +184,19 @@ pFlow::VectorSingle<T,MemorySpace>::VectorSingle
: :
VectorSingle(name, src.capacity(), src.size(), RESERVE()) VectorSingle(name, src.capacity(), src.size(), RESERVE())
{ {
if constexpr(isTriviallyCopyable_) copy(deviceView(), src.deviceView());
{ }
copy(deviceView(), src.deviceView());
} template<typename T, typename MemorySpace>
else if constexpr( isHostAccessible_) pFlow::VectorSingle<T,MemorySpace>::VectorSingle
{ (
for(auto i=0u; i<src.size(); i++) const word& name,
{ const ViewType1D<T, MemorySpace>& src
view_[i] = src.view_[i]; )
} :
} VectorSingle(name, src.size(), src.size(), RESERVE())
else {
{ copy(deviceView(), src);
static_assert("This constructor is not valid for non-trivially copyable data type on device memory");
}
} }
template<typename T, typename MemorySpace> template<typename T, typename MemorySpace>
@ -299,18 +272,7 @@ INLINE_FUNCTION_H
auto pFlow::VectorSingle<T,MemorySpace>::hostViewAll()const auto pFlow::VectorSingle<T,MemorySpace>::hostViewAll()const
{ {
auto hView = Kokkos::create_mirror_view(view_); auto hView = Kokkos::create_mirror_view(view_);
if constexpr(isTriviallyCopyable_) copy(hView, view_);
{
copy(hView, view_);
}
else if constexpr( isHostAccessible_ )
{
// nothing to be done, since it is already a host memory
}
else
{
static_assert("hostViewAll is not valid for non-trivially copyable data type on device memory");
}
return hView; return hView;
} }
@ -319,19 +281,7 @@ INLINE_FUNCTION_H
auto pFlow::VectorSingle<T,MemorySpace>::hostView()const auto pFlow::VectorSingle<T,MemorySpace>::hostView()const
{ {
auto hView = Kokkos::create_mirror_view(deviceView()); auto hView = Kokkos::create_mirror_view(deviceView());
if constexpr(isTriviallyCopyable_) copy(hView, deviceView());
{
copy(hView, deviceView());
}
else if constexpr( isHostAccessible_ )
{
// nothing to be done, since it is already a host memory
}
else
{
static_assert("hostView is not valid for non-trivially copyable data type on device memory");
}
return hView; return hView;
} }
@ -367,6 +317,7 @@ template<typename T, typename MemorySpace>
INLINE_FUNCTION_H INLINE_FUNCTION_H
void pFlow::VectorSingle<T,MemorySpace>::reserve(uint32 cap) void pFlow::VectorSingle<T,MemorySpace>::reserve(uint32 cap)
{ {
if(cap == capacity() ) return;
changeCapacity(cap); changeCapacity(cap);
} }
@ -470,23 +421,9 @@ void pFlow::VectorSingle<T,MemorySpace>::assign
changeSize(srcSize); changeSize(srcSize);
} }
if constexpr( isTriviallyCopyable_ ) // - unmanaged view in the host
{ hostViewType1D<const T> temp(src.data(), srcSize );
// - unmanaged view in the host copy(deviceView(), temp);
hostViewType1D<const T> temp(src.data(), srcSize );
copy(deviceView(), temp);
}
else if constexpr( isHostAccessible_)
{
for(auto i=0u; i<srcSize; i++)
{
view_[i] = src[i];
}
}
else
{
static_assert("Not a valid operation for this data type on memory device");
}
} }
@ -516,21 +453,8 @@ void pFlow::VectorSingle<T,MemorySpace>::assignFromHost(const VectorTypeHost& sr
changeSize(srcSize); changeSize(srcSize);
} }
if constexpr(isTriviallyCopyable_) copy(deviceView(), src.hostView());
{
copy(deviceView(), src.hostView());
}
else if constexpr( isHostAccessible_)
{
for(auto i=0u; i<src.size(); i++)
{
view_[i] = src.view_[i];
}
}
else
{
static_assert("Not a valid operation for this data type on device memory");
}
} }
template<typename T, typename MemorySpace> template<typename T, typename MemorySpace>
@ -553,22 +477,48 @@ void pFlow::VectorSingle<T,MemorySpace>::assign
changeSize(srcSize); changeSize(srcSize);
} }
copy(deviceView(), src.deviceView());
}
if constexpr(isTriviallyCopyable_)
{ template<typename T, typename MemorySpace>
copy(deviceView(), src.deviceView()); template<typename MSpace>
INLINE_FUNCTION_H
void pFlow::VectorSingle<T,MemorySpace>::assignFromDevice(
const VectorSingle<T, MSpace>& src,
bool srcCapacity
)
{
uint32 srcSize = src.size();
uint32 srcCap = src.capacity();
if(srcCapacity && srcCap != capacity()){
reallocateCapacitySize(srcCap, srcSize);
} }
else if constexpr( isHostAccessible_) else {
{ changeSize(srcSize);
for(auto i=0u; i<src.size(); i++)
{
view_[i] = src.view_[i];
}
}
else
{
static_assert("Not a valid operation for this data type on device memory");
} }
copy(deviceView(), src.deviceView());
}
template <typename T, typename MemorySpace>
INLINE_FUNCTION_H
void pFlow::VectorSingle<T, MemorySpace>::append(const ViewType1D<T,MemorySpace>& appVec)
{
uint32 appSize = appVec.size();
if(appSize == 0) return;
uint32 oldS = size();
uint32 newSize = oldS + appSize;
changeSize(newSize);
auto appendView = Kokkos::subview(
view_,
Kokkos::make_pair<uint32>(oldS, newSize));
copy(appendView, appVec);
} }
template <typename T, typename MemorySpace> template <typename T, typename MemorySpace>
@ -589,22 +539,7 @@ void pFlow::VectorSingle<T, MemorySpace>::append
hostViewType1D<const T> temp(appVec.data(), srcSize ); hostViewType1D<const T> temp(appVec.data(), srcSize );
auto dest = Kokkos::subview(view_, Kokkos::make_pair<uint32>(oldSize,newSize)); auto dest = Kokkos::subview(view_, Kokkos::make_pair<uint32>(oldSize,newSize));
if constexpr( isTriviallyCopyable_) copy(dest, temp);
{
copy(dest, temp);
}
else if constexpr( isHostAccessible_)
{
for(auto i=0u; i<appVec.size(); i++)
{
dest[i] = appVec[i];
}
}
else
{
static_assert("not a valid operation for this data type on device memory");
}
} }
template <typename T, typename MemorySpace> template <typename T, typename MemorySpace>
@ -626,21 +561,8 @@ void pFlow::VectorSingle<T, MemorySpace>::append
view_, view_,
Kokkos::make_pair<uint32>(oldS, newSize)); Kokkos::make_pair<uint32>(oldS, newSize));
if constexpr( isTriviallyCopyable_) copy(appendView, appVec.deviceView());
{
copy(appendView, appVec.deviceView());
}
else if constexpr( isHostAccessible_)
{
for(auto i=0u; i<appVec.size(); i++)
{
appendView[i] = appVec.view_[i];
}
}
else
{
static_assert("not a valid operation for this data type on device memory");
}
} }
template <typename T, typename MemorySpace> template <typename T, typename MemorySpace>
@ -813,7 +735,7 @@ bool pFlow::VectorSingle<T,MemorySpace>::insertSetElement
template<typename T, typename MemorySpace> template<typename T, typename MemorySpace>
INLINE_FUNCTION_H INLINE_FUNCTION_H
bool pFlow::VectorSingle<T,MemorySpace>::reorderItems(uint32IndexContainer indices) bool pFlow::VectorSingle<T,MemorySpace>::reorderItems(const uint32IndexContainer& indices)
{ {
if(indices.size() == 0) if(indices.size() == 0)
{ {
@ -831,10 +753,8 @@ bool pFlow::VectorSingle<T,MemorySpace>::reorderItems(uint32IndexContainer indic
return false; return false;
} }
uint32 newSize = indices.size(); uint32 newSize = indices.size();
setSize(newSize);
viewType sortedView(this->name(), newSize); viewType sortedView(this->name(), newSize);
using policy = Kokkos::RangePolicy< execution_space,Kokkos::IndexType<uint32>>; using policy = Kokkos::RangePolicy< execution_space,Kokkos::IndexType<uint32>>;
@ -875,7 +795,10 @@ bool pFlow::VectorSingle<T,MemorySpace>::reorderItems(uint32IndexContainer indic
Kokkos::fence(); Kokkos::fence();
} }
copy(deviceView(), sortedView); setSize(newSize);
copy(deviceView(), sortedView);
return true; return true;
} }

View File

@ -39,9 +39,6 @@ Licence:
namespace pFlow namespace pFlow
{ {
//- Forward
template<typename T, typename MemorySpace>
class VectorSingle;
template<typename T, typename MemorySpace=void> template<typename T, typename MemorySpace=void>
class VectorSingle class VectorSingle
@ -101,6 +98,8 @@ private:
static constexpr static constexpr
bool isTriviallyCopyable_ = std::is_trivially_copyable_v<T>; bool isTriviallyCopyable_ = std::is_trivially_copyable_v<T>;
static_assert(isTriviallyCopyable_, "This type is not trivially copyable");
/// Evaluate capacity based on the input size /// Evaluate capacity based on the input size
static INLINE_FUNCTION_H uint32 evalCapacity(uint32 n) static INLINE_FUNCTION_H uint32 evalCapacity(uint32 n)
{ {
@ -158,6 +157,9 @@ public:
/// Copy construct with a new name (perform deep copy) /// Copy construct with a new name (perform deep copy)
VectorSingle(const word& name, const VectorSingle& src); VectorSingle(const word& name, const VectorSingle& src);
/// Copy construct with a new name (perform deep copy)
VectorSingle(const word& name, const ViewType1D<T, MemorySpace>& src);
/// Copy assignment (perform deep copy from rhs to *this) /// Copy assignment (perform deep copy from rhs to *this)
VectorSingle& operator = (const VectorSingle& rhs) ; VectorSingle& operator = (const VectorSingle& rhs) ;
@ -287,25 +289,10 @@ public:
template<typename MSpace> template<typename MSpace>
INLINE_FUNCTION_H INLINE_FUNCTION_H
void assignFromDevice(const VectorSingle<T, MSpace>& src, bool srcCapacity = true) void assignFromDevice(const VectorSingle<T, MSpace>& src, bool srcCapacity = true);
{
uint32 srcSize = src.size();
uint32 srcCap = src.capacity();
if(srcCapacity && srcCap != capacity()){ INLINE_FUNCTION_H
reallocateCapacitySize(srcCap, srcSize); void append(const ViewType1D<T,MemorySpace>& appVec);
}
else {
changeSize(srcSize);
}
if constexpr(isTriviallyCopyable_){
copy(deviceView(), src.deviceView());
}
else{
static_assert("Not a valid operation for this data type ");
}
}
INLINE_FUNCTION_H INLINE_FUNCTION_H
void append(const std::vector<T>& appVec); void append(const std::vector<T>& appVec);
@ -331,7 +318,7 @@ public:
const ViewType1D<T, memory_space> vals); const ViewType1D<T, memory_space> vals);
INLINE_FUNCTION_H INLINE_FUNCTION_H
bool reorderItems(uint32IndexContainer indices); bool reorderItems(const uint32IndexContainer& indices);
/// @brief push a new element at the end (host call only) /// @brief push a new element at the end (host call only)
/// resize if necessary and works on host accessible vector. /// resize if necessary and works on host accessible vector.

View File

@ -25,6 +25,7 @@ Licence:
#include "types.hpp" #include "types.hpp"
#include "VectorSingle.hpp" #include "VectorSingle.hpp"
#include "wordVectorHost.hpp"
namespace pFlow namespace pFlow
{ {
@ -77,6 +78,8 @@ typedef VectorSingle<realx3x3> realx3x3Vector_D;
typedef VectorSingle<realx3x3, HostSpace> realx3x3Vector_H; typedef VectorSingle<realx3x3, HostSpace> realx3x3Vector_H;
typedef VectorSingle<word, HostSpace> wordVector_H;
} }
#endif #endif

View File

@ -0,0 +1,23 @@
/*------------------------------- 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.
-----------------------------------------------------------------------------*/
#include "wordVectorHost.hpp"

View File

@ -0,0 +1,558 @@
/*------------------------------- 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.
-----------------------------------------------------------------------------*/
#ifndef __wordVectorHost_hpp__
#define __wordVectorHost_hpp__
#include "VectorSingle.hpp"
#include "Vector.hpp"
namespace pFlow
{
template<>
class VectorSingle<word, HostSpace>
{
public:
//- typedefs for accessing data
using VectorType = VectorSingle<word, HostSpace>;
using VectorTypeHost = VectorSingle<word, HostSpace>;
using iterator = word*;
using const_iterator = const word*;
using reference = word&;
using const_reference = const word&;
using value_type = word;
using pointer = word*;
using const_pointer = const word*;
//- typedefs related to memory management
using viewType = ViewType1D<word, HostSpace>;
using device_type = typename viewType::device_type;
using memory_space = typename viewType::memory_space;
using execution_space = typename viewType::execution_space;
private:
// - Data members
Vector<word> container_;
mutable viewType unManagedView_;
// - protected members and methods
/// Is the memory of this vector accessible from Host
static constexpr
bool isHostAccessible_ = true;
/// Is the memory of this vector accessiple from Divce
static constexpr
bool isDeviceAccessible_ = false;
static constexpr
bool isTriviallyCopyable_ = false;
public:
/// Type info
TypeInfoTemplateNV111("VectorSingle", word , memoerySpaceName());
//// - Constructors
/// Empty vector
VectorSingle() = default;
/// Empty vector with a name (capacity = 2)
explicit VectorSingle(const word& name)
:
container_(name)
{}
/// Vector with name and size n
VectorSingle(const word& name, uint32 n)
:
container_(name, n)
{}
/// Vector with name, size and value
VectorSingle(const word& name, uint32 n, const word& val)
:
container_(name, n, val)
{}
/// Vector with name, size (n) and reserved capacity
VectorSingle(const word& name, uint32 cap, uint32 n, const RESERVE& r )
:
container_(name, cap, n, r)
{}
/// Construct with a name and form std::vector (host memory)
VectorSingle(const word& name, const std::vector<word> & src)
:
container_(name, src)
{}
/// Construct with a name and form std::vector (host memory) and with a desired capacity.
VectorSingle(const word& name, const std::vector<word> & src, uint32 cap)
:
container_(name, src, cap)
{}
/// Copy construct (performs deep copy)
VectorSingle(const VectorSingle& src)=default;
/// Copy construct with a new name (perform deep copy)
VectorSingle(const word& name, const VectorSingle& src)
:
container_(name, src.container_)
{}
/// Copy assignment (perform deep copy from rhs to *this)
VectorSingle& operator = (const VectorSingle& rhs)=default;
/// Move construct
VectorSingle(VectorSingle&&) = default;
/// Move assignment
VectorSingle& operator= (VectorSingle&&) = default;
/// @brief Descructor
/// This may not destroy the underlying memory, sice view is
/// shared_ptr and maybe referenced by another object too
~VectorSingle() = default;
/// Clone as a uniquePtr (perform deep copy)
INLINE_FUNCTION_H
uniquePtr<VectorSingle> clone() const
{
return makeUnique<VectorSingle>(*this);
}
//// - Methods
/// Return *this
INLINE_FUNCTION_H
VectorType& VectorField()
{
return *this;
}
/// Return *this
INLINE_FUNCTION_H
const VectorType& VectorField()const
{
return *this;
}
/// Device view range [0,capcity)
INLINE_FUNCTION_H
auto& deviceViewAll()
{
// return un-managed view
unManagedView_ = viewType(container_.data(), container_.capacity());
return unManagedView_;
}
/// Device view range [0,capcity)
INLINE_FUNCTION_H
const auto& deviceViewAll() const
{
// return un-managed view
unManagedView_ = viewType(const_cast<word*>(container_.data()), container_.capacity());
return unManagedView_;
}
/// Device view range [0, size)
INLINE_FUNCTION_H
auto deviceView()const
{
return viewType(const_cast<word*>(container_.data()), container_.size());
}
/// Return a view accessible on Host in range [0,capacity)
INLINE_FUNCTION_H
auto hostViewAll()const
{
return viewType(const_cast<word*>(container_.data()), container_.capacity());
}
/// Return a view accessible on Host in range [0,size)
INLINE_FUNCTION_H
auto hostView()const
{
return viewType(const_cast<word*>(container_.data()), container_.size());
}
/// Name of the vector
INLINE_FUNCTION_H
word name()const
{
return container_.name();
}
/// Size of the vector
INLINE_FUNCTION_H
uint32 size()const
{
return container_.size();
}
// Capcity of the vector
INLINE_FUNCTION_H
uint32 capacity()const
{
return container_.capacity();
}
/// If vector is empty
INLINE_FUNCTION_H
bool empty()const
{
return container_.size()==0uL;
}
/// Reserve capacity for vector
/// Preserve the content.
INLINE_FUNCTION_H
void reserve(uint32 cap)
{
container_.reserve(cap);
}
/// Reallocate memory to new cap and set size to 0.
/*INLINE_FUNCTION_H
void reallocate(uint32 cap);
/// Reallocate memory to new cap and set size to newSize.
/// Do not preserve the content
INLINE_FUNCTION_H
void reallocate(uint32 cap, uint32 newSize);*/
/// Resize the vector and preserve the content
INLINE_FUNCTION_H
void resize(uint32 n)
{
container_.resize(n);
}
/// Resize the vector and assign the value to it.
INLINE_FUNCTION_H
void resize(uint32 n, const word& val)
{
container_.resize(n, val);
}
/// Clear the vector, but keep the allocated memory unchanged
INLINE_FUNCTION_H
void clear()
{
container_.clear();
}
/// Fill the range [0,size) with val
INLINE_FUNCTION_H
void fill(const word& val)
{
container_.fill(val);
}
INLINE_FUNCTION_H
void fill(rangeU32 r, const word& val)
{
container_.fill(r.start(), r.end(), val);
}
/// Change size of the vector and assign val to vector and
INLINE_FUNCTION_H
void assign(size_t n, const word& val)
{
container_.assign(n, val);
}
/// Assign source vector with specified capacity.
/// The size of *this becomes the size of src.
INLINE_FUNCTION_H
void assign(const std::vector<word>& src, uint32 cap)
{
container_.reserve(cap);
this->assign(src);
}
/// Assign source vector.
/// The size of *this becomes the size of src.
/// The capacity of *this becomes the capacity of src.
INLINE_FUNCTION_H
void assign(const std::vector<word>& src)
{
container_.assign(src.begin(), src.end());
}
/// Assign source vector from host side.
/// The size of *this becomes the size of src.
/// The capacity of *this becomes the capacity of src.
INLINE_FUNCTION_H
void assignFromHost(const VectorTypeHost& src)
{
notImplementedFunction;
fatalExit;
}
INLINE_FUNCTION_H
void assign(const VectorType& src, bool srcCapacity = true)
{
notImplementedFunction;
fatalExit;
}
template<typename MSpace>
INLINE_FUNCTION_H
void assignFromDevice(const VectorSingle<word, MSpace>& src, bool srcCapacity = true)
{
notImplementedFunction;
fatalExit;
}
/*INLINE_FUNCTION_H
void append(const ViewType1D<T,MemorySpace>& appVec);
INLINE_FUNCTION_H
void append(const std::vector<T>& appVec);
INLINE_FUNCTION_H
void append(const VectorType& appVec);*/
INLINE_FUNCTION_H
auto getSpan()
{
return span<word>(container_.data(), container_.size());
}
INLINE_FUNCTION_H
auto getSpan()const
{
return span<word>(const_cast<word*>(container_.data()), container_.size());
}
INLINE_FUNCTION_H
bool insertSetElement(const uint32IndexContainer& indices, const word& val)
{
notImplementedFunction;
return false;
}
INLINE_FUNCTION_H
bool insertSetElement(const uint32IndexContainer& indices, const std::vector<word>& vals)
{
notImplementedFunction;
return false;
}
INLINE_FUNCTION_H
bool insertSetElement(
const uint32IndexContainer& indices,
const ViewType1D<word, memory_space> vals)
{
notImplementedFunction;
return false;
}
INLINE_FUNCTION_H
bool reorderItems(const uint32IndexContainer& indices)
{
notImplementedFunction;
return false;
}
/// @brief push a new element at the end (host call only)
/// resize if necessary and works on host accessible vector.
void push_back(const word& val)
{
container_.push_back(val);
}
INLINE_FUNCTION_H
pointer data(){
return container_.data();
}
INLINE_FUNCTION_H
const_pointer data()const{
return container_.data();
}
/// Return begin iterator. It works when devices is host accessible.
auto
begin(){
return container_.begin();
}
/// Return begin iterator. it works when host is accessible.
const auto
begin()const {
return container_.begin();
}
auto end(){
return container_.end();
}
/// Return end iterator. it works when host is accessible.
const auto end()const{
return container_.end();
}
/// Return reference to element i. it works when host is accessible.
word& operator[](size_t i){
return container_[i];
}
const word& operator[](size_t i)const{
return container_[i];
}
//// - IO operations
/// Read vector from stream
FUNCTION_H
bool read(iIstream& is)
{
return container_.read(is);
}
/// Read vector from stream
FUNCTION_H
bool read(iIstream& is, const IOPattern& iop)
{
return container_.read(is, iop);
}
/// Write the vector to os
FUNCTION_H
bool write(iOstream& os, const IOPattern& iop)const
{
return container_.write(os, iop);
}
FUNCTION_H
bool write(iOstream& os)const
{
return container_.write(os);
}
template<typename HostMask>
FUNCTION_H
bool write(iOstream& os, const IOPattern& iop, const HostMask& mask)const
{
notImplementedFunction;
return false;
}
/// Name of the memory space
static
constexpr const char* memoerySpaceName()
{
return memory_space::name();
}
}; // class wordVectorHost
inline iIstream& operator >> (iIstream & is, VectorSingle<word, HostSpace> & ivec )
{
if( !ivec.read(is) )
{
ioErrorInFile (is.name(), is.lineNumber());
fatalExit;
}
return is;
}
inline iOstream& operator << (iOstream& os, const VectorSingle<word, HostSpace>& ovec )
{
if( !ovec.write(os) )
{
ioErrorInFile(os.name(), os.lineNumber());
fatalExit;
}
return os;
}
} // - pFlow
#endif
/*
INLINE_FUNCTION_H
bool append(const deviceViewType1D<T>& dVec, size_t numElems)
{
if(numElems == 0 )return true;
auto oldSize = size_;
auto newSize = size_ + numElems;
if(this->empty() || newSize > capacity() )
{
resize(newSize);
}
else
{
size_ = size_+numElems;
}
auto dSubView = Kokkos::subview(view_, Kokkos::make_pair(oldSize, newSize));
copy(dSubView, dVec);
return true;
}
INLINE_FUNCTION_H
bool append(const VectorSingle& Vec)
{
return append(Vec.deviceView(), Vec.size());
}*/

View File

@ -143,6 +143,16 @@ public:
indexContainer(ind.data(), ind.size()) indexContainer(ind.data(), ind.size())
{} {}
indexContainer(const DeviceViewType& ind):
size_(ind.size()),
views_("indexContainer", size_)
{
copy(views_.h_view, ind);
copy(views_.d_view, ind);
min_ = pFlow::min(views_.d_view, 0, size_);
max_ = pFlow::max(views_.d_view, 0, size_);
}
/// Copy /// Copy
indexContainer(const indexContainer&) = default; indexContainer(const indexContainer&) = default;
@ -240,13 +250,13 @@ public:
void syncViews() void syncViews()
{ {
bool findMinMax = false; bool findMinMax = false;
if(views_.template need_sync<HostType>()) if(views_.template need_sync<DeviceType>())
{ {
Kokkos::deep_copy(views_.d_view, views_.h_view); Kokkos::deep_copy(views_.d_view, views_.h_view);
views_.clear_sync_state(); views_.clear_sync_state();
findMinMax = true; findMinMax = true;
} }
else if(views_.template need_sync<DeviceType>()) else if(views_.template need_sync<HostType>())
{ {
Kokkos::deep_copy(views_.h_view, views_.d_view); Kokkos::deep_copy(views_.h_view, views_.d_view);
views_.clear_sync_state(); views_.clear_sync_state();
@ -260,6 +270,12 @@ public:
} }
} }
void syncViews(uint32 newSize)
{
size_ = newSize;
syncViews();
}
}; };

View File

@ -121,21 +121,45 @@ public:
return true; return true;
} }
inline
InternalFieldType& internal()
{
return internal_;
}
inline
const InternalFieldType& internal()const
{
return internal_;
}
FieldAccessType thisField()const FieldAccessType thisField()const
{ {
return FieldAccessType( if constexpr(isDeviceAccessible<execution_space>())
this->size(), return FieldAccessType(
this->indexList().deviceViewAll(), this->size(),
internal_.deviceViewAll()); this->indexList().deviceViewAll(),
internal_.deviceViewAll());
else
return FieldAccessType(
this->size(),
this->boundary().indexListHost().deviceViewAll(),
internal_.deviceViewAll());
} }
FieldAccessType mirrorField()const FieldAccessType mirrorField()const
{ {
return FieldAccessType( if constexpr(isDeviceAccessible<execution_space>())
this->mirrorBoundary().size(), return FieldAccessType(
this->mirrorBoundary().indexList().deviceViewAll(), this->mirrorBoundary().size(),
internal_.deviceViewAll()); this->mirrorBoundary().indexList().deviceViewAll(),
internal_.deviceViewAll());
else
return FieldAccessType(
this->mirrorBoundary().size(),
this->mirrorBoundary().indexListHost().deviceViewAll(),
internal_.deviceViewAll());
} }
virtual virtual
@ -144,11 +168,6 @@ public:
virtual virtual
const ProcVectorType& neighborProcField()const; const ProcVectorType& neighborProcField()const;
void fill(const std::any& val)override
{
return;
}
virtual virtual
void fill(const T& val) void fill(const T& val)
{ {

View File

@ -43,7 +43,7 @@ protected:
const boundaryList& boundaries_; const boundaryList& boundaries_;
uint32 slaveToMasterUpdateIter_ = -1; uint32 slaveToMasterUpdateIter_ = static_cast<uint32>(-1);
public: public:
@ -95,7 +95,7 @@ public:
bool slaveToMasterUpdateRequested()const bool slaveToMasterUpdateRequested()const
{ {
return slaveToMasterUpdateIter_ != -1; return slaveToMasterUpdateIter_ != static_cast<uint32>(-1);
} }

View File

@ -147,10 +147,6 @@ public:
} }
const Time& time()const; const Time& time()const;
virtual
void fill(const std::any& val)=0;
}; };

View File

@ -52,9 +52,29 @@ bool pFlow::internalField<T, MemorySpace>::insert(const anyList& varList)
} }
return true; return true;
} }
template<class T, class MemorySpace>
bool pFlow::internalField<T, MemorySpace>::rearrange(const anyList& varList)
{
const word eventName = message::eventName(message::ITEM_REARRANGE);
const auto& indices = varList.getObject<uint32IndexContainer>(
eventName);
field_.reserve( internalPoints_.capacity());
field_.resize(internalPoints_.size());
if(!field_.reorderItems(indices))
{
fatalErrorInFunction<<
"cannot reorder items in field "<< name()<<endl;
return false;
}
return true;
}
template<class T, class MemorySpace> template<class T, class MemorySpace>
pFlow::internalField<T, MemorySpace>::internalField pFlow::internalField<T, MemorySpace>::internalField
( (
@ -166,15 +186,15 @@ bool pFlow::internalField<T, MemorySpace>:: hearChanges
{ {
// do nothing // do nothing
} }
if(msg.equivalentTo(message::ITEM_REARRANGE))
{
notImplementedFunction;
return false;
}
if(msg.equivalentTo(message::ITEM_INSERT)) if(msg.equivalentTo(message::ITEM_INSERT))
{ {
return insert(varList); return insert(varList);
} }
if(msg.equivalentTo(message::ITEM_REARRANGE))
{
return rearrange(varList);
}
return true; return true;
} }

View File

@ -73,6 +73,8 @@ protected:
bool insert(const anyList& varList); bool insert(const anyList& varList);
bool rearrange(const anyList& varList);
public: public:
internalField( internalField(

View File

@ -302,10 +302,10 @@ public:
//// - IO operations //// - IO operations
/// read from stream /// read from stream
virtual bool read(iIstream& is); bool read(iIstream& is) override;
/// write to stream /// write to stream
virtual bool write(iOstream& os) const; bool write(iOstream& os) const override;
}; };

View File

@ -46,6 +46,9 @@ public:
const dictionary& dict, const dictionary& dict,
repository* owner=nullptr); repository* owner=nullptr);
using dictionary::read;
using dictionary::write;
/// read from stream /// read from stream
bool read(iIstream& is, const IOPattern& iop) override; bool read(iIstream& is, const IOPattern& iop) override;

View File

@ -47,13 +47,17 @@ public:
BNDR_TRANSFER = 9, // boundary indices transfered BNDR_TRANSFER = 9, // boundary indices transfered
BNDR_RESET = 10, // boundary indices reset entirely BNDR_RESET = 10, // boundary indices reset entirely
BNDR_DELETE = 11, // boundary indices deleted BNDR_DELETE = 11, // boundary indices deleted
BNDR_APPEND = 12 BNDR_APPEND = 12, //
BNDR_PROCTRANSFER_SEND = 13, // transfer of data between processors step 1
BNDR_PROCTRANSFER_RECIEVE = 14, // transfer of data between processors step 2
BNDR_PROCTRANSFER_WAITFILL = 15, // wait for data and fill the field
BNDR_PROC_SIZE_CHANGED = 16
}; };
private: private:
static constexpr size_t numberOfEvents_ = 13; static constexpr size_t numberOfEvents_ = 17;
std::bitset<numberOfEvents_> events_{0x0000}; std::bitset<numberOfEvents_> events_{0x0000};
@ -72,7 +76,11 @@ private:
"transferredIndices", "transferredIndices",
"", "",
"deletedIndices", "deletedIndices",
"appendedIndices" "appendedIndices",
"transferredIndices",
"numToRecieve",
"insertedIndices",
"size"
}; };
public: public:

View File

@ -1,6 +1,14 @@
#include <chrono>
#include <thread>
#include "globalSettings.hpp" #include "globalSettings.hpp"
const double pFlow::gSettings::vectorGrowthFactor__ = 1.1;
const double pFlow::gSettings::vectorGrowthFactor__ = 1.1;
void pFlow::gSettings::sleepMiliSeconds(int miliSeconds)
{
std::this_thread::sleep_for(std::chrono::milliseconds(miliSeconds));
}

View File

@ -28,6 +28,8 @@ namespace pFlow::gSettings
extern const double vectorGrowthFactor__; extern const double vectorGrowthFactor__;
void sleepMiliSeconds(int miliSeconds);
} }

View File

@ -37,6 +37,10 @@ Licence:
#define CONSUME_PARAM(x) (void)(x); #define CONSUME_PARAM(x) (void)(x);
#if defined(pFlow_Build_Cuda) && !defined(__CUDACC__)
#define __CUDACC__
#endif
#ifdef __CUDACC__ #ifdef __CUDACC__
#define INLINE_FUNCTION_HD inline __host__ __device__ #define INLINE_FUNCTION_HD inline __host__ __device__
#define INLINE_FUNCTION_D inline __device__ #define INLINE_FUNCTION_D inline __device__

View File

@ -145,6 +145,15 @@ public:
} }
#endif #endif
static
bool builtForMPI()
{
#ifdef pFlow_Build_MPI
return true;
#else
return false;
#endif
}
}; };
} }

View File

@ -29,7 +29,6 @@ Licence:
#include "processors.hpp" #include "processors.hpp"
#include "streams.hpp" #include "streams.hpp"
static int numVarsInitialized__ = 0;
#ifdef pFlow_Build_MPI #ifdef pFlow_Build_MPI

View File

@ -42,12 +42,22 @@ pFlow::uniquePtr<pFlow::oFstream> pFlow::IOfileHeader::outStream()const
return osPtr; return osPtr;
} }
pFlow::IOfileHeader::IOfileHeader pFlow::uniquePtr<pFlow::oFstream> pFlow::IOfileHeader::dummyOutStream() const
( {
const objectFile& objf auto osPtr = makeUnique<oFstream>( CWD()+word("dummyFile") , outFileBinary());
)
: if(osPtr && owner())
objectFile(objf) {
auto outPrecision = owner()->outFilePrecision();
osPtr->precision(static_cast<int>(outPrecision));
}
return osPtr;
}
pFlow::IOfileHeader::IOfileHeader(
const objectFile &objf)
: objectFile(objf)
{} {}
pFlow::fileSystem pFlow::IOfileHeader::path() const pFlow::fileSystem pFlow::IOfileHeader::path() const

View File

@ -58,6 +58,8 @@ protected:
// - ouput file stream // - ouput file stream
uniquePtr<oFstream> outStream()const; uniquePtr<oFstream> outStream()const;
uniquePtr<oFstream> dummyOutStream()const;
public: public:
// with owner // with owner

View File

@ -122,18 +122,35 @@ bool pFlow::IOobject::writeObject() const
if(ioPattern().thisCallWrite()) if(ioPattern().thisCallWrite())
{ {
if( ioPattern().thisProcWriteData())
if(auto ptrOS = outStream(); ptrOS )
{ {
return writeObject(ptrOS()); if(auto ptrOS = outStream(); ptrOS )
{
return writeObject(ptrOS());
}
else
{
warningInFunction<<
"error in opening file "<< path() <<endl;
return false;
}
} }
else else
{ {
warningInFunction<<
"error in opening file "<< path() <<endl; if(auto ptrOS = dummyOutStream(); ptrOS )
return false; {
return writeObject(ptrOS());
}
else
{
warningInFunction<<
"error in opening file "<< path() <<endl;
return false;
}
} }
} }
return true; return true;

View File

@ -65,6 +65,16 @@ pFlow::baseTimeControl::baseTimeControl
} }
pFlow::baseTimeControl::baseTimeControl(int32 start, int32 end, int32 stride, const word &intervalPrefix)
:
isTimeStep_(true),
iRange_(start, end, std::max(stride,1)),
intervalPrefix_(
intervalPrefix.size()==0uL? word("interval"): intervalPrefix+"Interval"
)
{
}
bool pFlow::baseTimeControl::timeEvent(uint32 iter, real t, real dt) const bool pFlow::baseTimeControl::timeEvent(uint32 iter, real t, real dt) const
{ {
if(isTimeStep_) if(isTimeStep_)

View File

@ -46,6 +46,13 @@ public:
real defStartTime = 0.0 real defStartTime = 0.0
); );
baseTimeControl(
int32 start,
int32 end,
int32 stride,
const word& intervalPrefix = ""
);
inline bool isTimeStep() const inline bool isTimeStep() const
{ {
return isTimeStep_; return isTimeStep_;

View File

@ -18,7 +18,7 @@ Licence:
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
#include "math.hpp"
#include "timeControl.hpp" #include "timeControl.hpp"
#include "dictionary.hpp" #include "dictionary.hpp"
@ -137,14 +137,14 @@ pFlow::word pFlow::timeControl::timeName()const
bool pFlow::timeControl::finalTime()const bool pFlow::timeControl::finalTime()const
{ {
if( currentTime_ >= endTime_ ) return true; if( currentTime_ >= endTime_ ) return true;
if( abs(currentTime_-endTime_) < 0.5*dt_ )return true; if( std::abs(currentTime_-endTime_) < 0.5*dt_ )return true;
return false; return false;
} }
bool pFlow::timeControl::reachedStopAt()const bool pFlow::timeControl::reachedStopAt()const
{ {
if( currentTime_ >= stopAt_ ) return true; if( currentTime_ >= stopAt_ ) return true;
if( abs(currentTime_-stopAt_) < 0.5*dt_ )return true; if( std::abs(currentTime_-stopAt_) < 0.5*dt_ )return true;
return false; return false;
} }
@ -154,7 +154,7 @@ void pFlow::timeControl::checkForOutputToFile()
bool save = false; bool save = false;
if(managedExternaly_) if(managedExternaly_)
{ {
if( abs(currentTime_-writeTime_) < 0.5*dt_) if( std::abs(currentTime_-writeTime_) < 0.5*dt_)
{ {
save = true; save = true;
lastSaved_ = currentTime_; lastSaved_ = currentTime_;
@ -162,12 +162,12 @@ void pFlow::timeControl::checkForOutputToFile()
} }
else else
{ {
if ( abs(currentTime_ - lastSaved_ - saveInterval_) < 0.5 * dt_ ) if ( std::abs(currentTime_ - lastSaved_ - saveInterval_) < 0.5 * dt_ )
{ {
lastSaved_ = currentTime_; lastSaved_ = currentTime_;
save = true; save = true;
} }
else if( abs(currentTime_ - lastSaved_) < min( pow(10.0,-1.0*timePrecision_), 0.5 *dt_) ) else if( std::abs(currentTime_ - lastSaved_) < std::min( pow(10.0,-1.0*timePrecision_), 0.5 *dt_) )
{ {
lastSaved_ = currentTime_; lastSaved_ = currentTime_;
save = true; save = true;

View File

@ -37,16 +37,15 @@ namespace pFlow
template< template<
typename T, typename T
typename Deleter = std::default_delete<T>
> >
class uniquePtr class uniquePtr
: :
public std::unique_ptr<T, Deleter> public std::unique_ptr<T>
{ {
public: public:
using uniquePtrType = std::unique_ptr<T, Deleter>; using uniquePtrType = std::unique_ptr<T>;
// using base constructors // using base constructors
using uniquePtrType::unique_ptr; using uniquePtrType::unique_ptr;

View File

@ -325,7 +325,7 @@ void pFlow::iTstream::reset()
size_t pFlow::iTstream::tell() size_t pFlow::iTstream::tell()
{ {
notImplementedFunction; notImplementedFunction;
return -1; return static_cast<size_t>(-1);
} }
const pFlow::tokenList& pFlow::iTstream::tokens()const const pFlow::tokenList& pFlow::iTstream::tokens()const

View File

@ -22,7 +22,7 @@ template<typename T>
bool pFlow::writeDataAsciiBinary(iOstream& os, span<T> data) bool pFlow::writeDataAsciiBinary(iOstream& os, span<T> data)
{ {
if( os.isBinary() ) if( std::is_trivially_copyable_v<T> && os.isBinary() )
{ {
// first write the number of data // first write the number of data
uint64 numData = data.size(); uint64 numData = data.size();
@ -83,7 +83,7 @@ bool pFlow::readDataAsciiBinary
) )
{ {
if(is.isBinary()) if(std::is_trivially_copyable_v<T> && is.isBinary())
{ {
data.clear(); data.clear();
// read length of data // read length of data

View File

@ -42,6 +42,7 @@ void pFlow::boundaryBase::setNewIndices
unSyncLists(); unSyncLists();
} }
bool pFlow::boundaryBase::appendNewIndices bool pFlow::boundaryBase::appendNewIndices
( (
const uint32Vector_D& newIndices const uint32Vector_D& newIndices
@ -98,15 +99,11 @@ bool pFlow::boundaryBase::removeIndices
keepIndices keepIndices
); );
if(!internal_.deletePoints(removeIndices)) if(!setRemoveKeepIndices(removeIndices, keepIndices))
{ {
fatalErrorInFunction<<
"error in deleting points from boundary "<< name()<<endl;
return false; return false;
} }
setNewIndices(keepIndices);
anyList aList; anyList aList;
aList.emplaceBack( aList.emplaceBack(
@ -129,7 +126,26 @@ bool pFlow::boundaryBase::removeIndices
return true; return true;
} }
bool pFlow::boundaryBase::transferPoints bool pFlow::boundaryBase::setRemoveKeepIndices
(
const uint32Vector_D &removeIndices,
const uint32Vector_D &keepIndices
)
{
if(!internal_.deletePoints(removeIndices))
{
fatalErrorInFunction<<
"error in deleting points from boundary "<< name()<<endl;
return false;
}
setNewIndices(keepIndices);
return true;
}
bool pFlow::boundaryBase::transferPointsToMirror
( (
uint32 numTransfer, uint32 numTransfer,
const uint32Vector_D& transferMask, const uint32Vector_D& transferMask,
@ -188,6 +204,8 @@ pFlow::boundaryBase::boundaryBase
indexList_(groupNames("indexList", dict.name())), indexList_(groupNames("indexList", dict.name())),
indexListHost_(groupNames("hostIndexList",dict.name())), indexListHost_(groupNames("hostIndexList",dict.name())),
neighborLength_(dict.getVal<real>("neighborLength")), neighborLength_(dict.getVal<real>("neighborLength")),
updateInetrval_(dict.getVal<uint32>("updateInterval")),
boundaryExtntionLengthRatio_(dict.getVal<real>("boundaryExtntionLengthRatio")),
internal_(internal), internal_(internal),
boundaries_(bndrs), boundaries_(bndrs),
thisBoundaryIndex_(thisIndex), thisBoundaryIndex_(thisIndex),

View File

@ -68,6 +68,12 @@ private:
/// The length defined for creating neighbor list /// The length defined for creating neighbor list
real neighborLength_; real neighborLength_;
/// time steps between successive update of boundary lists
uint32 updateInetrval_;
/// the extra boundary extension beyound actual limits of boundary
real boundaryExtntionLengthRatio_;
/// a reference to internal points /// a reference to internal points
internalPoints& internal_; internalPoints& internal_;
@ -102,7 +108,11 @@ protected:
uint32 numRemove, uint32 numRemove,
const uint32Vector_D& removeMask); const uint32Vector_D& removeMask);
bool transferPoints( bool setRemoveKeepIndices(
const uint32Vector_D& removeIndices,
const uint32Vector_D& keepIndices);
bool transferPointsToMirror(
uint32 numTransfer, uint32 numTransfer,
const uint32Vector_D& transferMask, const uint32Vector_D& transferMask,
uint32 transferBoundaryIndex, uint32 transferBoundaryIndex,
@ -122,6 +132,12 @@ protected:
} }
} }
/// Is this iter the right time for updating bounday list
bool boundaryListUpdate(uint32 iter)const
{
return iter%updateInetrval_ == 0u || iter == 0u;
}
/// Update this boundary data in two steps (1 and 2). /// Update this boundary data in two steps (1 and 2).
/// This is called after calling beforeIteration for /// This is called after calling beforeIteration for
/// all boundaries, so any particle addition, deletion, /// all boundaries, so any particle addition, deletion,
@ -129,11 +145,25 @@ protected:
/// This two-step update help to have a flexible mechanism /// This two-step update help to have a flexible mechanism
/// for data transfer, mostly for MPI related jobs. /// for data transfer, mostly for MPI related jobs.
virtual virtual
bool updataBoundary(int step) bool updataBoundaryData(int step)
{ {
return true; return true;
} }
/// @brief This method is called when a transfer of data
/// is to be performed between processors (in afterIteration).
/// @param step is the step in the transfer of data.
/// @return true: if operation requires at least one additional step
/// to complete. false: if the operation is complete and no need for
/// additional step in operation.
virtual
bool transferData(uint32 iter, int step)
{
return false;
}
public: public:
TypeInfo("boundaryBase"); TypeInfo("boundaryBase");
@ -173,20 +203,21 @@ public:
/// The length from boundary plane into the domain /// The length from boundary plane into the domain
/// where beyond that distance internal points exist. /// where beyond that distance internal points exist.
/// By conventions is it always equal to neighborLength_ /// By conventions is it always equal to neighborLength_
inline
real neighborLengthIntoInternal()const real neighborLengthIntoInternal()const
{ {
return neighborLength_; return neighborLength_;
} }
/// The distance length from boundary plane /// The distance length from boundary plane
/// where neighbor particles exist in that distance. /// where neighbor particles still exist in that distance.
/// This length may be modified in each boundary type /// This length may be modified in each boundary type
/// as required. In this case the boundaryExtensionLength /// as required. In this case the boundaryExtensionLength
/// method should also be modified accordingly. /// method should also be modified accordingly.
virtual virtual
real neighborLength()const real neighborLength()const
{ {
return neighborLength_; return (1+boundaryExtntionLengthRatio_)*neighborLength_;
} }
/// The extention length (in vector form) for the boundary /// The extention length (in vector form) for the boundary
@ -197,7 +228,7 @@ public:
virtual virtual
realx3 boundaryExtensionLength()const realx3 boundaryExtensionLength()const
{ {
return {0,0,0}; return -boundaryExtntionLengthRatio_*neighborLength_ * boundaryPlane_.normal();
} }
inline inline
@ -335,6 +366,18 @@ public:
virtual virtual
const realx3Vector_D& neighborProcPoints()const; const realx3Vector_D& neighborProcPoints()const;
virtual
uint32 numToTransfer()const
{
return 0u;
}
virtual
uint32 numToRecieve()const
{
return 0u;
}
/// - static create /// - static create
static static
uniquePtr<boundaryBase> create uniquePtr<boundaryBase> create

View File

@ -67,14 +67,26 @@ void pFlow::boundaryBaseKernels::createRemoveKeepIndices
uint32 numRemove, uint32 numRemove,
const uint32Vector_D& removeMask, const uint32Vector_D& removeMask,
uint32Vector_D& removeIndices, uint32Vector_D& removeIndices,
uint32Vector_D& keepIndices uint32Vector_D& keepIndices,
bool exactCap
) )
{ {
uint32 numTotal = indices.size(); uint32 numTotal = indices.size();
uint32 numKeep = numTotal - numRemove; uint32 numKeep = numTotal - numRemove;
if(exactCap)
{
removeIndices.reallocate(numRemove, numRemove);
keepIndices.reallocate(numKeep, numKeep);
}
else
{
removeIndices.clear();
removeIndices.resize(numRemove);
keepIndices.clear();
keepIndices.resize(numKeep);
}
removeIndices.reallocate(numRemove, numRemove);
keepIndices.reallocate(numKeep, numKeep);
auto maskD = removeMask.deviceViewAll(); auto maskD = removeMask.deviceViewAll();
const auto& removeD = removeIndices.deviceViewAll(); const auto& removeD = removeIndices.deviceViewAll();

View File

@ -38,7 +38,8 @@ void createRemoveKeepIndices(
uint32 numRemove, uint32 numRemove,
const uint32Vector_D& removeMask, const uint32Vector_D& removeMask,
uint32Vector_D& removeIndices, uint32Vector_D& removeIndices,
uint32Vector_D& keepIndices); uint32Vector_D& keepIndices,
bool exactCap = true);
} }

Some files were not shown because too many files have changed in this diff Show More