Particle base class and sphereParticle class have been updated

This commit is contained in:
Hamidreza Norouzi
2024-01-25 03:07:59 -08:00
parent 9c86fe8f31
commit 20be76aed0
11 changed files with 1051 additions and 523 deletions

View File

@ -0,0 +1,114 @@
/*------------------------------- 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 "baseShapeNames.hpp"
bool pFlow::baseShapeNames::createHashNames()
{
hashNames_.clear();
uint32 i=0;
for(const auto& nm:shapeNames_)
{
if(!hashNames_.insertIf(nm, i))
{
fatalErrorInFunction<<
" repeated name in the list of shape names: " << shapeNames_;
return false;
}
i++;
}
hashNames_.rehash(0);
return true;
}
bool pFlow::baseShapeNames::readFromDictionary()
{
shapeNames_ = getVal<wordVector>("names");
numShapes_ = shapeNames_.size();
return true;
}
pFlow::baseShapeNames::baseShapeNames
(
const word &fileName,
repository *owner
)
:
fileDictionary
(
objectFile
(
fileName,
"",
objectFile::READ_ALWAYS,
objectFile::WRITE_ALWAYS
),
owner
)
{
if( !readFromDictionary() )
{
fatalExit;
}
if( !createHashNames())
{
fatalExit;
}
}
bool pFlow::baseShapeNames::writeToDict(dictionary &dict)const
{
if( !dict.add("names", shapeNames_) )
{
fatalErrorInFunction<<
" Error in writing names to dictionary "<< dict.globalName()<<endl;
return false;
}
return true;
}
bool pFlow::baseShapeNames::write(iOstream &os) const
{
dictionary newDict(fileDictionary::dictionary::name(), true);
if( !writeToDict(newDict) )
{
return false;
}
if( !newDict.write(os) )
{
fatalErrorInFunction<<"Error in writing dictionary "<< globalName()<<
"to stream "<< os.name()<<endl;
return false;
}
return true;
}

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 __baseShapeNames_hpp__
#define __baseShapeNames_hpp__
#include "fileDictionary.hpp"
#include "Vectors.hpp"
#include "hashMap.hpp"
namespace pFlow
{
class repository;
class baseShapeNames
:
public fileDictionary
{
private:
size_t numShapes_;
// - hashed list of spheres names
wordHashMap<uint32> hashNames_;
/// list of shape names
wordVector shapeNames_;
bool createHashNames();
bool readFromDictionary();
protected:
virtual
bool writeToDict(dictionary& dict)const;
public:
TypeInfo("baseShapeNames");
baseShapeNames(
const word& fileName,
repository* owner);
~baseShapeNames() override=default;
inline
const wordVector& shapeNames()const
{
return shapeNames_;
}
inline
wordList shapeNameList()const
{
wordList wl;
wl.insert(wl.begin(), shapeNames_.begin(), shapeNames_.end());
return wl;
}
inline
size_t numShapes()const
{
return numShapes_;
}
// name to index
inline
bool shapeNameToIndex(const word& name, uint32& index)const
{
if(auto[iter, found] = hashNames_.findIf(name); found )
{
index = iter->second;
return true;
}
else
{
index = 0;
return false;
}
}
inline
bool indexToShapeName(uint32 i, word& name)const
{
if( i < numShapes_)
{
name = shapeNames_[i];
return true;
}
return false;
}
inline
bool indexValid(uint32 index)const
{
return index < numShapes_;
}
// - IO
bool write(iOstream& os)const override;
};
}
#endif //__shapeNames_hpp__

View File

@ -21,17 +21,71 @@ Licence:
#include "particles.hpp"
bool pFlow::particles::initMassDiameter()const
{
auto [minIndex, maxIndex] = minMax(shapeIndex_.internal());
const auto& shp = getShapes();
if( !shp.indexValid(maxIndex) )
{
fatalErrorInFunction<<
"the maximum value of shape index is "<< maxIndex <<
" which is not valid."<<endl;
return false;
}
realVector_D d("diameter", shp.boundingDiameter());
realVector_D mass("mass",shp.mass());
uint8Vector_D propId("propId", shp.shapePropertyIds());
auto aPointsMask = dynPointStruct_.activePointsMaskDevice();
auto aRange = aPointsMask.activeRange();
using exeSpace = typename realPointField_D::execution_space;
using policy = Kokkos::RangePolicy<
exeSpace,
Kokkos::IndexType<uint32>>;
auto field_diameter = diameter_.fieldDevice();
auto field_mass = mass_.fieldDevice();
auto field_propId = propertyId_.fieldDevice();
auto field_shapeIndex = shapeIndex_.fieldDevice();
auto d_d = d.deviceVector();
auto d_mass = mass.deviceVector();
auto d_propId = propId.deviceVector();
Kokkos::parallel_for(
"particles::initMassDiameter",
policy(aRange.start(), aRange.end()),
LAMBDA_HD(uint32 i)
{
if(aPointsMask(i))
{
uint32 index = field_shapeIndex[i];
field_diameter[i] = d_d[index];
field_mass[i] = d_mass[index];
field_propId[i] = d_propId[index];
}
});
Kokkos::fence();
return true;
}
pFlow::particles::particles
(
systemControl& control
systemControl &control
)
:
observer(),
:
observer(defaultMessage_),
demComponent("particles", control),
dynPointStruct_(control),
id_
(
(
objectFile
(
"id",
@ -48,127 +102,108 @@ pFlow::particles::particles
(
"propertyId",
"",
objectFile::READ_NEVER,
objectFile::READ_ALWAYS,
objectFile::WRITE_NEVER
),
dynPointStruct_,
static_cast<int8>(0)
),
diameter_
shapeIndex_
(
objectFile
(
"shapeIndex",
"",
objectFile::READ_ALWAYS,
objectFile::WRITE_ALWAYS
),
dynPointStruct_,
0
),
diameter_
(
objectFile(
"diameter",
"",
objectFile::READ_NEVER,
objectFile::WRITE_ALWAYS
),
objectFile::WRITE_NEVER),
dynPointStruct_,
0.00000000001
),
mass_
(
objectFile
(
objectFile(
"mass",
"",
objectFile::READ_NEVER,
objectFile::WRITE_ALWAYS
),
objectFile::WRITE_NEVER),
dynPointStruct_,
0.0000000001
),
accelertion_
(
objectFile
(
objectFile(
"accelertion",
"",
objectFile::READ_IF_PRESENT,
objectFile::WRITE_ALWAYS
),
objectFile::WRITE_ALWAYS),
dynPointStruct_,
zero3
),
contactForce_
(
objectFile
(
contactForce_(
objectFile(
"contactForce",
"",
objectFile::READ_IF_PRESENT,
objectFile::WRITE_ALWAYS
),
objectFile::WRITE_ALWAYS),
dynPointStruct_,
zero3
),
contactTorque_
(
objectFile
(
zero3),
contactTorque_(
objectFile(
"contactTorque",
"",
objectFile::READ_IF_PRESENT,
objectFile::WRITE_ALWAYS
),
objectFile::WRITE_ALWAYS),
dynPointStruct_,
zero3
)
zero3)
{
WARNING<<"Subscribe particles"<<END_WARNING;
//this->subscribe(pStruct());
this->addToSubscriber(dynPointStruct_);
if(!initMassDiameter())
{
fatalExit;
}
}
bool pFlow::particles::beforeIteration()
{
/*auto domain = this->control().domain();
auto numMarked = dynPointStruct_.markDeleteOutOfBox(domain);
if(time_.sortTime())
{
real min_dx, max_dx;
boundingSphereMinMax(min_dx, max_dx);
Timer t;
t.start();
REPORT(0)<<"Performing morton sorting on particles ...."<<endREPORT;
if(!pStruct().mortonSortPoints(domain, max_dx))
{
fatalErrorInFunction<<"Morton sorting was not successful"<<endl;
return false;
}
t.end();
REPORT(1)<<"Active range is "<< pStruct().activeRange()<<endREPORT;
REPORT(1)<<"It took "<< yellowText(t.totalTime())<<" seconds."<<endREPORT;
}
this->zeroForce();
this->zeroTorque();*/
dynPointStruct_.beforeIteration();
zeroForce();
zeroTorque();
return true;
}
/*pFlow::uniquePtr<pFlow::List<pFlow::eventObserver*>>
pFlow::particles::getFieldObjectList()const
bool pFlow::particles::iterate()
{
auto objListPtr = makeUnique<pFlow::List<pFlow::eventObserver*>>();
objListPtr().push_back(
static_cast<eventObserver*>(&id_) );
objListPtr().push_back(
static_cast<eventObserver*>(&propertyId_) );
return dynPointStruct_.iterate();
}
objListPtr().push_back(
static_cast<eventObserver*>(&diameter_) );
bool pFlow::particles::afterIteration()
{
return dynPointStruct_.afterIteration();
}
objListPtr().push_back(
static_cast<eventObserver*>(&mass_) );
objListPtr().push_back(
static_cast<eventObserver*>(&shapeName_) );
return objListPtr;
}*/
void pFlow::particles::boundingSphereMinMax
(
real &minDiam,
real &maxDiam
) const
{
auto& shp = getShapes();
minDiam = shp.minBoundingSphere();
maxDiam = shp.maxBoundingSphere();
}

