Interaction folder is finalized with adjustable box and tested for rotating drum

This commit is contained in:
Hamidreza Norouzi
2024-03-24 01:46:19 -07:00
parent be56d8ee2e
commit d21b7276e1
48 changed files with 2252 additions and 3260 deletions

View File

@ -0,0 +1,67 @@
/*------------------------------- 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 "NBS.hpp"
pFlow::NBS::NBS
(
const dictionary& dict,
const box& domainBox,
real minBSSize,
real maxBSSize,
const deviceViewType1D<realx3> &position,
const pFlagTypeDevice &flags,
const deviceViewType1D<real> &diam,
uint32 nWallPoints,
uint32 nWallElements,
const ViewType1D<realx3,memory_space>& wallPoints,
const ViewType1D<uint32x3,memory_space>& wallVertices
)
:
particleWallContactSearchs<NBS>(
dict,
domainBox,
minBSSize,
maxBSSize,
position,
flags,
diam),
sizeRatio_(max(dict.getVal<real>("sizeRatio"), 1.0)),
cellExtent_(max(dict.getVal<real>("cellExtent"), 0.5)),
adjustableBox_(dict.getVal<Logical>("adjustableBox")),
NBSLevel0_
(
this->domainBox_,
maxBSSize,
sizeRatio_,
position,
flags,
adjustableBox_()
),
cellsWallLevel0_
(
cellExtent_,
nWallPoints,
nWallElements,
wallPoints,
wallVertices
)
{
}

View File

@ -0,0 +1,148 @@
/*------------------------------- 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 __NBS_hpp__
#define __NBS_hpp__
#include "particleWallContactSearchs.hpp"
#include "NBSLevel0.hpp"
#include "cellsWallLevel0.hpp"
#include "Vector.hpp"
namespace pFlow
{
class NBS
:
public particleWallContactSearchs<NBS>
{
public:
using CellIterator = typename NBSLevel0::CellIterator;
private:
real sizeRatio_ = 1.0;
real cellExtent_ = 0.5;
Logical adjustableBox_;
NBSLevel0 NBSLevel0_;
cellsWallLevel0 cellsWallLevel0_;
protected:
friend particleWallContactSearchs<NBS>;
bool impl_broadSearch
(
csPairContainerType& ppPairs,
csPairContainerType& pwPairs,
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice& flags,
const deviceViewType1D<real>& diameter
)
{
bool searchBoxChanged;
if( !NBSLevel0_.broadSearch(
ppPairs,
pointPos,
flags,
diameter,
searchBoxChanged))
{
fatalErrorInFunction<<
"Error in broadSearch for NBS (particle-particle)"<<endl;
return false;
}
if(!cellsWallLevel0_.broadSearch(
pwPairs,
NBSLevel0_.getSearchCells(),
NBSLevel0_.getCellIterator()))
{
fatalErrorInFunction<<
"Error in broadSearch for NBS (particle-wall)"<<endl;
return false;
}
return true;
}
public:
TypeInfoNV("NBS");
NBS(
const dictionary& dict,
const box& domainBox,
real minBSSize,
real maxBSSize,
const deviceViewType1D<realx3> &position,
const pFlagTypeDevice &flags,
const deviceViewType1D<real> &diam,
uint32 nWallPoints,
uint32 nWallElements,
const ViewType1D<realx3,memory_space>& wallPoints,
const ViewType1D<uint32x3,memory_space>& wallVertices);
INLINE_FUNCTION_HD
NBS(const NBS&) = default;
INLINE_FUNCTION_HD
NBS(NBS&&) = default;
INLINE_FUNCTION_HD
NBS& operator = (const NBS&) = default;
INLINE_FUNCTION_HD
NBS& operator = (NBS&&) = default;
INLINE_FUNCTION_HD
~NBS()=default;
//// - Methods
uint32 numLevels()const
{
return 1;
}
auto getCellIterator([[maybe_unused]] uint32 lvl)const
{
return NBSLevel0_.getCellIterator();
}
Vector<cells> getDomainCellsLevels()const
{
return Vector<cells>("Cells", 1, NBSLevel0_.getDomainCells());
}
};
}
#endif

View File

@ -0,0 +1,118 @@
/*------------------------------- 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 "NBSLevel0.hpp"
#include "streams.hpp"
bool pFlow::NBSLevel0::findPairs
(
csPairContainerType &pairs,
const deviceViewType1D<realx3> &pointPos,
const pFlagTypeDevice &flags,
const deviceViewType1D<real> &diameter
)
{
uint32 getFull = 1;
// loop until the container size fits the numebr of contact pairs
while (getFull > 0)
{
getFull = pFlow::NBSLevel0Kernels::findPairsCount
(
pairs,
sizeRatio_,
pointPos,
flags,
diameter,
getCellIterator()
);
if(getFull)
{
// - resize the container
// note that getFull now shows the number of failed insertions.
uint32 len = max(getFull,500u) ;
auto oldCap = pairs.capacity();
pairs.increaseCapacityBy(len);
INFORMATION<< "The contact pair container capacity increased from "<<
oldCap << " to "<<pairs.capacity()<<" in NBSLevel0."<<END_INFO;
}
Kokkos::fence();
}
return true;
}
pFlow::NBSLevel0::NBSLevel0
(
const box& domain,
real cellSize,
real sizeRatio,
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice& flags,
bool adjustableBox
)
:
mapperNBS
(
domain,
cellSize,
pointPos,
flags,
adjustableBox,
true
),
sizeRatio_(sizeRatio)
{
}
bool pFlow::NBSLevel0::broadSearch
(
csPairContainerType &pairs,
const deviceViewType1D<realx3> &pointPos,
const pFlagTypeDevice &flags,
const deviceViewType1D<real> &diameter,
bool& searchBoxChanged
)
{
if(!build(pointPos, flags, searchBoxChanged))
{
fatalErrorInFunction;
return false;
}
if(!findPairs(pairs, pointPos, flags, diameter))
{
fatalErrorInFunction;
return false;
}
return true;
}

View File

@ -0,0 +1,98 @@
/*------------------------------- 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 __NBSLevel0_hpp__
#define __NBSLevel0_hpp__
#include "NBSLevel0Kernels.hpp"
#include "mapperNBS.hpp"
namespace pFlow
{
class NBSLevel0
:
public mapperNBS
{
public:
using MapperType = mapperNBS;
using CellIterator = typename MapperType::CellIterator;
using HeadType = typename MapperType::HeadType;
using NextType = typename MapperType::NextType;
private:
real sizeRatio_ = 1.0;
bool findPairs
(
csPairContainerType& pairs,
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice& flags,
const deviceViewType1D<real>& diameter
);
public:
TypeInfoNV("NBSLevel0");
INLINE_FUNCTION_HD
NBSLevel0() = default;
NBSLevel0(
const box& domain,
real cellSize,
real sizeRatio,
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice& flags,
bool adjustableBox);
INLINE_FUNCTION_HD
NBSLevel0(const NBSLevel0&) = default;
INLINE_FUNCTION_HD
NBSLevel0& operator = (const NBSLevel0&) = default;
INLINE_FUNCTION_HD
~NBSLevel0()=default;
bool broadSearch(
csPairContainerType& pairs,
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice& flags,
const deviceViewType1D<real>& diameter,
bool& searchBoxChanged);
};
} // pFlow
#endif // __NBSLevel0_hpp__

View File

@ -0,0 +1,83 @@
/*------------------------------- 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 "mapperNBS.hpp"
#include "contactSearchGlobals.hpp"
#include "streams.hpp"
namespace pFlow::NBSLevel0Kernels
{
using mdrPolicyFindPairs =
Kokkos::MDRangePolicy<
Kokkos::IndexType<uint32>,
Kokkos::Rank<3>,
Kokkos::Schedule<Kokkos::Dynamic>,
DefaultExecutionSpace>;
template<typename T>
INLINE_FUNCTION_HD
void Swap(T& x, T& y)
{
T tmp = x;
x = y;
y = tmp;
}
INLINE_FUNCTION_HD
bool sphereSphereCheck(const realx3& p1, const realx3 p2, real d1, real d2)
{
return length(p2-p1) < 0.5*(d2+d1);
}
inline
uint32 findPairsCount
(
csPairContainerType& pairs,
real sizeRatio,
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice& flags,
const deviceViewType1D<real>& diameter,
mapperNBS::CellIterator cellIter
)
{
auto nCells = cellIter.numCells();
mdrPolicyFindPairs
mdrPolicy(
{0,0,0},
{nCells.x(), nCells.y(), nCells.z()} );
uint32 notInsertedPairs = 0u;
Kokkos::parallel_reduce (
"pFlow::NBSLevel0Kernels::findPairsCount",
mdrPolicy,
LAMBDA_HD(uint32 i, uint32 j, uint32 k, uint32& getFullUpdate){
#include "NBSLoop.hpp"
}, notInsertedPairs);
return notInsertedPairs;
}
}

View File

@ -0,0 +1,100 @@
/*------------------------------- 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.
-----------------------------------------------------------------------------*/
uint32 m = cellIter.start(i,j,k);
int32x3 currentCell(i,j,k);
uint32 n = mapperNBS::NoPos;
while( m != mapperNBS::NoPos)
{
auto p_m = pointPos[m];
auto d_m = sizeRatio* diameter[m];
// the same cell
n = cellIter.getNext(m);
while(n != mapperNBS::NoPos)
{
auto p_n = pointPos[n];
auto d_n = sizeRatio*diameter[n];
if( sphereSphereCheck(p_m, p_n, d_m, d_n) )
{
auto ln = n;
auto lm = m;
if(lm>ln) Swap(lm,ln);
if( pairs.insert(lm,ln) == -1)
{
getFullUpdate++;
}
}
n = cellIter.getNext(n);;
}
// neighbor cells
int32x3 neighborCell;
for(uint32 ni=0u; ni<13; ni++)
{
if(ni==0) neighborCell = currentCell + int32x3( 0, 0,-1);
else if(ni==1) neighborCell = currentCell + int32x3(-1, 0,-1);
else if(ni==2) neighborCell = currentCell + int32x3(-1, 0, 0);
else if(ni==3) neighborCell = currentCell + int32x3(-1, 0, 1);
else if(ni==4) neighborCell = currentCell + int32x3( 0,-1,-1);
else if(ni==5) neighborCell = currentCell + int32x3( 0,-1, 0);
else if(ni==6) neighborCell = currentCell + int32x3( 0,-1, 1);
else if(ni==7) neighborCell = currentCell + int32x3(-1,-1,-1);
else if(ni==8) neighborCell = currentCell + int32x3(-1,-1, 0);
else if(ni==9) neighborCell = currentCell + int32x3(-1,-1, 1);
else if(ni==10) neighborCell = currentCell + int32x3( 1,-1,-1);
else if(ni==11) neighborCell = currentCell + int32x3( 1,-1, 0);
else if(ni==12) neighborCell = currentCell + int32x3( 1,-1, 1);
if( neighborCell.x()>=0 && neighborCell.y()>=0 && neighborCell.z()>=0 &&
neighborCell.x()<nCells.x() && neighborCell.y()<nCells.y() && neighborCell.z()<nCells.z() )
{
n = cellIter.start(neighborCell.x(), neighborCell.y(), neighborCell.z());
while(n != mapperNBS::NoPos)
{
auto p_n = pointPos[n];
auto d_n = sizeRatio*diameter[n];
if(sphereSphereCheck(p_m, p_n, d_m, d_n))
{
auto ln = n;
auto lm = m;
if(lm>ln) Swap(lm,ln);
if( pairs.insert(lm,ln) == -1)
{
getFullUpdate++;
}
}
n = cellIter.next(n);
}
}
}
m = cellIter.next(m);
}

