This is the first merge from main into MPI branch

Merge branch 'main' into local-MPI
This commit is contained in:
Hamidreza
2025-05-03 16:40:46 +03:30
578 changed files with 118959 additions and 28494 deletions

View File

@ -6,9 +6,23 @@ particles/shape/shape.cpp
particles/particles.cpp
particles/particleIdHandler/particleIdHandler.cpp
particles/regularParticleIdHandler/regularParticleIdHandler.cpp
globalDamping/globalDamping.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
@ -18,7 +32,8 @@ Insertion/Insertion/Insertions.cpp
if(pFlow_Build_MPI)
list(APPEND SourceFiles
particles/MPIParticleIdHandler/MPIParticleIdHandler.cpp)
particles/MPIParticleIdHandler/MPIParticleIdHandler.cpp
SphereParticles/processorBoundarySphereParticles.cpp)
endif()
set(link_libs Kokkos::kokkos phasicFlow Integration Property)

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,83 @@
#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(
const timeInfo& ti,
const message &msg,
const anyList &varList) override
{
return true;
}
virtual
bool acceleration(const timeInfo& ti, const realx3& g)
{
return true;
}
bool isActive()const override
{
return false;
}
static
uniquePtr<boundaryGrainParticles> create(
const boundaryBase &boundary,
grainParticles& prtcls);
};
}
#endif

View File

@ -0,0 +1,20 @@
#include "boundaryGrainParticlesList.hpp"
pFlow::boundaryGrainParticlesList::boundaryGrainParticlesList(
const boundaryList &bndrs,
grainParticles &prtcls
)
:
boundaryListPtr(),
boundaries_(bndrs)
{
ForAllBoundariesPtr(i, this)
{
this->set
(
i,
boundaryGrainParticles::create(boundaries_[i], prtcls)
);
}
}

View File

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

View File