View File

@ -24,6 +24,7 @@ Licence:
#include "dynamicPointStructure.hpp"
#include "demComponent.hpp"
#include "shape.hpp"
namespace pFlow
{
@ -39,43 +40,51 @@ private:
/// dynamic point structure for particles center mass
dynamicPointStructure dynPointStruct_;
// - name of shapes - this is managed by particles
//wordPointField& shapeName_;
/// id of particles on host
uint32PointField_D id_;
// id of particles on host
int32PointField_D id_;
/// property id on device
uint8PointField_D propertyId_;
// property id on device
int8PointField_D propertyId_;
/// property id on device
uint32PointField_D shapeIndex_;
// diameter / boundig sphere size of particles on device
/// diameter / boundig sphere size of particles on device
realPointField_D diameter_;
// mass of particles field
/// mass of particles field
realPointField_D mass_;
// - acceleration on device
realx3PointField_D accelertion_;
/// acceleration on device
realx3PointField_D accelertion_;
/// contact force field
realx3PointField_D contactForce_;
/// contact torque field
realx3PointField_D contactTorque_;
realx3PointField_D contactTorque_;
static inline
const message defaultMessage_ =
(
message::CAP_CHANGED+
message::SIZE_CHANGED+
message::ITEM_INSERT+
message::ITEM_DELETE
);
bool initMassDiameter()const;
void zeroForce()
{
WARNING<<"fill contactTorque"<<END_WARNING;
//contactForce_.fill(zero3);
contactForce_.fill(zero3);
}
void zeroTorque()
{
WARNING<<"fill contactTorque"<<END_WARNING;
//contactTorque_.fill(zero3);
contactTorque_.fill(zero3);
}
protected:
inline auto& dynPointStruct()
@ -94,6 +103,12 @@ protected:
return dynPointStruct_.velocity();
}
inline
auto& shapeIndex()
{
return shapeIndex_;
}
public:
// type info
@ -208,16 +223,12 @@ public:
return propertyId_;
}
/*inline const auto& shapeName()const{
return shapeName_;
}*/
/*inline auto& shapName(){
return shapeName_;
}*/
bool beforeIteration() override;
bool iterate()override;
bool afterIteration() override;
/*virtual
bool insertParticles
(
@ -234,14 +245,17 @@ public:
virtual
const realx3PointField_D& rAcceleration() const = 0;
/*virtual
const realVector_D& boundingSphere()const = 0;*/
virtual
const realPointField_D& boundingSphere()const = 0;
virtual
word shapeTypeName()const = 0;
virtual
void boundingSphereMinMax(real & minDiam, real& maxDiam)const = 0;
const shape& getShapes()const = 0;
virtual
void boundingSphereMinMax(real & minDiam, real& maxDiam)const;