View File

@ -0,0 +1,195 @@
/*------------------------------- 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 "cellsWallLevel0.hpp"
#include "streams.hpp"
pFlow::cellsWallLevel0::cellsWallLevel0
(
real cellExtent,
uint32 numPoints,
uint32 numElements,
const ViewType1D<realx3,
memory_space> &points,
const ViewType1D<uint32x3, memory_space> &vertices
)
:
cellExtent_( max(cellExtent, 0.5 ) ),
numElements_(numElements),
numPoints_(numPoints),
vertices_(vertices),
points_(points)
{
allocateArrays();
}
bool pFlow::cellsWallLevel0::resetElements
(
uint32 numElements,
uint32 numPoints,
ViewType1D<realx3, memory_space> &points,
ViewType1D<uint32x3, memory_space> &vertices
)
{
numElements_ = numElements;
numPoints_ = numPoints;
points_ = points;
vertices_ = vertices;
allocateArrays();
return true;
}
bool pFlow::cellsWallLevel0::broadSearch
(
csPairContainerType &pairs,
const cells& searchBox,
const mapperNBS::CellIterator &particleMap
)
{
// map walls onto the cells
this->build(searchBox);
this->particleWallFindPairs(pairs, particleMap);
return true;
}
bool pFlow::cellsWallLevel0::build(const cells & searchBox)
{
Kokkos::parallel_for(
"pFlow::cellsWallLevel0::build",
deviceRPolicyStatic(0,numElements_),
CLASS_LAMBDA_HD(uint32 i)
{
auto v = vertices_[i];
auto p1 = points_[v.x()];
auto p2 = points_[v.y()];
auto p3 = points_[v.z()];
realx3 minP;
realx3 maxP;
searchBox.extendBox(p1, p2, p3, cellExtent_, minP, maxP);
elementBox_[i] = iBoxType(searchBox.pointIndex(minP), searchBox.pointIndex(maxP));
});
Kokkos::fence();
return true;
}
bool pFlow::cellsWallLevel0::particleWallFindPairs
(
csPairContainerType &pairs,
const mapperNBS::CellIterator &particleMap
)
{
uint32 getFull = 1;
while (getFull)
{
getFull = findPairsElementRangeCount(pairs, particleMap);
if(getFull)
{
// - resize the container
// note that getFull now shows the number of failed insertions.
uint32 len = max(getFull, 50u);
auto oldCap = pairs.capacity();
pairs.increaseCapacityBy(len);
INFORMATION<<"Contact pair container capacity increased from "<<
oldCap << " to "
<< pairs.capacity() <<" in cellsWallLevel0."<<END_INFO;
Kokkos::fence();
}
}
return true;
}
pFlow::int32 pFlow::cellsWallLevel0::findPairsElementRangeCount
(
csPairContainerType &pairs,
const mapperNBS::CellIterator &particleMap
)
{
uint32 getFull =0;
//const auto pwPairs = pairs;
const auto elementBox = elementBox_;
Kokkos::parallel_reduce(
"pFlow::cellsWallLevel0::findPairsElementRangeCount",
tpPWContactSearch(numElements_, Kokkos::AUTO),
LAMBDA_HD(
const typename tpPWContactSearch::member_type & teamMember,
uint32& valueToUpdate){
const uint32 iTri = teamMember.league_rank();
const auto triBox = elementBox[iTri];
uint32 getFull2 = 0;
auto bExtent = boxExtent(triBox);
uint32 numCellBox = bExtent.x()*bExtent.y()*bExtent.z();
Kokkos::parallel_reduce(
Kokkos::TeamThreadRange( teamMember, numCellBox ),
[&] ( const uint32 linIndex, uint32 &innerUpdate )
{
int32x3 cell;
indexToCell(linIndex, triBox, cell);
uint32 n = particleMap.start(cell.x(),cell.y(),cell.z());
while( n != particleMap.NoPos)
{
// id is wall id the pair is (particle id, wall id)
if( pairs.insert(
static_cast<csIdType>(n),
static_cast<csIdType>(iTri) ) == -1 )
innerUpdate++;
n = particleMap.next(n);
}
},
getFull2
);
if ( teamMember.team_rank() == 0 ) valueToUpdate += getFull2;
},
getFull
);
return getFull;
}

View File

@ -0,0 +1,139 @@
/*------------------------------- 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 __cellsWallLevel0_hpp__
#define __cellsWallLevel0_hpp__
#include "contactSearchGlobals.hpp"
#include "contactSearchFunctions.hpp"
#include "mapperNBS.hpp"
#include "iBox.hpp"
namespace pFlow
{
class cellsWallLevel0
{
public:
using execution_space = csExecutionSpace;
using memory_space = typename execution_space::memory_space;
using iBoxType = iBox<int32>;
class TagFindCellRange2{};
private:
// - box extent
real cellExtent_ = 0.5;
// - number of triangle elements
uint32 numElements_ = 0;
// - number of points
uint32 numPoints_ = 0;
// - ref to vectices (borrowed)
ViewType1D<uint32x3, memory_space> vertices_;
// - ref to points in the trisurface (borrowed)
ViewType1D<realx3, memory_space> points_;
// cell range of element/triangle bounding box
ViewType1D<iBoxType, memory_space> elementBox_;
using tpPWContactSearch = Kokkos::TeamPolicy<
execution_space,
Kokkos::Schedule<Kokkos::Dynamic>,
Kokkos::IndexType<uint32>>;
FUNCTION_H
void allocateArrays()
{
reallocNoInit( elementBox_, numElements_);
}
public:
TypeInfoNV("cellsWallLevel0");
INLINE_FUNCTION_HD
cellsWallLevel0(){}
FUNCTION_H
cellsWallLevel0(
real cellExtent,
uint32 numPoints,
uint32 numElements,
const ViewType1D<realx3,memory_space>& points,
const ViewType1D<uint32x3,memory_space>& vertices);
// - host call
// reset triangle elements if they have changed
bool resetElements(
uint32 numElements,
uint32 numPoints,
ViewType1D<realx3, memory_space>& points,
ViewType1D<uint32x3, memory_space>& vertices);
INLINE_FUNCTION_HD
iBoxType elementBox(uint32 i)const
{
return elementBox_[i];
}
INLINE_FUNCTION_HD
uint32 numElements()const
{
return numElements_;
}
bool broadSearch(
csPairContainerType& pairs,
const cells& searchBox,
const mapperNBS::CellIterator& particleMap);
bool build(const cells& searchBox);
bool particleWallFindPairs(
csPairContainerType& pairs,
const mapperNBS::CellIterator& particleMap);
int32 findPairsElementRangeCount(
csPairContainerType& pairs,
const mapperNBS::CellIterator& particleMap);
}; // cellsWallLevel0
} // pFlow
#endif // __cellsWallLevel0_hpp__

View File

@ -0,0 +1,194 @@
/*------------------------------- 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 "mapperNBS.hpp"
#include "mapperNBSKernels.hpp"
#include "streams.hpp"
pFlow::uint32 pFlow::mapperNBS::checkInterval_ = 1000;
pFlow::real pFlow::mapperNBS::enlargementFactor_ = 1;
bool pFlow::mapperNBS::setSearchBox
(
const deviceViewType1D<realx3> &pointPos,
const pFlagTypeDevice &flags,
real cellSize
)
{
box domainBox = domainCells_.domainBox();
if(adjustableBox_)
{
lastCheckForBox_ = buildCount_;
realx3 minP;
realx3 maxP;
pFlow::mapperNBSKernels::findPointExtends
(
pointPos,
flags,
minP, maxP
);
minP = max( minP - enlargementFactor_*cellSize, domainBox.minPoint());
maxP = min( maxP + enlargementFactor_*cellSize, domainBox.maxPoint());
box searchBox = {minP, maxP};
searchCells_ = cells(searchBox, cellSize);
INFORMATION<<"Search box for contact search has changed: "<<
"search box is ["<<searchCells_.domainBox().minPoint()<<
" "<<searchCells_.domainBox().maxPoint()<<"]"<<END_INFO;
return true;
}
else
{
searchCells_ = cells(domainBox, cellSize);
INFORMATION<<"Search box for contact search is: ["
<< domainBox.minPoint()<<" "<<domainBox.maxPoint()<<"]"<<END_INFO;
return false;
}
}
void pFlow::mapperNBS::allocateArrays(rangeU32 nextRng)
{
checkAllocateNext(nextRng);
nullifyNext(nextRng);
reallocFill(head_, searchCells_.nx(), searchCells_.ny(), searchCells_.nz(), NoPos);
}
void pFlow::mapperNBS::checkAllocateNext(rangeU32 nextRng)
{
auto newCap = nextRng.end();
if( nextCapacity_ < newCap)
{
nextCapacity_ = newCap;
if(!nextOwner_)return;
reallocNoInit(next_, nextCapacity_);
}
}
void pFlow::mapperNBS::nullifyHead()
{
fill(head_, NoPos);
}
void pFlow::mapperNBS::nullifyNext(rangeU32 nextRng)
{
if(!nextOwner_)return;
fill(next_, nextRng, NoPos);
}
pFlow::mapperNBS::mapperNBS(
const box &domain,
real cellSize,
const deviceViewType1D<realx3> &pointPos,
const pFlagTypeDevice &flags,
bool adjustableBox,
bool nextOwner
)
:
domainCells_(domain, cellSize),
searchCells_(domain, cellSize),
adjustableBox_(adjustableBox),
nextOwner_(nextOwner)
{
setSearchBox(pointPos, flags, cellSize);
allocateArrays(flags.activeRange());
}
bool pFlow::mapperNBS::build
(
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice & flags,
bool& searchBoxChanged
)
{
auto aRange = flags.activeRange();
buildCount_++;
if(adjustableBox_ && buildCount_%checkInterval_ == 0)
{
if(searchBoxChanged =
setSearchBox(pointPos, flags, searchCells_.cellSize());searchBoxChanged)
{
allocateArrays(aRange);
}
}
else
{
checkAllocateNext(aRange);
nullifyHead();
nullifyNext(aRange);
}
if( adjustableBox_ )
{
if(!pFlow::mapperNBSKernels::buildListsReduce(
searchCells_,
head_,
next_,
pointPos,
flags) )
{
buildCount_++;
setSearchBox(pointPos, flags, searchCells_.cellSize());
searchBoxChanged = true;
allocateArrays(flags.activeRange());
if(!pFlow::mapperNBSKernels::buildListsReduce(
searchCells_,
head_,
next_,
pointPos,
flags))
{
fatalErrorInFunction<<"failed to build list in anjustable search box mode!"<<endl;
return false;
}
}
}
else
{
pFlow::mapperNBSKernels::buildLists(
searchCells_,
head_,
next_,
pointPos,
flags
);
searchBoxChanged = false;
}
return true;
}

View File

@ -0,0 +1,212 @@
/*------------------------------- 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 __mapperNBS_hpp__
#define __mapperNBS_hpp__
#include "phasicFlowKokkos.hpp"
#include "pointFlag.hpp"
#include "cells.hpp"
//#include "contactSearchFunctions.hpp"
namespace pFlow
{
class mapperNBS
{
public:
using HeadType = deviceViewType3D<uint32>;
using NextType = deviceViewType1D<uint32>;
static constexpr uint32 NoPos = 0xFFFFFFFF;
class CellIterator
{
private:
HeadType head_;
NextType next_;
public:
CellIterator(const HeadType& head, const NextType& next)
:
head_(head),
next_(next)
{}
static constexpr uint32 NoPos = 0xFFFFFFFF;
INLINE_FUNCTION_HD
int32x3 numCells()const {
return int32x3(head_.extent(0), head_.extent(1), head_.extent(2));}
INLINE_FUNCTION_HD
uint32 start(int32 i, int32 j, int32 k)const {
return head_(i,j,k); }
INLINE_FUNCTION_HD
uint32 getNext(uint32 n)const {
if(n == NoPos ) return NoPos;
return next_(n); }
INLINE_FUNCTION_HD
uint32 next(uint32 n)const{
return next_(n);}
};
private:
cells domainCells_;
cells searchCells_;
HeadType head_{"NBS::head",1,1,1};
NextType next_{"NBS::next", 1};
uint32 nextCapacity_ = 0;
uint32 lastCheckForBox_ = 0;
uint32 buildCount_ = 0;
bool adjustableBox_ = false;
bool nextOwner_ = true;
static uint32 checkInterval_;
static real enlargementFactor_;
bool setSearchBox(
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice& flags,
real cellSize
);
void allocateArrays(rangeU32 nextRng);
void checkAllocateNext(rangeU32 nextRng);
void nullifyHead();
void nullifyNext(rangeU32 nextRng);
public:
TypeInfoNV("mapperNBS");
INLINE_FUNCTION_HD
mapperNBS() = default;
mapperNBS(
const box& domain,
real cellSize,
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice& flags,
bool adjustableBox,
bool nextOwner = true);
INLINE_FUNCTION_HD
mapperNBS(const mapperNBS&) = default;
INLINE_FUNCTION_HD
mapperNBS(mapperNBS&&) = default;
INLINE_FUNCTION_HD
mapperNBS& operator = (const mapperNBS&) = default;
INLINE_FUNCTION_HD
mapperNBS& operator = (mapperNBS&&) = default;
INLINE_FUNCTION_HD
~mapperNBS()=default;
//// - Methods
auto getCellIterator()const
{
return CellIterator(head_, next_);
}
const auto& getDomainCells()const
{
return domainCells_;
}
const auto& getSearchCells()const
{
return searchCells_;
}
bool build(
const deviceViewType1D<realx3>& pointPos,
const pFlagTypeDevice& flags,
bool& searchBoxChanged);
};
} // pFlow
#endif // __mapperNBS_hpp__
/*
INLINE_FUNCTION_HD
auto& head()
{
return head_;
}
INLINE_FUNCTION_HD
auto& next()
{
return next_;
}
INLINE_FUNCTION_HD
const auto& head()const
{
return head_;
}
INLINE_FUNCTION_HD
const auto& next()const
{
return next_;
}
INLINE_FUNCTION_HD
auto& pointPosition()
{
return pointPosition_;
}
*/

