mirror of
https://github.com/PhasicFlow/phasicFlow.git
synced 2025-06-22 16:28:30 +00:00
This is the first merge from main into MPI branch
Merge branch 'main' into local-MPI
This commit is contained in:
@ -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)
|
||||
|
64
src/Particles/GrainParticles/boundaryGrainParticles.cpp
Normal file
64
src/Particles/GrainParticles/boundaryGrainParticles.cpp
Normal 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;
|
||||
}
|
83
src/Particles/GrainParticles/boundaryGrainParticles.hpp
Normal file
83
src/Particles/GrainParticles/boundaryGrainParticles.hpp
Normal 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
|
20
src/Particles/GrainParticles/boundaryGrainParticlesList.cpp
Normal file
20
src/Particles/GrainParticles/boundaryGrainParticlesList.cpp
Normal 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)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
36
src/Particles/GrainParticles/boundaryGrainParticlesList.hpp
Normal file
36
src/Particles/GrainParticles/boundaryGrainParticlesList.hpp
Normal 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
|
421
src/Particles/GrainParticles/grainParticles/grainParticles.cpp
Normal file
421
src/Particles/GrainParticles/grainParticles/grainParticles.cpp
Normal 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();
|
||||
}
|
247
src/Particles/GrainParticles/grainParticles/grainParticles.hpp
Normal file
247
src/Particles/GrainParticles/grainParticles/grainParticles.hpp
Normal 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__
|
@ -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();
|
||||
}
|
@ -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
|
261
src/Particles/GrainParticles/grainShape/grainShape.cpp
Normal file
261
src/Particles/GrainParticles/grainShape/grainShape.cpp
Normal 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);
|
||||
}
|
128
src/Particles/GrainParticles/grainShape/grainShape.hpp
Normal file
128
src/Particles/GrainParticles/grainShape/grainShape.hpp
Normal 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__
|
@ -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>;
|
@ -24,11 +24,15 @@ Licence:
|
||||
|
||||
#include "Insertion.hpp"
|
||||
#include "sphereShape.hpp"
|
||||
#include "grainShape.hpp"
|
||||
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
using sphereInsertion = Insertion<sphereShape> ;
|
||||
using grainInsertion = Insertion<grainShape> ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -24,6 +24,7 @@ Licence:
|
||||
#include "particles.hpp"
|
||||
#include "twoPartEntry.hpp"
|
||||
#include "types.hpp"
|
||||
#include "shape.hpp"
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
(
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) )
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
54
src/Particles/globalDamping/globalDamping.cpp
Normal file
54
src/Particles/globalDamping/globalDamping.cpp
Normal 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_;
|
||||
}
|
62
src/Particles/globalDamping/globalDamping.hpp
Normal file
62
src/Particles/globalDamping/globalDamping.hpp
Normal 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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user