course graining added

This commit is contained in:
alireza Hosseini
2024-11-17 10:19:40 +03:30
parent 7eb707f950
commit 2bd95b933f
43 changed files with 4566 additions and 5 deletions

View File

@ -9,8 +9,17 @@ particles/regularParticleIdHandler/regularParticleIdHandler.cpp
SphereParticles/sphereShape/sphereShape.cpp
SphereParticles/sphereParticles/sphereParticles.cpp
SphereParticles/sphereParticles/sphereParticlesKernels.cpp
GrainParticles/grainShape/grainShape.cpp
GrainParticles/grainParticles/grainParticles.cpp
GrainParticles/grainParticles/grainParticlesKernels.cpp
SphereParticles/boundarySphereParticles.cpp
SphereParticles/boundarySphereParticlesList.cpp
GrainParticles/boundaryGrainParticles.cpp
GrainParticles/boundaryGrainParticlesList.cpp
Insertion/collisionCheck/collisionCheck.cpp
Insertion/insertionRegion/insertionRegion.cpp
Insertion/insertion/insertion.cpp

View File

@ -0,0 +1,64 @@
#include "boundaryGrainParticles.hpp"
#include "boundaryBase.hpp"
#include "grainParticles.hpp"
pFlow::boundaryGrainParticles::boundaryGrainParticles(
const boundaryBase &boundary,
grainParticles &prtcls
)
:
generalBoundary(boundary, prtcls.pStruct(), "", ""),
particles_(prtcls)
{
}
pFlow::grainParticles &pFlow::boundaryGrainParticles::Particles()
{
return particles_;
}
const pFlow::grainParticles &pFlow::boundaryGrainParticles::Particles() const
{
return particles_;
}
pFlow::uniquePtr<pFlow::boundaryGrainParticles> pFlow::boundaryGrainParticles::create(
const boundaryBase &boundary,
grainParticles &prtcls
)
{
word bType = angleBracketsNames2(
"boundaryGrainParticles",
pFlowProcessors().localRunTypeName(),
boundary.type());
word altBType{"boundaryGrainParticles<none>"};
if( boundaryBasevCtorSelector_.search(bType) )
{
pOutput.space(4)<<"Creating boundary "<< Green_Text(bType)<<
" for "<<boundary.name()<<endl;
return boundaryBasevCtorSelector_[bType](boundary, prtcls);
}
else if(boundaryBasevCtorSelector_.search(altBType))
{
pOutput.space(4)<<"Creating boundary "<< Green_Text(altBType)<<
" for "<<boundary.name()<<endl;
return boundaryBasevCtorSelector_[altBType](boundary, prtcls);
}
else
{
printKeys(
fatalError << "Ctor Selector "<< bType<<
" and "<< altBType << " do not exist. \n"
<<"Avaiable ones are: \n",
boundaryBasevCtorSelector_
);
fatalExit;
}
return nullptr;
}

View File

@ -0,0 +1,80 @@
#ifndef __boundaryGrainParticles_hpp__
#define __boundaryGrainParticles_hpp__
#include "generalBoundary.hpp"
#include "virtualConstructor.hpp"
#include "timeInfo.hpp"
namespace pFlow
{
class grainParticles;
class boundaryGrainParticles
: public generalBoundary
{
private:
grainParticles& particles_;
public:
/// type info
TypeInfo("boundaryGrainParticles<none>");
boundaryGrainParticles(
const boundaryBase &boundary,
grainParticles& prtcls
);
create_vCtor(
boundaryGrainParticles,
boundaryBase,
(
const boundaryBase &boundary,
grainParticles& prtcls
),
(boundary, prtcls)
);
add_vCtor(
boundaryGrainParticles,
boundaryGrainParticles,
boundaryBase
);
grainParticles& Particles();
const grainParticles& Particles()const;
bool hearChanges(
real t,
real dt,
uint32 iter,
const message &msg,
const anyList &varList) override
{
return true;
}
virtual
bool acceleration(const timeInfo& ti, const realx3& g)
{
return true;
}
static
uniquePtr<boundaryGrainParticles> create(
const boundaryBase &boundary,
grainParticles& prtcls);
};
}
#endif