View File

@ -0,0 +1,76 @@
#include "shape.hpp"
bool pFlow::shape::findPropertyIds()
{
shapePropertyIds_.resize(numShapes());
ForAll( i, materialNames_)
{
if(uint32 propId; property_.nameToIndex(materialNames_[i], propId) )
{
shapePropertyIds_[i] = static_cast<uint8>(propId);
}
else
{
fatalErrorInFunction<<"Material name "<< materialNames_[i]<<
"is not valid in dictionary "<<globalName()<<endl;
return false;
}
}
return false;
}
bool pFlow::shape::readFromDictionary()
{
materialNames_ = getVal<wordVector>("materials");
if(materialNames_.size() != numShapes() )
{
fatalErrorInFunction<<
" number of elements in materials and names are not the same in "<< globalName()<<endl;
return false;
}
return true;
}
pFlow::shape::shape
(
const word &fileName,
repository *owner,
const property &prop
)
:
baseShapeNames(fileName,owner),
property_(prop)
{
if( !readFromDictionary() )
{
fatalExit;
}
if(!findPropertyIds())
{
fatalExit;
}
}
bool pFlow::shape::writeToDict(dictionary &dict)const
{
if(!baseShapeNames::writeToDict(dict))return false;
if( !dict.add("materials", materialNames_) )
{
fatalErrorInFunction<<
" Error in writing materials to dictionary "<< dict.globalName()<<endl;
return false;
}
return true;
}