View File

@ -0,0 +1,192 @@
/*------------------------------- 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 "mapperNBSKernels.hpp"
void pFlow::mapperNBSKernels::findPointExtends
(
const deviceViewType1D<realx3>& points,
const pFlagTypeDevice& flags,
realx3& minPoint,
realx3& maxPoint
)
{
if(flags.numActive() == 0)
{
minPoint = {0,0,0};
maxPoint = {0,0,0};
return;
}
real minX;
real minY;
real minZ;
real maxX;
real maxY;
real maxZ;
auto aRange = flags.activeRange();
Kokkos::parallel_reduce(
"pFlow::mapperNBSKernels::findPointExtends",
deviceRPolicyStatic(aRange.start(), aRange.end()),
LAMBDA_HD(
uint32 i,
real& minXUpdate,
real& minYUpdate,
real& minZUpdate,
real& maxXUpdate,
real& maxYUpdate,
real& maxZUpdate)
{
if(flags(i))
{
auto p = points(i);
minXUpdate = min(p.x(), minXUpdate);
minYUpdate = min(p.y(), minYUpdate);
minZUpdate = min(p.z(), minZUpdate);
maxXUpdate = max(p.x(), maxXUpdate);
maxYUpdate = max(p.y(), maxYUpdate);
maxZUpdate = max(p.z(), maxZUpdate);
}
},
Kokkos::Min<real>(minX),
Kokkos::Min<real>(minY),
Kokkos::Min<real>(minZ),
Kokkos::Max<real>(maxX),
Kokkos::Max<real>(maxY),
Kokkos::Max<real>(maxZ)
);
minPoint = {minX, minY, minZ};
maxPoint = {maxX, maxY, maxZ};
}
bool pFlow::mapperNBSKernels::buildListsReduce
(
const cells &searchCell,
const deviceViewType3D<uint32> &head,
const deviceViewType1D<uint32> &next,
const deviceViewType1D<realx3> &points,
const pFlagTypeDevice &flags
)
{
uint32 numOut = 0;
auto aRange = flags.activeRange();
if(flags.isAllActive())
{
Kokkos::parallel_reduce
(
"pFlow::mapperNBSKernels::buildListsReduce",
deviceRPolicyStatic(aRange.start(), aRange.end()),
LAMBDA_HD(uint32 i, uint32& valToUpdate)
{
int32x3 ind;
if( searchCell.pointIndexInDomain(points[i], ind) )
{
uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i);
next[i] = old;
}
else
{
valToUpdate++;
}
},
numOut
);
}
else
{
Kokkos::parallel_reduce
(
"pFlow::mapperNBSKernels::buildListsReduce",
deviceRPolicyStatic(aRange.start(), aRange.end()),
LAMBDA_HD(uint32 i, uint32& valToUpdate)
{
int32x3 ind;
if( flags(i) )
{
if( searchCell.pointIndexInDomain(points[i], ind) )
{
uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i);
next[i] = old;
}
else
{
valToUpdate++;
}
}
},
numOut
);
}
return numOut == 0u ;
}
bool pFlow::mapperNBSKernels::buildLists
(
const cells &searchCell,
const deviceViewType3D<uint32> &head,
const deviceViewType1D<uint32> &next,
const deviceViewType1D<realx3> &points,
const pFlagTypeDevice &flags
)
{
auto aRange = flags.activeRange();
if(flags.isAllActive() )
{
Kokkos::parallel_for
(
"pFlow::mapperNBSKernels::buildLists",
deviceRPolicyStatic(aRange.start(), aRange.end()),
LAMBDA_HD(uint32 i)
{
auto ind = searchCell.pointIndex(points[i]);
uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i);
next[i] = old;
}
);
Kokkos::fence();
}
else
{
Kokkos::parallel_for
(
"pFlow::mapperNBSKernels::buildLists",
deviceRPolicyStatic(aRange.start(), aRange.end()),
LAMBDA_HD(uint32 i)
{
if( flags(i) )
{
auto ind = searchCell.pointIndex(points[i]);
uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i);
next[i] = old;
}
}
);
Kokkos::fence();
}
return true;
}

View File

@ -0,0 +1,49 @@
/*------------------------------- 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 "cells.hpp"
#include "pointFlag.hpp"
namespace pFlow::mapperNBSKernels
{
void findPointExtends(
const deviceViewType1D<realx3>& points,
const pFlagTypeDevice& flags,
realx3& minPoint,
realx3& maxPoint);
bool buildListsReduce(
const cells& searchCell,
const deviceViewType3D<uint32>& head,
const deviceViewType1D<uint32>& next,
const deviceViewType1D<realx3>& points,
const pFlagTypeDevice& flags);
bool buildLists(
const cells& searchCell,
const deviceViewType3D<uint32>& head,
const deviceViewType1D<uint32>& next,
const deviceViewType1D<realx3>& points,
const pFlagTypeDevice& flags);
}