# PhasicFlow: src/Particles/GrainParticles/grainParticles/grainParticles.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.

grainParticles.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.
-----------------------------------------------------------------------------*/
#include "grainParticles.hpp"
#include "systemControl.hpp"
#include "vocabs.hpp"
#include "grainParticlesKernels.hpp"
bool pFlow::grainParticles::initializeParticles()
{
using exeSpace = typename realPointField_D::execution_space;
using policy = Kokkos::RangePolicy<
exeSpace,
Kokkos::IndexType<uint32>>;
auto [minIndex, maxIndex] = minMax(shapeIndex().internal());
if( !grains_.indexValid(maxIndex) )
{
fatalErrorInFunction<<
"the maximum value of shapeIndex is "<< maxIndex <<
" which is not valid."<<endl;
return false;
}
auto aPointsMask = dynPointStruct().activePointsMaskDevice();
auto aRange = aPointsMask.activeRange();
auto field_shapeIndex = shapeIndex().deviceView();
auto field_diameter = grainDiameter_.deviceView();
auto field_coarseGrainFactor = coarseGrainFactor_.deviceView();
auto field_mass = mass_.deviceView();
auto field_propId = propertyId_.deviceView();
auto field_I = I_.deviceView();
// get info from grains shape
realVector_D d("diameter", grains_.boundingDiameter());
realVector_D coarseGrainFactor("coarse Grain Factor", grains_.coarseGrainFactor());
realVector_D mass("mass",grains_.mass());
uint32Vector_D propId("propId", grains_.shapePropertyIds());
realVector_D I("I", grains_.Inertia());
auto d_d = d.deviceView();
auto d_coarseGrainFactor = coarseGrainFactor.deviceView();
auto d_mass = mass.deviceView();
auto d_propId = propId.deviceView();
auto d_I = I.deviceView();
Kokkos::parallel_for(
"particles::initInertia",
policy(aRange.start(), aRange.end()),
LAMBDA_HD(uint32 i)
{
if(aPointsMask(i))
{
uint32 index = field_shapeIndex[i];
field_I[i] = d_I[index];
field_diameter[i] = d_d[index];
field_coarseGrainFactor[i] = d_coarseGrainFactor[index];
field_mass[i] = d_mass[index];
field_propId[i] = d_propId[index];
}
});
Kokkos::fence();
return true;
}
bool
pFlow::grainParticles::getParticlesInfoFromShape(
const wordVector& shapeNames,
uint32Vector& propIds,
realVector& diams,
realVector& coarseGrainFactors,
realVector& m,
realVector& Is,
uint32Vector& shIndex
)
{
auto numNew = static_cast< uint32 >(shapeNames.size());
propIds.clear();
propIds.reserve(numNew);
diams.clear();
diams.reserve(numNew);
coarseGrainFactors.clear();
coarseGrainFactors.reserve(numNew);
m.clear();
m.reserve(numNew);
Is.clear();
Is.reserve(numNew);
shIndex.clear();
shIndex.reserve(numNew);
for(const auto& name:shapeNames)
{
uint32 indx;
if(grains_.shapeNameToIndex(name,indx))
{
shIndex.push_back(indx);
Is.push_back( grains_.Inertia(indx));
m.push_back(grains_.mass(indx));
diams.push_back(grains_.boundingDiameter(indx));
coarseGrainFactors.push_back(grains_.coarseGrainFactor(indx));
propIds.push_back( grains_.propertyId(indx));
}
else
{
fatalErrorInFunction<<"Shape name "<< name <<
"does not exist. The list is "<<grains_.shapeNameList()<<endl;
return false;
}
}
return true;
}
pFlow::grainParticles::grainParticles(
systemControl &control,
const property& prop
)
:
particles(control),
grains_
(
shapeFile__,
&control.caseSetup(),
prop
),
propertyId_
(
objectFile
(
"propertyId",
"",
objectFile::READ_NEVER,
objectFile::WRITE_NEVER
),
dynPointStruct(),
0u
),
grainDiameter_
(
objectFile(
"diameter",
"",
objectFile::READ_NEVER,
objectFile::WRITE_NEVER),
dynPointStruct(),
0.00000000001
),
coarseGrainFactor_
(
objectFile(
"coarseGrainFactor",
"",
objectFile::READ_NEVER,
objectFile::WRITE_NEVER),
dynPointStruct(),
0.00000000001
),
mass_
(
objectFile(
"mass",
"",
objectFile::READ_NEVER,
objectFile::WRITE_NEVER),
dynPointStruct(),
0.0000000001
),
I_
(
objectFile
(
"I",
"",
objectFile::READ_NEVER,
objectFile::WRITE_NEVER
),
dynPointStruct(),
static_cast<real>(0.0000000001)
),
rVelocity_
(
objectFile
(
"rVelocity",
"",
objectFile::READ_IF_PRESENT,
objectFile::WRITE_ALWAYS
),
dynPointStruct(),
zero3
),
rAcceleration_
(
objectFile(
"rAcceleration",
"",
objectFile::READ_IF_PRESENT,
objectFile::WRITE_ALWAYS
),
dynPointStruct(),
zero3
),
boundaryGrainParticles_
(
dynPointStruct().boundaries(),
*this
),
accelerationTimer_(
"Acceleration", &this->timers() ),
intPredictTimer_(
"Integration-predict", &this->timers() ),
intCorrectTimer_(
"Integration-correct", &this->timers() ),
fieldUpdateTimer_(
"fieldUpdate", &this->timers() )
{
auto intMethod = control.settingsDict().getVal<word>("integrationMethod");
REPORT(1)<<"Creating integration method "<<Green_Text(intMethod)
<< " for rotational velocity."<<END_REPORT;
rVelIntegration_ = integration::create
(
"rVelocity",
dynPointStruct(),
intMethod,
rVelocity_.field()
);
if( !rVelIntegration_ )
{
fatalErrorInFunction<<
" error in creating integration object for rVelocity. \n";
fatalExit;
}
WARNING<<"setFields for rVelIntegration_"<<END_WARNING;
if(!initializeParticles())
{
fatalErrorInFunction;
fatalExit;
}
}
bool pFlow::grainParticles::beforeIteration()
{
particles::beforeIteration();
intPredictTimer_.start();
auto dt = this->dt();
dynPointStruct().predict(dt, accelertion());
rVelIntegration_().predict(dt,rVelocity_, rAcceleration_);
intPredictTimer_.end();
fieldUpdateTimer_.start();
propertyId_.updateBoundariesSlaveToMasterIfRequested();
grainDiameter_.updateBoundariesSlaveToMasterIfRequested();
coarseGrainFactor_.updateBoundariesSlaveToMasterIfRequested();
mass_.updateBoundariesSlaveToMasterIfRequested();
I_.updateBoundariesSlaveToMasterIfRequested();
rVelocity_.updateBoundariesSlaveToMasterIfRequested();
rAcceleration_.updateBoundariesSlaveToMasterIfRequested();
rVelIntegration_().updateBoundariesSlaveToMasterIfRequested();
fieldUpdateTimer_.end();
return true;
}
bool pFlow::grainParticles::iterate()
{
timeInfo ti = TimeInfo();
realx3 g = control().g();
particles::iterate();
accelerationTimer_.start();
pFlow::grainParticlesKernels::acceleration(
g,
mass().deviceViewAll(),
contactForce().deviceViewAll(),
I().deviceViewAll(),
contactTorque().deviceViewAll(),
dynPointStruct().activePointsMaskDevice(),
accelertion().deviceViewAll(),
rAcceleration().deviceViewAll()
);
for(auto& bndry:boundaryGrainParticles_)
{
bndry->acceleration(ti, g);
}
accelerationTimer_.end();
intCorrectTimer_.start();
if(!dynPointStruct().correct(dt(), accelertion()))
{
return false;
}
if(!rVelIntegration_().correct(
dt(),
rVelocity_,
rAcceleration_))
{
return false;
}
intCorrectTimer_.end();
return true;
}
bool pFlow::grainParticles::insertParticles
(
const realx3Vector &position,
const wordVector &shapesNames,
const anyList &setVarList
)
{
anyList newVarList(setVarList);
realVector mass("mass");
realVector I("I");
realVector diameter("diameter");
realVector coarseGrainFactor("coarseGrainFactor");
uint32Vector propId("propId");
uint32Vector shapeIdx("shapeIdx");
if(!getParticlesInfoFromShape(
shapesNames,
propId,
diameter,
coarseGrainFactor,
mass,
I,
shapeIdx))
{
return false;
}
newVarList.emplaceBack(
mass_.name()+"Vector",
std::move(mass));
newVarList.emplaceBack(
I_.name()+"Vector",
std::move(I));
newVarList.emplaceBack(
grainDiameter_.name()+"Vector",
std::move(diameter));
newVarList.emplaceBack(
coarseGrainFactor_.name()+"Vector",
std::move(coarseGrainFactor));
newVarList.emplaceBack(
propertyId_.name()+"Vector",
std::move(propId));
newVarList.emplaceBack(
shapeIndex().name()+"Vector",
std::move(shapeIdx));
if(!dynPointStruct().insertPoints(position, newVarList))
{
return false;
}
return true;
}
pFlow::word pFlow::grainParticles::shapeTypeName()const
{
return "grain";
}
const pFlow::shape &pFlow::grainParticles::getShapes() const
{
return grains_;
}
void pFlow::grainParticles::boundingSphereMinMax
(
real & minDiam,
real& maxDiam
)const
{
minDiam = grains_.minBoundingSphere();
maxDiam = grains_.maxBoundingSphere();
}
pFlow::minMax
Pair< T, T > minMax(const internalField< T, MemorySpace > &iField)
Definition: internalFieldAlgorithms.hpp:132
pFlow::grainParticles::mass_
realPointField_D mass_
mass of particles field
Definition: grainParticles.hpp:63
Green_Text
#define Green_Text(text)
Definition: iOstream.hpp:42
pFlow::particles::beforeIteration
bool beforeIteration() override
This is called in time loop, before iterate.
Definition: particles.cpp:86
pFlow::grainParticlesKernels::acceleration
void acceleration(const realx3 &g, const deviceViewType1D< real > &mass, const deviceViewType1D< realx3 > &force, const deviceViewType1D< real > &I, const deviceViewType1D< realx3 > &torque, const pFlagTypeDevice &incld, deviceViewType1D< realx3 > lAcc, deviceViewType1D< realx3 > rAcc)
Definition: grainParticlesKernels.cpp:62
pFlow::particles::iterate
bool iterate() override
This is called in time loop.
Definition: particles.cpp:104
pFlow::grainParticles::rVelocity_
realx3PointField_D rVelocity_
pointField of rotational Velocity of particles on device
Definition: grainParticles.hpp:69
pFlow::grainShape::coarseGrainFactor
real coarseGrainFactor(uint32 index) const
Definition: grainShape.cpp:113
grainParticlesKernels.hpp
pFlow::grainParticles::grains_
ShapeType grains_
reference to shapes
Definition: grainParticles.hpp:51
pFlow::grainParticles::insertParticles
bool insertParticles(const realx3Vector &position, const wordVector &shapesNames, const anyList &setVarList) override
Definition: grainParticles.cpp:345
pFlow::real
float real
Definition: builtinTypes.hpp:45
fatalExit
#define fatalExit
Fatal exit.
Definition: error.hpp:98
pFlow::grainParticles::getShapes
const shape & getShapes() const override
Definition: grainParticles.cpp:409
pFlow::demComponent::control
const auto & control() const
Const ref to systemControl.
Definition: demComponent.hpp:88
REPORT
#define REPORT(n)
Definition: streams.hpp:39
systemControl.hpp
pFlow::grainParticles::grainDiameter_
realPointField_D grainDiameter_
diameter / boundig sphere size of particles on device
Definition: grainParticles.hpp:57
pFlow::grainParticles::propertyId_
uint32PointField_D propertyId_
property id on device
Definition: grainParticles.hpp:54
pFlow::Vector::reserve
void reserve(size_t cap)
Reserve capacity for vector Preserve the content.
Definition: Vector.hpp:284
pFlow::grainParticles::shapeTypeName
word shapeTypeName() const override
Definition: grainParticles.cpp:404
pFlow::uint32
unsigned int uint32
Definition: builtinTypes.hpp:56
pFlow::baseShapeNames::indexValid
bool indexValid(uint32 index) const
Definition: baseShapeNames.hpp:140
pFlow::word
std::string word
Definition: builtinTypes.hpp:64
pFlow::shape::shapePropertyIds
const auto & shapePropertyIds() const
Definition: shape.hpp:80
pFlow::systemControl
Definition: systemControl.hpp:41
pFlow::grainParticles::iterate
bool iterate() override
iterate particles
Definition: grainParticles.cpp:301
pFlow::zero3
const realx3 zero3(0.0)
Definition: types.hpp:137
pFlow::Vector::size
auto size() const
Size of the vector.
Definition: Vector.hpp:265
pFlow::endl
iOstream & endl(iOstream &os)
Add newline and flush stream.
Definition: iOstream.hpp:341
pFlow::grainParticles::I
const auto & I() const
const reference to inertia pointField
Definition: grainParticles.hpp:153
pFlow::grainParticles::getParticlesInfoFromShape
bool getParticlesInfoFromShape(const wordVector &shapeNames, uint32Vector &propIds, realVector &diams, realVector &coarseGrainFactors, realVector &m, realVector &Is, uint32Vector &shIndex)
Definition: grainParticles.cpp:88
pFlow::timeInfo
Definition: timeInfo.hpp:28
pFlow::grainParticles::initializeParticles
bool initializeParticles()
Insert new particles in position with specified shapes.
Definition: grainParticles.cpp:26
policy
Kokkos::RangePolicy< pFlow::DefaultExecutionSpace, Kokkos::Schedule< Kokkos::Static >, Kokkos::IndexType< pFlow::uint32 > > policy
Definition: grainParticlesKernels.cpp:25
pFlow::pointField::execution_space
typename InternalFieldType::execution_space execution_space
Definition: pointField.hpp:52
grainParticles.hpp
pFlow::VectorSingle::deviceView
INLINE_FUNCTION_H auto deviceView() const
Device view range [0, size)
Definition: VectorSingle.cpp:263
pFlow::grainParticles::mass
const realPointField_D & mass() const override
Definition: grainParticles.hpp:207
pFlow::grainParticles::I_
realPointField_D I_
pointField of inertial of particles
Definition: grainParticles.hpp:66
END_WARNING
#define END_WARNING
Definition: streams.hpp:44
pFlow::anyList
Definition: anyList.hpp:35
pFlow::grainParticles::boundingSphereMinMax
void boundingSphereMinMax(real &minDiam, real &maxDiam) const override
Definition: grainParticles.cpp:415
pFlow::particles
Definition: particles.hpp:33
fatalErrorInFunction
#define fatalErrorInFunction
Report a fatal error and function name and exit the application.
Definition: error.hpp:77
pFlow::shape
Definition: shape.hpp:30
pFlow::internalField::field
const FieldType & field() const
Definition: internalField.hpp:109
pFlow::grainParticles::beforeIteration
bool beforeIteration() override
before iteration step
Definition: grainParticles.cpp:278
pFlow::particles::shapeIndex
auto & shapeIndex()
Definition: particles.hpp:89
pFlow::grainShape::Inertia
bool Inertia(uint32 index, real &I) const override
Definition: grainShape.cpp:189
pFlow::grainParticles::rVelIntegration_
uniquePtr< integration > rVelIntegration_
rotational velocity integrator
Definition: grainParticles.hpp:78
pFlow::VectorSingle
Definition: VectorSingle.hpp:44
pFlow::shapeFile__
const char *const shapeFile__
Definition: vocabs.hpp:41
END_REPORT
#define END_REPORT
Definition: streams.hpp:40
pFlow::objectFile
Definition: objectFile.hpp:30
pFlow::grainShape::mass
bool mass(uint32 index, real &m) const override
Definition: grainShape.cpp:150
pFlow::property
property holds the pure properties of materials.
Definition: property.hpp:37
pFlow::grainParticles::coarseGrainFactor_
realPointField_D coarseGrainFactor_
Definition: grainParticles.hpp:59
pFlow::grainParticles::coarseGrainFactor
const realPointField_D & coarseGrainFactor() const
Definition: grainParticles.hpp:201
pFlow::grainParticles::grainParticles
grainParticles(systemControl &control, const property &prop)
construct from systemControl and property
Definition: grainParticles.cpp:143
LAMBDA_HD
#define LAMBDA_HD
Definition: pFlowMacros.hpp:58
pFlow::particles::dynPointStruct
auto & dynPointStruct()
Definition: particles.hpp:74
pFlow::grainShape::boundingDiameter
bool boundingDiameter(uint32 index, real &bDiam) const override
Definition: grainShape.cpp:86
vocabs.hpp
pFlow::triple< real >
pFlow::Vector< word >
m
uint32 m
Definition: NBSLoop.hpp:22
pFlow::integration::create
static uniquePtr< integration > create(const word &baseName, pointStructure &pStruct, const word &method, const realx3Field_D &initialValField)
Create the polymorphic object based on inputs.
Definition: integration.cpp:41
pFlow::anyList::emplaceBack
reference emplaceBack(const word &name, Args &&... args)
Create variable using constructor in-place.
Definition: anyList.hpp:84
pFlow::internalField::deviceView
auto deviceView() const
Definition: internalField.hpp:97
WARNING
#define WARNING
Definition: streams.hpp:43