View File

@ -0,0 +1,19 @@
#include "boundaryGrainParticlesList.hpp"
pFlow::boundaryGrainParticlesList::boundaryGrainParticlesList(
const boundaryList &bndrs,
grainParticles &prtcls
)
:
ListPtr(bndrs.size()),
boundaries_(bndrs)
{
for(auto i=0; i<boundaries_.size(); i++)
{
this->set
(
i,
boundaryGrainParticles::create(boundaries_[i], prtcls)
);
}
}

View File

@ -0,0 +1,36 @@
#ifndef __boundaryGrainParticlesList_hpp__
#define __boundaryGrainParticlesList_hpp__
#include "ListPtr.hpp"
#include "boundaryList.hpp"
#include "boundaryGrainParticles.hpp"
namespace pFlow
{
class boundaryGrainParticlesList
:
public ListPtr<boundaryGrainParticles>
{
private:
const boundaryList& boundaries_;
public:
boundaryGrainParticlesList(
const boundaryList& bndrs,
grainParticles& prtcls
);
~boundaryGrainParticlesList()=default;
};
}
#endif

View File

@ -0,0 +1,422 @@
/*------------------------------- 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();
}

View File

@ -0,0 +1,236 @@
/*------------------------------- 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.
-----------------------------------------------------------------------------*/
/**
* @class pFlow::sphereParticles
*
* @brief Class for managing spherical particles
*
* This is a top-level class that contains the essential components for
* defining spherical prticles in a DEM simulation.
*/
#ifndef __grainParticles_hpp__
#define __grainParticles_hpp__
#include "indexContainer.hpp"
#include "particles.hpp"
#include "property.hpp"
#include "grainShape.hpp"
#include "boundaryGrainParticlesList.hpp"
#include "systemControl.hpp"
namespace pFlow
{
class grainParticles : public particles
{
public:
using ShapeType = grainShape;
private:
/// reference to shapes
ShapeType grains_;
/// property id on device
uint32PointField_D propertyId_;
/// diameter / boundig sphere size of particles on device
realPointField_D grainDiameter_;
realPointField_D coarseGrainFactor_;
/// mass of particles field
realPointField_D mass_;
/// pointField of inertial of particles
realPointField_D I_;
/// pointField of rotational Velocity of particles on device
realx3PointField_D rVelocity_;
/// pointField of rotational acceleration of particles on device
realx3PointField_D rAcceleration_;
/// boundaries
boundaryGrainParticlesList boundaryGrainParticles_;
/// rotational velocity integrator
uniquePtr<integration> rVelIntegration_ = nullptr;
/// timer for acceleration computations
Timer accelerationTimer_;
/// timer for integration computations (prediction step)
Timer intPredictTimer_;
/// timer for integration computations (correction step)
Timer intCorrectTimer_;
Timer fieldUpdateTimer_;
private:
bool getParticlesInfoFromShape(
const wordVector& shapeNames,
uint32Vector& propIds,
realVector& diams,
realVector& coarseGrainFactors,
realVector& m,
realVector& Is,
uint32Vector& shIndex
);
/*bool initializeParticles();
bool insertSphereParticles(
const wordVector& names,
const int32IndexContainer& indices,
bool setId = true);
virtual uniquePtr<List<eventObserver*>> getFieldObjectList()const override;
*/
public:
/// construct from systemControl and property
grainParticles(systemControl& control, const property& prop);
~grainParticles() override = default;
/**
* Insert new particles in position with specified shapes
*
* This function is involked by inserted object to insert new set of
* particles into the simulation. \param position position of new particles
* \param shape shape of new particles
* \param setField initial value of the selected fields for new particles
*/
/*bool insertParticles
(
const realx3Vector& position,
const wordVector& shapes,
const setFieldList& setField
) override ;*/
// TODO: make this method private later
bool initializeParticles();
/// const reference to shapes object
const auto& grains() const
{
return grains_;
}
/// const reference to inertia pointField
const auto& I() const
{
return I_;
}
/// reference to inertia pointField
auto& I()
{
return I_;
}
const auto& rVelocity() const
{
return rVelocity_;
}
auto& rVelocity()
{
return rVelocity_;
}
bool hearChanges(
real t,
real dt,
uint32 iter,
const message& msg,
const anyList& varList
) override
{
notImplementedFunction;
return false;
}
const uint32PointField_D& propertyId() const override
{
return propertyId_;
}
const realPointField_D& diameter() const override
{
return grainDiameter_;
}
const realPointField_D& coarseGrainFactor() const
{
return coarseGrainFactor_;
}
const realPointField_D& mass() const override
{
return mass_;
}
/// before iteration step
bool beforeIteration() override;
/// iterate particles
bool iterate() override;
bool insertParticles(
const realx3Vector& position,
const wordVector& shapesNames,
const anyList& setVarList
) override;
realx3PointField_D& rAcceleration() override
{
return rAcceleration_;
}
const realx3PointField_D& rAcceleration() const override
{
return rAcceleration_;
}
const realPointField_D& boundingSphere() const override
{
return diameter();
}
word shapeTypeName() const override;
const shape& getShapes() const override;
void boundingSphereMinMax(real& minDiam, real& maxDiam) const override;
};// grainParticles
} // pFlow
#endif //__sphereParticles_hpp__