View File

@ -0,0 +1,183 @@
/*------------------------------- 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 __shape_hpp__
#define __shape_hpp__
#include "baseShapeNames.hpp"
#include "property.hpp"
namespace pFlow
{
class shape
:
public baseShapeNames
{
private:
/// property of materials
const property& property_;
/// list of property ids of shapes (index)
uint8Vector shapePropertyIds_;
/// list of material names
wordVector materialNames_;
bool findPropertyIds();
bool readFromDictionary();
protected:
bool writeToDict(dictionary& dict)const override;
public:
TypeInfo("shape");
shape(
const word& fileName,
repository* owner,
const property& prop);
~shape() override=default;
inline
const auto& properties()const
{
return property_;
}
inline
const wordVector& materialNames()const
{
return materialNames_;
}
inline
const auto& shapePropertyIds()const
{
return shapePropertyIds_;
}
inline
bool shapeNameToPropId(const word& name, int8& propId)const
{
if(uint32 index; shapeNameToIndex(name, index))
{
propId = shapePropertyIds_[index];
return true;
}
return false;
}
inline
bool propIdValid(int8 propId)const
{
return static_cast<uint32>(propId) < property_.numMaterials();
}
inline
bool indexToDensity(uint32 index, real& rho)const
{
if(indexValid(index))
return property_.density(shapePropertyIds_[index], rho);
return false;
}
inline
real indexToDensity(uint32 index)const
{
if(indexValid(index))
{
return property_.density(shapePropertyIds_[index]);
}
fatalExit;
return 0.0;
}
virtual
real maxBoundingSphere()const = 0;
virtual
real minBoundingSphere()const = 0;
virtual
bool boundingDiameter(uint32 index, real& bDiam)const =0;
virtual
real boundingDiameter(uint32 index)const = 0;
virtual
realVector boundingDiameter()const = 0;
virtual
bool mass(uint32 index, real& m)const = 0;
virtual
real mass(uint32 index) const =0;
virtual
realVector mass()const =0;
virtual
realVector density()const =0;
virtual
bool Inertia(uint32 index, real& I)const = 0;
virtual
real Inertia(uint32 index)const = 0;
virtual
realVector Inertia()const=0;
virtual
bool Inertia_xx(uint32 index, real& Ixx)const = 0;
virtual
real Inertial_xx(uint32 index)const =0;
virtual
bool Inertia_yy(uint32 index, real& Iyy)const = 0;
virtual
real Inertial_yy(uint32 index)const = 0;
virtual
bool Inertia_zz(uint32 index, real& Izz)const = 0;
virtual
real Inertial_zz(uint32 index)const = 0;
};
}
#endif //__shape_hpp__