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

InsertionRegion.cpp
Go to the documentation of this file.
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
template<typename ShapeType>
bool pFlow::InsertionRegion<ShapeType>::checkForContact
(
const realx3Vector& pos,
const realVector& diams,
const realx3& p,
const real& d
)
{
ForAll(i, pos)
{
if( length(pos[i]-p) < 0.5*(diams[i]+d) ) return true;
}
return false;
}
template<typename ShapeType>
pFlow::InsertionRegion<ShapeType>::InsertionRegion
(
const word& name,
const insertion& instn,
const ShapeType& shapes
)
:
insertionRegion(name, instn),
shapes_(shapes)
{}
template<typename ShapeType>
bool pFlow::InsertionRegion<ShapeType>::insertParticles
(
uint32 iter,
real t,
real dt,
wordVector& names,
realx3Vector& positions,
bool& insertionOccured
)
{
insertionOccured = false;
if(!insertionTime(iter, t, dt)) return true;
uint32 newNum = numberToBeInserted(iter, t, dt);
if(newNum == 0) return true;
// get the internal box
auto internalBox = pStruct().internalDomainBox();
if( !(internalBox.minPoint() < internalBox.maxPoint()))
{
WARNING<<"Minimum point of internal point is not lower than "<<
"the maximum point \n"<<
"minimum point: "<< internalBox.minPoint()<<
"\nmaximum point:"<<internalBox.maxPoint()<<END_WARNING;
return false;
}
names.reserve(max(newNum,names.capacity()));
names.clear();
positions.reserve(max(newNum,positions.capacity()));
positions.clear();
auto allPositions = realx3Vector("allPositions");
auto allDiameters = realVector("allDiameters");
auto& mix = mixture();
auto& pReg = pRegion();
real maxDiam = shapes_.maxBoundingSphere();
auto minP = pReg.minPoint() - maxDiam;
auto maxP = pReg.maxPoint() + maxDiam;
if(Insertion().checkForCollision())
{
// check for collision with already inserted particles
// so, use selector to select particles in the simulation
auto bDict = dictionary("boxInfo");
bDict.add("min", minP);
bDict.add("max", maxP);
auto selector = pStructSelector::create(
"box",
pStruct(),
bDict);
allPositions = selector().selectedPointPositions();
allDiameters = selectedFieldVals<real>
(
selector(),
Insertion().diameterName()
);
}
auto collCheck = collisionCheck(
{minP, maxP},
maxDiam,
allPositions,
allDiameters);
uint32 numInserted = 0;
uint32 idx;
word name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
real d = shapes_.boundingDiameter(idx);
for(uint32 i=0; i< 100*newNum ; ++i)
{
realx3 p = pReg.peek();
// check if point is inside internal box
if(!internalBox.isInside(p))continue;
if( collCheck.checkPoint( p, d) )
{
names.push_back(name);
positions.push_back(p);
numInserted++;
if( numInserted == newNum ) break;
// add this new particle to collision check set
allDiameters.push_back(d);
allPositions.push_back(p);
collCheck.mapLastAddedParticle();
// obtain next shape name and diameter
name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
d = shapes_.boundingDiameter(idx);
}
}
insertionOccured = true;
addToNumInserted(numInserted);
return numInserted == newNum;
}
/*if(!checkForCollision)
{
realVector diams("diams", newNum, 0, RESERVE());
uint32 idx;
word name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
real d = shapes_.boundingDiameter(idx);
for(uint32 i=0; i< 100*newNum ; ++i)
{
realx3 p = pReg.peek();
// check if point is inside internal box
if(!internalBox.isInside(p))continue;
if( !checkForContact(positions, diams, p, d) )
{
names.push_back(name);
positions.push_back(p);
diams.push_back(d);
numInserted++;
if( numInserted == newNum ) break;
name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
d = shapes_.boundingDiameter(idx);
}
}
}
else
{
real maxDiam = shapes_.maxBoundingSphere();
auto minP = pReg.minPoint() - maxDiam;
auto maxP = pReg.maxPoint() + maxDiam;
auto bDict = dictionary("boxInfo");
bDict.add("min", minP);
bDict.add("max", maxP);
auto selector = pStructSelector::create(
"box",
pStruct(),
bDict);
auto allPositions = selector().selectedPointPositions();
auto allDiameters = selectedFieldVals<real>(selector(), "diameter");
auto collCheck = collisionCheck(
{minP, maxP},
maxDiam,
allPositions,
allDiameters);
uint32 idx;
word name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
real d = shapes_.boundingDiameter(idx);
for(uint32 i=0; i< 100*newNum ; ++i)
{
realx3 p = pReg.peek();
// check if point is inside internal box
if(!internalBox.isInside(p))continue;
if( collCheck.checkPoint( p, d) )
{
names.push_back(name);
positions.push_back(p);
numInserted++;
if( numInserted == newNum ) break;
// add this new particle to collision check set
allDiameters.push_back(d);
allPositions.push_back(p);
collCheck.mapLastAddedParticle();
// obtain next shape name and diameter
name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
d = shapes_.boundingDiameter(idx);
}
}
}*/
pFlow::realVector
Vector< real > realVector
Definition: Vectors.hpp:46
pFlow::real
float real
Definition: builtinTypes.hpp:45
pFlow::collisionCheck
Definition: collisionCheck.hpp:13
pFlow::algorithms::KOKKOS::max
INLINE_FUNCTION_H Type max(const Type *first, uint32 numElems)
Definition: kokkosAlgorithms.hpp:104
pFlow::Vector::reserve
void reserve(size_t cap)
Reserve capacity for vector Preserve the content.
Definition: Vector.hpp:284
pFlow::uint32
unsigned int uint32
Definition: builtinTypes.hpp:56
pFlow::word
std::string word
Definition: builtinTypes.hpp:64
pFlow::InsertionRegion::checkForContact
static bool checkForContact(const realx3Vector &pos, const realVector &diams, const realx3 &p, const real &d)
Definition: InsertionRegion.cpp:23
pFlow::insertionRegion
This class defines all the necessary enteties for defining an insertion region.
Definition: insertionRegion.hpp:86
END_WARNING
#define END_WARNING
Definition: streams.hpp:44
length
INLINE_FUNCTION_HD T length(const triple< T > &v1)
pFlow::Vector::capacity
auto capacity() const
Capacity of the vector.
Definition: Vector.hpp:271
pFlow::InsertionRegion::InsertionRegion
InsertionRegion(const word &name, const insertion &instn, const ShapeType &shapes)
Construct from dictionary.
Definition: InsertionRegion.cpp:41
ForAll
#define ForAll(i, container)
Definition: pFlowMacros.hpp:75
pFlow::realx3Vector
Vector< realx3 > realx3Vector
Definition: Vectors.hpp:48
pStruct
auto & pStruct
Definition: setPointStructure.hpp:24
pFlow::InsertionRegion::insertParticles
bool insertParticles(uint32 iter, real t, real dt, wordVector &names, realx3Vector &pos, bool &insertionOccured)
Insert particles at current time t Check if currentTime is the right moment for particle insertion.
Definition: InsertionRegion.cpp:54
pFlow::triple< real >
pFlow::Vector< realx3 >
pFlow::Insertion
This class manages all the insertion regions for particles insertion in the simulation.
Definition: Insertion.hpp:56
pFlow::dictionary
Dictionary holds a set of data entries or sub-dictionaries that are enclosed in a curely braces or ar...
Definition: dictionary.hpp:67
pFlow::insertion
Base class for particle insertion.
Definition: insertion.hpp:35
WARNING
#define WARNING
Definition: streams.hpp:43