View File

@ -0,0 +1,101 @@
/*------------------------------- 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 "grainParticlesKernels.hpp"
using policy = Kokkos::RangePolicy<
pFlow::DefaultExecutionSpace,
Kokkos::Schedule<Kokkos::Static>,
Kokkos::IndexType<pFlow::uint32>>;
void pFlow::grainParticlesKernels::addMassDiamInertiaProp
(
deviceViewType1D<uint32> shapeIndex,
deviceViewType1D<real> mass,
deviceViewType1D<real> diameter,
deviceViewType1D<real> coarseGrainFactor,
deviceViewType1D<real> I,
deviceViewType1D<uint32> propertyId,
pFlagTypeDevice incld,
deviceViewType1D<real> src_mass,
deviceViewType1D<real> src_diameter,
deviceViewType1D<real> src_I,
deviceViewType1D<uint32> src_propertyId
)
{
auto aRange = incld.activeRange();
Kokkos::parallel_for(
"particles::initInertia",
policy(aRange.start(), aRange.end()),
LAMBDA_HD(uint32 i)
{
if(incld(i))
{
uint32 index = shapeIndex[i];
I[i] = src_I[index];
diameter[i] = src_diameter[index];
mass[i] = src_mass[index];
propertyId[i] = src_propertyId[index];
}
});
}
void pFlow::grainParticlesKernels::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
)
{
auto activeRange = incld.activeRange();
if(incld.isAllActive())
{
Kokkos::parallel_for(
"pFlow::grainParticlesKernels::acceleration",
policy(activeRange.start(), activeRange.end()),
LAMBDA_HD(uint32 i){
lAcc[i] = force[i]/mass[i] + g;
rAcc[i] = torque[i]/I[i];
});
}
else
{
Kokkos::parallel_for(
"pFlow::grainParticlesKernels::acceleration",
policy(activeRange.start(), activeRange.end()),
LAMBDA_HD(uint32 i){
if(incld(i))
{
lAcc[i] = force[i]/mass[i] + g;
rAcc[i] = torque[i]/I[i];
}
});
}
Kokkos::fence();
}

View File

@ -0,0 +1,59 @@
/*------------------------------- 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 __grainParticlesKernels_hpp__
#define __grainParticlesKernels_hpp__
#include "types.hpp"
#include "pointFlag.hpp"
namespace pFlow::grainParticlesKernels
{
void addMassDiamInertiaProp(
deviceViewType1D<uint32> shapeIndex,
deviceViewType1D<real> mass,
deviceViewType1D<real> diameter,
deviceViewType1D<real> coarseGrainFactor,
deviceViewType1D<real> I,
deviceViewType1D<uint32> propertyId,
pFlagTypeDevice incld,
deviceViewType1D<real> src_mass,
deviceViewType1D<real> src_grainDiameter,
deviceViewType1D<real> src_I,
deviceViewType1D<uint32> src_propertyId
);
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
);
}
#endif

View File

@ -0,0 +1,242 @@
/*------------------------------- 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 "grainShape.hpp"
bool pFlow::grainShape::readFromDictionary3()
{
grainDiameters_ = getVal<realVector>("grainDiameters");
sphereDiameters_ = getVal<realVector>("sphereDiameters");
coarseGrainFactor_ = grainDiameters_ / sphereDiameters_ ;
if(grainDiameters_.size() != numShapes() )
{
fatalErrorInFunction<<
" number of elements in grain diameters in "<< globalName()<<" is not consistent"<<endl;
return false;
}
if(sphereDiameters_.size() != numShapes() )
{
fatalErrorInFunction<<
" number of elements in sphere diameters in "<< globalName()<<" is not consistent"<<endl;
return false;
}
return true;
}
bool pFlow::grainShape::writeToDict(dictionary& dict)const
{
if(!shape::writeToDict(dict))return false;
return true;
}
pFlow::grainShape::grainShape
(
const word& fileName,
repository* owner,
const property& prop
)
:
shape(fileName, owner, prop)
{
if(!readFromDictionary3())
{
fatalExit;
fatalErrorInFunction;
}
}
pFlow::real pFlow::grainShape::maxBoundingSphere() const
{
return max(grainDiameters_);
}
pFlow::real pFlow::grainShape::minBoundingSphere() const
{
return min(grainDiameters_);
}
bool pFlow::grainShape::boundingDiameter(uint32 index, real &bDiam) const
{
if( indexValid(index))
{
bDiam = grainDiameters_[index];
return true;
}
return false;
}
pFlow::real pFlow::grainShape::boundingDiameter(uint32 index) const
{
if(indexValid(index))
{
return grainDiameters_[index];
}
fatalErrorInFunction<<"Invalid index for diameter "<<
index<<endl;
fatalExit;
return 0.0;
}
pFlow::realVector pFlow::grainShape::boundingDiameter() const
{
return grainDiameters_;
}
pFlow::real pFlow::grainShape::coarseGrainFactor(uint32 index) const
{
if(indexValid(index))
{
return coarseGrainFactor_[index];
}
fatalErrorInFunction<<"Invalid index for coarse Grain Factor "<<
index<<endl;
fatalExit;
return 0.0;
}
pFlow::realVector pFlow::grainShape::coarseGrainFactor() const
{
return coarseGrainFactor_;
}
pFlow::real pFlow::grainShape::orginalDiameter(uint32 index) const
{
if(indexValid(index))
{
return sphereDiameters_[index];
}
fatalErrorInFunction<<"Invalid index for sphere diameter "<<
index<<endl;
fatalExit;
return 0.0;
}
pFlow::realVector pFlow::grainShape::orginalDiameter() const
{
return sphereDiameters_;
}
bool pFlow::grainShape::mass(uint32 index, real &m) const
{
if( indexValid(index) )
{
real d = grainDiameters_[index];
real rho = indexToDensity(index);
m = Pi/6.0*pow(d,3)*rho;
return true;
}
return false;
}
pFlow::real pFlow::grainShape::mass(uint32 index) const
{
if(real m; mass(index, m))
{
return m;
}
fatalErrorInFunction<<"bad index for mass "<< index<<endl;
fatalExit;
return 0;
}
pFlow::realVector pFlow::grainShape::mass() const
{
return realVector ("mass", Pi/6*pow(grainDiameters_,(real)3.0)*density());
}
pFlow::realVector pFlow::grainShape::density()const
{
auto pids = shapePropertyIds();
realVector rho("rho", numShapes());
ForAll(i, pids)
{
rho[i] = properties().density(pids[i]);
}
return rho;
}
bool pFlow::grainShape::Inertia(uint32 index, real &I) const
{
if( indexValid(index) )
{
I = 0.4 * mass(index) * pow(grainDiameters_[index]/2.0,2.0);
return true;
}
return false;
}
pFlow::real pFlow::grainShape::Inertia(uint32 index) const
{
if(real I; Inertia(index, I))
{
return I;
}
fatalExit;
return 0;
}
pFlow::realVector pFlow::grainShape::Inertia() const
{
return realVector("I", (real)0.4*mass()*pow((real)0.5*grainDiameters_,(real)2.0));
}
bool pFlow::grainShape::Inertia_xx(uint32 index, real &Ixx) const
{
return Inertia(index,Ixx);
}
pFlow::real pFlow::grainShape::Inertial_xx(uint32 index) const
{
return Inertia(index);
}
bool pFlow::grainShape::Inertia_yy(uint32 index, real &Iyy) const
{
return Inertia(index,Iyy);
}
pFlow::real pFlow::grainShape::Inertial_yy(uint32 index) const
{
return Inertia(index);
}
bool pFlow::grainShape::Inertia_zz(uint32 index, real &Izz) const
{
return Inertia(index,Izz);
}
pFlow::real pFlow::grainShape::Inertial_zz(uint32 index) const
{
return Inertia(index);
}

View File

@ -0,0 +1,110 @@
/*------------------------------- 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 __grainShape_hpp__
#define __grainShape_hpp__
#include "shape.hpp"
namespace pFlow
{
class grainShape
:
public shape
{
private:
// - diameter of spheres
realVector grainDiameters_;
realVector sphereDiameters_;
realVector coarseGrainFactor_;
bool readFromDictionary3();
protected:
bool writeToDict(dictionary& dict)const override;
public:
// - type info
TypeInfo("shape<grain>");
grainShape(
const word& fileName,
repository* owner,
const property& prop);
~grainShape() override = default;
//// - Methods
real maxBoundingSphere()const override;
real minBoundingSphere()const override;
bool boundingDiameter(uint32 index, real& bDiam)const override;
real boundingDiameter(uint32 index)const override;
realVector boundingDiameter()const override;
real coarseGrainFactor(uint32 index)const ;
realVector coarseGrainFactor()const ;
real orginalDiameter(uint32 index)const ;
realVector orginalDiameter()const ;
bool mass(uint32 index, real& m)const override;
real mass(uint32 index) const override;
realVector mass()const override;
realVector density() const override;
bool Inertia(uint32 index, real& I)const override;
real Inertia(uint32 index)const override;
realVector Inertia()const override;
bool Inertia_xx(uint32 index, real& Ixx)const override;
real Inertial_xx(uint32 index)const override;
bool Inertia_yy(uint32 index, real& Iyy)const override;
real Inertial_yy(uint32 index)const override;
bool Inertia_zz(uint32 index, real& Izz)const override;
real Inertial_zz(uint32 index)const override;
};
} // pFlow
#endif //__grainShape_hpp__

View File

@ -21,4 +21,5 @@ Licence:
#include "Insertions.hpp"
template class pFlow::Insertion<pFlow::sphereShape>;
template class pFlow::Insertion<pFlow::sphereShape>;
template class pFlow::Insertion<pFlow::grainShape>;

View File

@ -24,11 +24,15 @@ Licence:
#include "Insertion.hpp"
#include "sphereShape.hpp"
#include "grainShape.hpp"
namespace pFlow
{
using sphereInsertion = Insertion<sphereShape> ;
using grainInsertion = Insertion<grainShape> ;
}