@ -0,0 +1,421 @@
/*------------------------------- 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 grainShape& gShape
)
:
particles(control, gShape),
grains_(gShape),
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,
rAcceleration_.field(),
control.keepIntegrationHistory()
);
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);
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()
{
const timeInfo ti = TimeInfo();
const realx3 g = control().g();
particles::iterate();
accelerationTimer_.start();
pFlow::grainParticlesKernels::acceleration(
g,
mass().deviceViewAll(),
contactForce().deviceViewAll(),
I().deviceViewAll(),
contactTorque().deviceViewAll(),
dynPointStruct().activePointsMaskDevice(),
acceleration().deviceViewAll(),
rAcceleration().deviceViewAll()
);
ForAllActiveBoundaries(i,boundaryGrainParticles_)
{
boundaryGrainParticles_[i].acceleration(ti, g);
}
accelerationTimer_.end();
intCorrectTimer_.start();
if(!dynPointStruct().correct(ti.dt()))
{
return false;
}
real damping = dynPointStruct().dampingFactor(ti);
if(!rVelIntegration_().correct(
ti.dt(),
rVelocity_,
rAcceleration_,
damping))
{
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,247 @@
/*------------------------------- 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
const 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
);
protected:
Timer& accelerationTimer()
{
return accelerationTimer_;
}
Timer& intCorrectTimer()
{
return intCorrectTimer_;
}
integration& rVelIntegration()
{
return rVelIntegration_();
}
public:
/// construct from systemControl and property
grainParticles(systemControl& control, const grainShape& gShape);
~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(
const timeInfo& ti,
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& grainDiameter()const
{
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,261 @@
/*------------------------------- 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::grainShape::grainShape
(
const word &shapeType,
const word &fileName,
repository *owner,
const property &prop
)
:
grainShape(fileName, owner, prop)
{
}
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::volume() const
{
return realVector("volume", Pi/6*pow(grainDiameters_,(real)3.0));
}
pFlow::realVector pFlow::grainShape::coarseGrainFactor() const
{
return coarseGrainFactor_;
}
pFlow::real pFlow::grainShape::originalDiameter(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::originalDiameter() 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,128 @@
/*------------------------------- 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 grains
realVector grainDiameters_;
/// diameter of spheres
realVector sphereDiameters_;
/// course-grain factor
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(
const word& shapeType,
const word& fileName,
repository* owner,
const property& prop);
~grainShape() override = default;
add_vCtor
(
shape,
grainShape,
word
);
//// - 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;
realVector volume()const override;
real coarseGrainFactor(uint32 index)const ;
realVector coarseGrainFactor()const ;
real originalDiameter(uint32 index)const ;
realVector originalDiameter()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> ;
}

View File

@ -81,7 +81,7 @@ pFlow::insertion::readInsertionDict()
if (active_)
{
checkForCollision_ = getVal<Logical>("checkForCollision");
//checkForCollision_ = getVal<Logical>("checkForCollision");
REPORT(1) << "Particle insertion mechanism is " << Yellow_Text("active")
<< " in the simulation." << END_REPORT;

View File

@ -42,7 +42,7 @@ private:
Logical active_ = "No";
/// Check for collision? It is not active now
Logical checkForCollision_ = "No";
Logical checkForCollision_ = "Yes";
/// if increase velocity in case particles are failed
/// to be inserted due to collision

View File

@ -24,6 +24,7 @@ Licence:
#include "particles.hpp"
#include "twoPartEntry.hpp"
#include "types.hpp"
#include "shape.hpp"
namespace pFlow
{

View File

@ -173,7 +173,7 @@ public:
inline bool insertionTime(uint32 iter, real t, real dt) const
{
return tControl_.timeEvent(iter, t, dt);
return tControl_.eventTime(iter, t, dt);
}
uint32 numberToBeInserted(uint32 iter, real t, real dt);

View File

@ -50,9 +50,7 @@ public:
const sphereParticles& Particles()const;
bool hearChanges(
real t,
real dt,
uint32 iter,
const timeInfo& ti,
const message &msg,
const anyList &varList) override
{
@ -65,6 +63,11 @@ public:
return true;
}
bool isActive()const override
{
return false;
}
static
uniquePtr<boundarySphereParticles> create(
const boundaryBase &boundary,

View File

@ -5,10 +5,10 @@ pFlow::boundarySphereParticlesList::boundarySphereParticlesList(
sphereParticles &prtcls
)
:
ListPtr(bndrs.size()),
boundaryListPtr(),
boundaries_(bndrs)
{
for(auto i=0; i<boundaries_.size(); i++)
ForAllBoundariesPtr(i, this)
{
this->set
(

View File

@ -3,7 +3,7 @@
#ifndef __boundarySphereParticlesList_hpp__
#define __boundarySphereParticlesList_hpp__
#include "ListPtr.hpp"
#include "boundaryListPtr.hpp"
#include "boundaryList.hpp"
#include "boundarySphereParticles.hpp"
@ -12,7 +12,7 @@ namespace pFlow
class boundarySphereParticlesList
:
public ListPtr<boundarySphereParticles>
public boundaryListPtr<boundarySphereParticles>
{
private:

View File

@ -24,180 +24,6 @@ Licence:
#include "sphereParticlesKernels.hpp"
//#include "setFieldList.hpp"
/*pFlow::uniquePtr<pFlow::List<pFlow::eventObserver*>>
pFlow::sphereParticles::getFieldObjectList()const
{
auto objListPtr = particles::getFieldObjectList();
objListPtr().push_back(
static_cast<eventObserver*>(&I_) );
return objListPtr;
}
bool pFlow::sphereParticles::diameterMassInertiaPropId
(
const word& shName,
real& diam,
real& mass,
real& I,
int8& propIdx
)
{
uint32 idx;
if( !shapes_.nameToIndex(shName, idx) )
{
printKeys(fatalErrorInFunction<<
" wrong shape name in the input: "<< shName<<endl<<
" available shape names are: ", shapes_.names())<<endl;
return false;
}
diam = shapes_.diameter(idx);
word materialName = shapes_.material(idx);
uint32 pIdx;
if( !property_.nameToIndex(materialName, pIdx) )
{
fatalErrorInFunction <<
" wrong material name "<< materialName <<" specified for shape "<< shName<<
" in the sphereShape dictionary.\n"<<
" available materials are "<< property_.materials()<<endl;
return false;
}
real rho = property_.density(pIdx);
mass = Pi/6.0*pow(diam,3.0)*rho;
I = 0.4 * mass * pow(diam/2.0,2.0);
propIdx= static_cast<int8>(pIdx);
return true;
}
bool pFlow::sphereParticles::initializeParticles()
{
int32IndexContainer indices(
0,
static_cast<int32>(shapeName_.size()));
return insertSphereParticles(shapeName_, indices, false);
}*/
/*bool pFlow::sphereParticles::beforeIteration()
{
particles::beforeIteration();
intPredictTimer_.start();
//INFO<<"before dyn predict"<<endINFO;
dynPointStruct_.predict(this->dt(), accelertion_);
//INFO<<"after dyn predict"<<endINFO;
//INFO<<"before revel predict"<<endINFO;
rVelIntegration_().predict(this->dt(),rVelocity_, rAcceleration_);
//INFO<<"after rvel predict"<<endINFO;
intPredictTimer_.end();
return true;
}*/
/*bool pFlow::sphereParticles::afterIteration()
{
return true;
}*/
/*bool pFlow::sphereParticles::insertSphereParticles(
const wordVector& names,
const int32IndexContainer& indices,
bool setId
)
{
if(names.size()!= indices.size())
{
fatalErrorInFunction <<
"sizes of names ("<<names.size()<<") and indices ("
<< indices.size()<<") do not match \n";
return false;
}
auto len = names.size();
realVector diamVec(len, RESERVE());
realVector massVec(len, RESERVE());
realVector IVec(len, RESERVE());
int8Vector pIdVec(len, RESERVE());
int32Vector IdVec(len, RESERVE());
real d, m, I;
int8 pId;
ForAll(i, names )
{
if (diameterMassInertiaPropId(names[i], d, m, I, pId))
{
diamVec.push_back(d);
massVec.push_back(m);
IVec.push_back(I);
pIdVec.push_back(pId);
if(setId) IdVec.push_back(idHandler_.getNextId());
//output<<" we are in sphereParticles nextId "<< idHandler_.nextId()<<endl;
}
else
{
fatalErrorInFunction<< "failed to calculate properties of shape " <<
names[i]<<endl;
return false;
}
}
if(!diameter_.insertSetElement(indices, diamVec))
{
fatalErrorInFunction<< " failed to insert diameters to the diameter field. \n";
return false;
}
if(!mass_.insertSetElement(indices, massVec))
{
fatalErrorInFunction<< " failed to insert mass to the mass field. \n";
return false;
}
if(!I_.insertSetElement(indices, IVec))
{
fatalErrorInFunction<< " failed to insert I to the I field. \n";
return false;
}
if(!propertyId_.insertSetElement(indices, pIdVec))
{
fatalErrorInFunction<< " failed to insert propertyId to the propertyId field. \n";
return false;
}
if(setId)
{
if( !id_.insertSetElement(indices, IdVec))
{
fatalErrorInFunction<< " failed to insert id to the id field. \n";
return false;
}
}
return true;
}*/
bool pFlow::sphereParticles::initializeParticles()
{
@ -307,16 +133,11 @@ pFlow::sphereParticles::getParticlesInfoFromShape(
pFlow::sphereParticles::sphereParticles(
systemControl &control,
const property& prop
const sphereShape& shpShape
)
:
particles(control),
spheres_
(
shapeFile__,
&control.caseSetup(),
prop
),
particles(control, shpShape),
spheres_(shpShape),
propertyId_
(
objectFile
@ -384,6 +205,11 @@ pFlow::sphereParticles::sphereParticles(
dynPointStruct(),
zero3
),
boundarySphereParticles_
(
dynPointStruct().boundaries(),
*this
),
accelerationTimer_(
"Acceleration", &this->timers() ),
intPredictTimer_(
@ -403,7 +229,8 @@ pFlow::sphereParticles::sphereParticles(
"rVelocity",
dynPointStruct(),
intMethod,
rVelocity_.field()
rAcceleration_.field(),
control.keepIntegrationHistory()
);
if( !rVelIntegration_ )
@ -413,8 +240,6 @@ pFlow::sphereParticles::sphereParticles(
fatalExit;
}
WARNING<<"setFields for rVelIntegration_"<<END_WARNING;
if(!initializeParticles())
{
fatalErrorInFunction;
@ -423,96 +248,12 @@ pFlow::sphereParticles::sphereParticles(
}
/*bool pFlow::sphereParticles::update(const eventMessage& msg)
{
if(rVelIntegration_->needSetInitialVals())
{
auto indexHD = pStruct().insertedPointIndex();
auto n = indexHD.size();
auto index = indexHD.indicesHost();
realx3Vector rvel(n,RESERVE());
const auto hrVel = rVelocity_.hostView();
for(auto i=0; i<n; i++)
{
rvel.push_back( hrVel[index(i)]);
}
rVelIntegration_->setInitialVals(indexHD, rvel);
}
return true;
}*/
/*bool pFlow::sphereParticles::insertParticles
(
const realx3Vector& position,
const wordVector& shapes,
const setFieldList& setField
)
{
if( position.size() != shapes.size() )
{
fatalErrorInFunction<<
" size of vectors position ("<<position.size()<<
") and shapes ("<<shapes.size()<<") are not the same. \n";
return false;
}
auto exclusionListAllPtr = getFieldObjectList();
auto newInsertedPtr = pStruct().insertPoints( position, setField, time(), exclusionListAllPtr());
if(!newInsertedPtr)
{
fatalErrorInFunction<<
" error in inserting points into pStruct. \n";
return false;
}
auto& newInserted = newInsertedPtr();
if(!shapeName_.insertSetElement(newInserted, shapes))
{
fatalErrorInFunction<<
" error in inserting shapes into sphereParticles system.\n";
return false;
}
if( !insertSphereParticles(shapes, newInserted) )
{
fatalErrorInFunction<<
"error in inserting shapes into the sphereParticles. \n";
return false;
}
auto activeR = this->activeRange();
REPORT(1)<< "Active range is "<<yellowText("["<<activeR.first<<", "<<activeR.second<<")")<<
" and number of active points is "<< cyanText(this->numActive())<<
" and pointStructure capacity is "<<cyanText(this->capacity())<<endREPORT;
return true;
}*/
bool pFlow::sphereParticles::beforeIteration()
{
particles::beforeIteration();
intPredictTimer_.start();
auto dt = this->dt();
dynPointStruct().predict(dt, accelertion());
dynPointStruct().predict(dt);
rVelIntegration_().predict(dt,rVelocity_, rAcceleration_);
intPredictTimer_.end();
@ -523,6 +264,7 @@ bool pFlow::sphereParticles::beforeIteration()
I_.updateBoundariesSlaveToMasterIfRequested();
rVelocity_.updateBoundariesSlaveToMasterIfRequested();
rAcceleration_.updateBoundariesSlaveToMasterIfRequested();
rVelIntegration_().updateBoundariesSlaveToMasterIfRequested();
fieldUpdateTimer_.end();
return true;
@ -531,30 +273,40 @@ bool pFlow::sphereParticles::beforeIteration()
bool pFlow::sphereParticles::iterate()
{
const timeInfo ti = TimeInfo();
const realx3 g = control().g();
particles::iterate();
accelerationTimer_.start();
pFlow::sphereParticlesKernels::acceleration(
control().g(),
g,
mass().deviceViewAll(),
contactForce().deviceViewAll(),
I().deviceViewAll(),
contactTorque().deviceViewAll(),
dynPointStruct().activePointsMaskDevice(),
accelertion().deviceViewAll(),
acceleration().deviceViewAll(),
rAcceleration().deviceViewAll()
);
ForAllActiveBoundaries(i,boundarySphereParticles_)
{
boundarySphereParticles_[i].acceleration(ti, g);
}
accelerationTimer_.end();
intCorrectTimer_.start();
if(!dynPointStruct().correct(dt(), accelertion()))
if(!dynPointStruct().correct(ti.dt()))
{
return false;
}
real damping = dynPointStruct().dampingFactor(ti);
if(!rVelIntegration_().correct(
dt(),
ti.dt(),
rVelocity_,
rAcceleration_))
rAcceleration_,
damping))
{
return false;
}

View File

@ -33,6 +33,7 @@ Licence:
#include "particles.hpp"
#include "property.hpp"
#include "sphereShape.hpp"
#include "boundarySphereParticlesList.hpp"
#include "systemControl.hpp"
namespace pFlow
@ -47,7 +48,7 @@ public:
private:
/// reference to shapes
ShapeType spheres_;
const ShapeType& spheres_;
/// property id on device
uint32PointField_D propertyId_;
@ -67,6 +68,9 @@ private:
/// pointField of rotational acceleration of particles on device
realx3PointField_D rAcceleration_;
/// boundaries
boundarySphereParticlesList boundarySphereParticles_;
/// rotational velocity integrator
uniquePtr<integration> rVelIntegration_ = nullptr;
@ -101,11 +105,26 @@ private:
virtual uniquePtr<List<eventObserver*>> getFieldObjectList()const override;
*/
protected:
Timer& accelerationTimer()
{
return accelerationTimer_;
}
Timer& intCorrectTimer()
{
return intCorrectTimer_;
}
integration& rVelIntegration()
{
return rVelIntegration_();
}
public:
/// construct from systemControl and property
sphereParticles(systemControl& control, const property& prop);
sphereParticles(systemControl& control, const sphereShape& shpShape);
~sphereParticles() override = default;
@ -156,9 +175,7 @@ public:
}
bool hearChanges(
real t,
real dt,
uint32 iter,
const timeInfo& ti,
const message& msg,
const anyList& varList
) override

View File

@ -68,6 +68,18 @@ pFlow::sphereShape::sphereShape
}
}
pFlow::sphereShape::sphereShape
(
const word &shapeType,
const word &fileName,
repository *owner,
const property &prop
)
:
sphereShape(fileName, owner, prop)
{
}
pFlow::real pFlow::sphereShape::maxBoundingSphere() const
{
return max(diameters_);
@ -105,6 +117,11 @@ pFlow::realVector pFlow::sphereShape::boundingDiameter() const
return diameters_;
}
pFlow::realVector pFlow::sphereShape::volume() const
{
return realVector("volume", Pi/6*pow(diameters_,(real)3.0));
}
bool pFlow::sphereShape::mass(uint32 index, real &m) const
{
if( indexValid(index) )

View File

@ -51,9 +51,22 @@ public:
repository* owner,
const property& prop);
sphereShape(
const word& shapeType,
const word& fileName,
repository* owner,
const property& prop);
~sphereShape() override = default;
add_vCtor
(
shape,
sphereShape,
word
);
//// - Methods
real maxBoundingSphere()const override;
@ -66,6 +79,8 @@ public:
realVector boundingDiameter()const override;
realVector volume()const override;
bool mass(uint32 index, real& m)const override;
real mass(uint32 index) const override;

View File

@ -21,12 +21,14 @@ Licence:
#include "dynamicPointStructure.hpp"
#include "systemControl.hpp"
pFlow::dynamicPointStructure::dynamicPointStructure
(
systemControl& control
systemControl& control,
real maxBSphere
)
:
pointStructure(control),
pointStructure(control, maxBSphere),
velocity_
(
objectFile(
@ -38,6 +40,16 @@ pFlow::dynamicPointStructure::dynamicPointStructure
*this,
zero3
),
acceleration_(
objectFile(
"acceleration",
"",
objectFile::READ_IF_PRESENT,
objectFile::WRITE_ALWAYS
),
*this,
zero3
),
velocityUpdateTimer_("velocity boundary update", &timers()),
integrationMethod_
(
@ -46,13 +58,14 @@ pFlow::dynamicPointStructure::dynamicPointStructure
{
REPORT(1)<< "Creating integration method "<<
Green_Text(integrationMethod_)<<" for dynamicPointStructure."<<END_REPORT;
integrationPos_ = integration::create
(
"pStructPosition",
*this,
integrationMethod_,
pointPosition()
velocity_.field(),
control.keepIntegrationHistory()
);
if( !integrationPos_ )
@ -67,7 +80,8 @@ pFlow::dynamicPointStructure::dynamicPointStructure
"pStructVelocity",
*this,
integrationMethod_,
velocity_.field()
acceleration_.field(),
control.keepIntegrationHistory()
);
if( !integrationVel_ )
@ -77,6 +91,11 @@ pFlow::dynamicPointStructure::dynamicPointStructure
fatalExit;
}
if(control.settingsDict().containsDictionay("globalDamping"))
{
REPORT(1)<<"Reading globalDamping dictionary ..."<<END_REPORT;
velDamping_ = makeUnique<globalDamping>(control);
}
}
@ -85,6 +104,9 @@ bool pFlow::dynamicPointStructure::beforeIteration()
if(!pointStructure::beforeIteration())return false;
velocityUpdateTimer_.start();
velocity_.updateBoundariesSlaveToMasterIfRequested();
acceleration_.updateBoundariesSlaveToMasterIfRequested();
integrationPos_->updateBoundariesSlaveToMasterIfRequested();
integrationVel_->updateBoundariesSlaveToMasterIfRequested();
velocityUpdateTimer_.end();
return true;
}
@ -93,34 +115,32 @@ bool pFlow::dynamicPointStructure::iterate()
{
return pointStructure::iterate();
/*real dt = this->dt();
auto& acc = time().lookupObject<realx3PointField_D>("acceleration");
return correct(dt, acc);*/
}
bool pFlow::dynamicPointStructure::predict(
real dt,
realx3PointField_D &acceleration)
bool pFlow::dynamicPointStructure::afterIteration()
{
//const auto ti = TimeInfo();
auto succs = pointStructure::afterIteration();
return succs;
}
bool pFlow::dynamicPointStructure::predict(real dt)
{
if(!integrationPos_().predict(dt, pointPosition(), velocity_ ))return false;
if(!integrationVel_().predict(dt, velocity_, acceleration))return false;
if(!integrationVel_().predict(dt, velocity_, acceleration_))return false;
return true;
}
bool pFlow::dynamicPointStructure::correct
(
real dt,
realx3PointField_D& acceleration
)
bool pFlow::dynamicPointStructure::correct(real dt)
{
//auto& pos = pStruct().pointPosition();
const auto& ti = TimeInfo();
if(!integrationPos_().correct(dt, pointPosition(), velocity_) )return false;
if(!integrationVel_().correct(dt, velocity_, acceleration))return false;
if(!integrationPos_().correctPStruct(dt, *this, velocity_) )return false;
if(!integrationVel_().correct(dt, velocity_, acceleration_, dampingFactor(ti)))return false;
return true;
}

View File

@ -26,11 +26,13 @@ Licence:
#include "pointFields.hpp"
#include "integration.hpp"
#include "uniquePtr.hpp"
#include "globalDamping.hpp"
namespace pFlow
{
class systemControl;
//class globalDamping;
class dynamicPointStructure
:
@ -40,10 +42,15 @@ private:
realx3PointField_D velocity_;
/// acceleration on device
realx3PointField_D acceleration_;
uniquePtr<integration> integrationPos_ = nullptr;
uniquePtr<integration> integrationVel_ = nullptr;
uniquePtr<globalDamping> velDamping_ = nullptr;
Timer velocityUpdateTimer_;
/// @brief integration method for velocity and position
@ -53,7 +60,7 @@ public:
TypeInfo("dynamicPointStructure");
explicit dynamicPointStructure(systemControl& control);
explicit dynamicPointStructure(systemControl& control, real maxBSphere);
dynamicPointStructure(const dynamicPointStructure& ps) = delete;
@ -82,18 +89,42 @@ public:
return velocity_;
}
inline
const realx3PointField_D& acceleration()const
{
return acceleration_;
}
inline
realx3PointField_D& acceleration()
{
return acceleration_;
}
inline
real dampingFactor(const timeInfo& ti)const
{
if(velDamping_)
{
return velDamping_().dampingFactor(ti);
}
return 1.0;
}
/// In the time loop before iterate
bool beforeIteration() override;
/// @brief This is called in time loop. Perform the main calculations
/// when the component should evolve along time.
bool iterate() override;
bool afterIteration()override;
/// prediction step (if any), is called in beforeIteration
bool predict(real dt, realx3PointField_D& acceleration);
bool predict(real dt);
/// correction step, is called in iterate
bool correct(real dt, realx3PointField_D& acceleration);
bool correct(real dt);
};

View File

@ -0,0 +1,54 @@
/*------------------------------- 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 "globalDamping.hpp"
pFlow::globalDamping::globalDamping(const systemControl& control)
:
timeControl_(control.settingsDict().subDict("globalDamping"), control.time().dt(), "damping")
{
const dictionary& dict = control.settingsDict().subDict("globalDamping");
dampingFactor_ = dict.getValMin<real>("dampingFactor", static_cast<real>(1.0));
dampingFactor_ = max( dampingFactor_ , static_cast<real>(0.01));
performDamping_ = !equal(dampingFactor_, static_cast<real>(1.0));
if( performDamping_ )
{
REPORT(2)<<"Global damping "<<Yellow_Text("is active")<<
" and damping factor is "<<dampingFactor_<<END_REPORT;
}
else
{
REPORT(2)<<"Global damping "<<Yellow_Text("is not active")<<"."<<END_REPORT;
}
}
pFlow::real pFlow::globalDamping::dampingFactor(const timeInfo& ti)const
{
if(!performDamping_) return 1.0;
if(!timeControl_.eventTime(ti ))return 1.0;
return dampingFactor_;
}

View File

@ -0,0 +1,62 @@
/*------------------------------- 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 __globalDamping_hpp__
#define __globalDamping_hpp__
#include "systemControl.hpp"
#include "pointFields.hpp"
#include "baseTimeControl.hpp"
namespace pFlow
{
class globalDamping
{
private:
bool performDamping_ = false;
real dampingFactor_;
baseTimeControl timeControl_;
public:
globalDamping(const systemControl& control);
~globalDamping()=default;
bool dampingActive()const
{
return performDamping_;
}
real dampingFactor(const timeInfo& ti)const;
};
}
#endif

View File

@ -41,16 +41,14 @@ pFlow::particleIdHandler::particleIdHandler(pointStructure& pStruct)
bool
pFlow::particleIdHandler::hearChanges(
real t,
real dt,
uint32 iter,
const timeInfo& ti,
const message& msg,
const anyList& varList
)
{
if(msg.equivalentTo(message::ITEM_INSERT))
if(msg.equivalentTo(message::ITEMS_INSERT))
{
const word eventName = message::eventName(message::ITEM_INSERT);
const word eventName = message::eventName(message::ITEMS_INSERT);
const auto& indices = varList.getObject<uint32IndexContainer>(
eventName);
@ -66,7 +64,7 @@ pFlow::particleIdHandler::hearChanges(
}
else
{
return uint32PointField_D::hearChanges(t,dt,iter, msg,varList);
return uint32PointField_D::hearChanges(ti, msg, varList);
}
}

View File

@ -60,15 +60,11 @@ public:
virtual
uint32 maxId()const = 0;
// heat change for possible insertion of particles
// overrdie from internalField
bool hearChanges
(
real t,
real dt,
uint32 iter,
const timeInfo& ti,
const message& msg,
const anyList& varList
) override;

View File

@ -18,22 +18,12 @@ Licence:
-----------------------------------------------------------------------------*/
#include "particles.hpp"
#include "shape.hpp"
pFlow::particles::particles(systemControl& control)
pFlow::particles::particles(systemControl& control, const shape& shapes)
: observer(defaultMessage_),
demComponent("particles", control),
dynPointStruct_(control),
/*id_(
objectFile(
"id",
"",
objectFile::READ_IF_PRESENT,
objectFile::WRITE_ALWAYS
),
dynPointStruct_,
static_cast<uint32>(-1),
static_cast<uint32>(-1)
),*/
dynPointStruct_(control, shapes.maxBoundingSphere()),
shapeIndex_(
objectFile(
"shapeIndex",
@ -44,16 +34,6 @@ pFlow::particles::particles(systemControl& control)
dynPointStruct_,
0
),
accelertion_(
objectFile(
"accelertion",
"",
objectFile::READ_IF_PRESENT,
objectFile::WRITE_ALWAYS
),
dynPointStruct_,
zero3
),
contactForce_(
objectFile(
"contactForce",
@ -82,6 +62,12 @@ pFlow::particles::particles(systemControl& control)
//idHandler_().initialIdCheck();
}
pFlow::particles::~particles()
{
// invalidates / unsobscribe from subscriber before its actual destruction
addToSubscriber(nullptr, message::Empty());
}
bool
pFlow::particles::beforeIteration()
{
@ -94,7 +80,6 @@ pFlow::particles::beforeIteration()
zeroTorque();
baseFieldBoundaryUpdateTimer_.start();
shapeIndex_.updateBoundariesSlaveToMasterIfRequested();
accelertion_.updateBoundariesSlaveToMasterIfRequested();
idHandler_().updateBoundariesSlaveToMasterIfRequested();
baseFieldBoundaryUpdateTimer_.end();
return true;

View File

@ -25,11 +25,14 @@ PARTICULAR PURPOSE.
#include "demComponent.hpp"
#include "dynamicPointStructure.hpp"
#include "particleIdHandler.hpp"
#include "shape.hpp"
//#include "shape.hpp"
namespace pFlow
{
class shape;
class particles
: public observer
, public demComponent
@ -42,9 +45,6 @@ private:
/// shape index of each particle
uint32PointField_D shapeIndex_;
/// acceleration on device
realx3PointField_D accelertion_;
/// contact force field
realx3PointField_D contactForce_;
@ -57,7 +57,7 @@ private:
Timer baseFieldBoundaryUpdateTimer_;
/// messages for this objects
static inline const message defaultMessage_{ message::DEFAULT };
static inline const message defaultMessage_= message::Empty();
protected:
@ -96,7 +96,9 @@ public:
// type info
TypeInfo("particles");
explicit particles(systemControl& control);
explicit particles(systemControl& control, const shape& shapes);
~particles() override;
inline const auto& dynPointStruct() const
{
@ -153,14 +155,14 @@ public:
return dynPointStruct_.velocity();
}
inline const auto& accelertion() const
inline const auto& acceleration() const
{
return accelertion_;
return dynPointStruct_.acceleration();
}
inline auto& accelertion()
inline auto& acceleration()
{
return accelertion_;
return dynPointStruct_.acceleration();
}
inline auto& contactForce()
@ -184,7 +186,7 @@ public:
}
inline
uint maxId()const
uint32 maxId()const
{
return idHandler_().maxId();
}

View File

@ -1,5 +1,24 @@
#include "shape.hpp"
/*------------------------------- 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 "shape.hpp"
bool pFlow::shape::findPropertyIds()
{
@ -62,6 +81,18 @@ pFlow::shape::shape
}
pFlow::shape::shape
(
const word &shapeType,
const word &fileName,
repository *owner,
const property &prop
)
:
shape(fileName, owner, prop)
{
}
bool pFlow::shape::writeToDict(dictionary &dict)const
{
if(!baseShapeNames::writeToDict(dict))return false;
@ -74,4 +105,37 @@ bool pFlow::shape::writeToDict(dictionary &dict)const
}
return true;
}
}
pFlow::uniquePtr<pFlow::shape> pFlow::shape::create
(
const word &shapeType,
const word &fileName,
repository *owner,
const property &prop
)
{
word type = angleBracketsNames("shape", shapeType);
if( wordvCtorSelector_.search(type) )
{
auto objPtr =
wordvCtorSelector_[type]
(shapeType, fileName, owner, prop);
return objPtr;
}
else
{
printKeys
(
fatalError << "Ctor Selector "<<
type << " dose not exist. \n"
<<"Avaiable ones are: \n\n"
,
wordvCtorSelector_
);
fatalExit;
return nullptr;
}
}

View File

@ -37,7 +37,7 @@ private:
const property& property_;
/// list of property ids of shapes (index)
uint32Vector shapePropertyIds_;
uint32Vector shapePropertyIds_;
/// list of material names
wordVector materialNames_;
@ -60,9 +60,28 @@ public:
const word& fileName,
repository* owner,
const property& prop);
shape(
const word& shapeType,
const word& fileName,
repository* owner,
const property& prop);
~shape() override=default;
create_vCtor
(
shape,
word,
(
const word& shapeType,
const word& fileName,
repository* owner,
const property& prop
),
(shapeType, fileName, owner, prop)
);
inline
const auto& properties()const
{
@ -148,6 +167,9 @@ public:
virtual
realVector boundingDiameter()const = 0;
virtual
realVector volume()const = 0;
virtual
bool mass(uint32 index, real& m)const = 0;
@ -187,6 +209,13 @@ public:
virtual
real Inertial_zz(uint32 index)const = 0;
static
uniquePtr<shape> create(
const word& shapeType,
const word& fileName,
repository* owner,
const property& prop);
};
}