Merge pull request #103 from PhasicFlow/develop

Particle insertion upgrade and pointStructure selectors
This commit is contained in:
PhasicFlow 2024-04-18 00:37:03 +03:30 committed by GitHub
commit ce57a18c4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 615 additions and 281 deletions

View File

@ -34,7 +34,7 @@ pFlow::particleWallContactSearchs<method>::particleWallContactSearchs
domainBox_(domain), domainBox_(domain),
updateInterval_ updateInterval_
( (
dict.getValOrSet<uint32>("updateInterval", 1) max(dict.getValOrSet<uint32>("updateInterval", 1),1u)
) )
{ {

View File

@ -18,31 +18,7 @@ Licence:
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
/*template<typename ShapeType>
bool pFlow::Insertion<ShapeType>::readInsertionDict
(
const dictionary& dict
)
{
if(!insertion::readInsertionDict(dict)) return false;
regions_.clear();
if( !this->isActive() )
{
return true;
}
wordList regionDicNames = dict.dictionaryKeywords();
for(auto& name:regionDicNames)
{
REPORT(2)<<"reading insertion region "<< greenText(name)<<endREPORT;
regions_.push_backSafe(dict.subDict(name), shapes_);
}
return true;
}
template<typename ShapeType> template<typename ShapeType>
bool pFlow::Insertion<ShapeType>::writeInsertionDict bool pFlow::Insertion<ShapeType>::writeInsertionDict
@ -50,7 +26,8 @@ bool pFlow::Insertion<ShapeType>::writeInsertionDict
dictionary& dict dictionary& dict
)const )const
{ {
if( !insertion::writeInsertionDict(dict) ) return false;
if(!insertion::writeInsertionDict(dict))return false;
if( !this->isActive() ) return true; if( !this->isActive() ) return true;
@ -60,16 +37,18 @@ bool pFlow::Insertion<ShapeType>::writeInsertionDict
if( !regions_[i].write(rgnDict) ) if( !regions_[i].write(rgnDict) )
{ {
fatalErrorInFunction<<
"Error in writing to dictionary "<<rgnDict.globalName()<<endl;
return false; return false;
} }
} }
return true; return true;
}*/ }
template<typename ShapeType> template<typename ShapeType>
bool bool
pFlow::Insertion<ShapeType>::setInsertionRegions() pFlow::Insertion<ShapeType>::readInsertionDict()
{ {
regions_.clear(); regions_.clear();
@ -102,7 +81,7 @@ pFlow::Insertion<ShapeType>::Insertion(
insertion(prtcl), insertion(prtcl),
shapes_(shapes) shapes_(shapes)
{ {
if(!setInsertionRegions()) if(!readInsertionDict())
{ {
fatalErrorInFunction; fatalErrorInFunction;
fatalExit; fatalExit;

View File

@ -62,12 +62,11 @@ private:
// - insertion regions // - insertion regions
ListPtr<InsertionRegion<ShapeType>> regions_; ListPtr<InsertionRegion<ShapeType>> regions_;
bool readInsertionDict();
bool setInsertionRegions(); protected:
// bool readInsertionDict(const dictionary& dict); bool writeInsertionDict(dictionary& dict)const override;
// bool writeInsertionDict(dictionary& dict)const;
public: public:

View File

@ -55,8 +55,8 @@ bool pFlow::InsertionRegion<ShapeType>::insertParticles
uint32 iter, uint32 iter,
real t, real t,
real dt, real dt,
wordVector& names, wordVector& names,
realx3Vector& pos, realx3Vector& positions,
bool& insertionOccured bool& insertionOccured
) )
{ {
@ -65,65 +65,185 @@ bool pFlow::InsertionRegion<ShapeType>::insertParticles
if(!insertionTime(iter, t, dt)) return true; if(!insertionTime(iter, t, dt)) return true;
uint32 newNum = numberToBeInserted(iter, t, dt); uint32 newNum = numberToBeInserted(iter, t, dt);
if(newNum == 0) return true; if(newNum == 0) return true;
// get the internal box
auto internalBox = pStruct().internalDomainBox(); auto internalBox = pStruct().internalDomainBox();
if( !(internalBox.minPoint() < internalBox.maxPoint())) if( !(internalBox.minPoint() < internalBox.maxPoint()))
{ {
WARNING<<"Minimum point of internal point is not lower than "<< WARNING<<"Minimum point of internal point is not lower than "<<
"the maximum point \n"<< "the maximum point \n"<<
"minimum point: "<< internalBox.minPoint()<< "minimum point: "<< internalBox.minPoint()<<
"\nmaximum point:"<<internalBox.maxPoint()<<END_WARNING; "\nmaximum point:"<<internalBox.maxPoint()<<END_WARNING;
return false;
} }
names.reserve(max(newNum,names.capacity()));
pos.reserve(max(newNum,pos.capacity()));
names.clear();
pos.clear();
realVector diams("diams", newNum, 0, RESERVE());
size_t n = 0;
uint32 idx; /// reserve enough space
names.reserve(max(newNum,names.capacity()));
names.clear();
positions.reserve(max(newNum,positions.capacity()));
positions.clear();
auto allPositions = realx3Vector("allPositions");
auto allDiameters = realVector("allDiameters");
auto& mix = mixture(); auto& mix = mixture();
auto& pReg = pRegion(); auto& pReg = pRegion();
real maxDiam = shapes_.maxBoundingSphere();
auto minP = pReg.minPoint() - maxDiam;
auto maxP = pReg.maxPoint() + maxDiam;
if(Insertion().checkForCollision())
{
// check for collision with already inserted particles
// so, use selector to select particles in the simulation
auto bDict = dictionary("boxInfo");
bDict.add("min", minP);
bDict.add("max", maxP);
auto selector = pStructSelector::create(
"box",
pStruct(),
bDict);
allPositions = selector().selectedPointPositions();
allDiameters = selectedFieldVals<real>
(
selector(),
Insertion().diameterName()
);
}
auto collCheck = collisionCheck(
{minP, maxP},
maxDiam,
allPositions,
allDiameters);
uint32 numInserted = 0;
uint32 idx;
word name = mix.getNextShapeName(); word name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx); shapes_.shapeNameToIndex(name, idx);
real d = shapes_.boundingDiameter(idx); real d = shapes_.boundingDiameter(idx);
for(uint32 i=0; i< 100*newNum ; ++i) for(uint32 i=0; i< 100*newNum ; ++i)
{ {
realx3 p = pReg.peek(); realx3 p = pReg.peek();
// check if point is inside internal box // check if point is inside internal box
if(!internalBox.isInside(p))continue; if(!internalBox.isInside(p))continue;
if( !checkForContact(pos, diams, p, d) ) if( collCheck.checkPoint( p, d) )
{ {
names.push_back(name); names.push_back(name);
pos.push_back(p); positions.push_back(p);
diams.push_back(d); numInserted++;
n++; if( numInserted == newNum ) break;
if( n == newNum ) // add this new particle to collision check set
{ allDiameters.push_back(d);
addToNumInserted(newNum); allPositions.push_back(p);
insertionOccured = true; collCheck.mapLastAddedParticle();
return true;
} // obtain next shape name and diameter
name = mix.getNextShapeName(); name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx); shapes_.shapeNameToIndex(name, idx);
d = shapes_.boundingDiameter(idx); d = shapes_.boundingDiameter(idx);
} }
} }
addToNumInserted(n);
insertionOccured = true; insertionOccured = true;
return false; addToNumInserted(numInserted);
} return numInserted == newNum;
}
/*if(!checkForCollision)
{
realVector diams("diams", newNum, 0, RESERVE());
uint32 idx;
word name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
real d = shapes_.boundingDiameter(idx);
for(uint32 i=0; i< 100*newNum ; ++i)
{
realx3 p = pReg.peek();
// check if point is inside internal box
if(!internalBox.isInside(p))continue;
if( !checkForContact(positions, diams, p, d) )
{
names.push_back(name);
positions.push_back(p);
diams.push_back(d);
numInserted++;
if( numInserted == newNum ) break;
name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
d = shapes_.boundingDiameter(idx);
}
}
}
else
{
real maxDiam = shapes_.maxBoundingSphere();
auto minP = pReg.minPoint() - maxDiam;
auto maxP = pReg.maxPoint() + maxDiam;
auto bDict = dictionary("boxInfo");
bDict.add("min", minP);
bDict.add("max", maxP);
auto selector = pStructSelector::create(
"box",
pStruct(),
bDict);
auto allPositions = selector().selectedPointPositions();
auto allDiameters = selectedFieldVals<real>(selector(), "diameter");
auto collCheck = collisionCheck(
{minP, maxP},
maxDiam,
allPositions,
allDiameters);
uint32 idx;
word name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
real d = shapes_.boundingDiameter(idx);
for(uint32 i=0; i< 100*newNum ; ++i)
{
realx3 p = pReg.peek();
// check if point is inside internal box
if(!internalBox.isInside(p))continue;
if( collCheck.checkPoint( p, d) )
{
names.push_back(name);
positions.push_back(p);
numInserted++;
if( numInserted == newNum ) break;
// add this new particle to collision check set
allDiameters.push_back(d);
allPositions.push_back(p);
collCheck.mapLastAddedParticle();
// obtain next shape name and diameter
name = mix.getNextShapeName();
shapes_.shapeNameToIndex(name, idx);
d = shapes_.boundingDiameter(idx);
}
}
}*/

View File

@ -21,9 +21,15 @@ Licence:
#ifndef __InsertionRegion_hpp__ #ifndef __InsertionRegion_hpp__
#define __InsertionRegion_hpp__ #define __InsertionRegion_hpp__
#include "insertionRegion.hpp"
#include "dictionary.hpp" #include "dictionary.hpp"
#include "pointStructure.hpp" #include "pointStructure.hpp"
#include "insertionRegion.hpp" #include "insertion.hpp"
#include "collisionCheck.hpp"
#include "pStructSelector.hpp"
#include "fieldSelector.hpp"
namespace pFlow namespace pFlow
{ {

View File

@ -49,16 +49,29 @@ pFlow::collisionCheck::checkPoint(const realx3& p, const real d) const
if(!searchBox_.isInside(p)) return false; if(!searchBox_.isInside(p)) return false;
const auto ind = pointIndex(p); const auto ind = pointIndex(p);
const auto startInd = max(ind - 1 ,int32x3(0));
uint32 n = head_(ind.x(), ind.y(), ind.z()); const auto endInd = min( ind+1 ,nCells_-1);
while( n != -1)
for(int32 i=startInd.x(); i<=endInd.x(); i++)
{ {
if( (position_[n]-p).length() - 0.5*(diameters_[n]+d )<0.0 ) for(int32 j=startInd.y(); j<=endInd.y(); j++)
{ {
return false; for(int32 k=startInd.z(); k<=endInd.z(); k++)
{
uint32 n = head_(i, j, k);
while( n != -1)
{
if( ((position_[n]-p).length() - 0.5*(diameters_[n]+d )) <= 0.0 )
{
return false;
}
n = next_[n];
}
}
} }
n = next_[n];
} }
return true; return true;
} }

View File

@ -30,13 +30,42 @@ pFlow::insertion::insertion(particles& prtcl)
insertionFile__, insertionFile__,
"", "",
objectFile::READ_IF_PRESENT, objectFile::READ_IF_PRESENT,
objectFile::WRITE_NEVER objectFile::WRITE_ALWAYS
), ),
&prtcl.control().caseSetup() &prtcl.time()
), ),
particles_(prtcl) particles_(prtcl)
{ {
readInsertionDict(*this); // this means that insertion file exist in time folder
if( IOobject::implyRead() )
{
readFromFile_ = true;
} // look inside the caseSetup folder if it exist
else
{
// read dictionary from caseSetup folder
fileDictionary caseFile(
objectFile(
insertionFile__,
"",
objectFile::READ_IF_PRESENT,
objectFile::WRITE_NEVER),
&prtcl.control().caseSetup());
// check if read happened
if(caseFile.implyRead())
{
readFromFile_ = true;
// assign it to this dictionary
fileDictionary::dictionary::operator=(caseFile);
}
}
if( readFromFile_)
{
readInsertionDict();
}
} }
const pFlow::pointStructure& const pFlow::pointStructure&
@ -45,27 +74,18 @@ pFlow::insertion::pStruct() const
return particles_.pStruct(); return particles_.pStruct();
} }
bool
pFlow::insertion::read(iIstream& is, const IOPattern& iop)
{
if (fileDictionary::read(is, iop))
{
readFromFile_ = true;
return true;
}
else
{
return false;
}
}
bool bool
pFlow::insertion::readInsertionDict(const dictionary& dict) pFlow::insertion::readInsertionDict()
{ {
active_ = dict.getVal<Logical>("active"); active_ = getVal<Logical>("active");
if (active_) if (active_)
{ {
checkForCollision_ = getVal<Logical>("checkForCollision");
REPORT(1) << "Particle insertion mechanism is " << Yellow_Text("active") REPORT(1) << "Particle insertion mechanism is " << Yellow_Text("active")
<< " in the simulation." << END_REPORT; << " in the simulation." << END_REPORT;
} }
@ -78,26 +98,56 @@ pFlow::insertion::readInsertionDict(const dictionary& dict)
return true; return true;
} }
/* bool
bool pFlow::insertion::writeInsertionDict pFlow::insertion::writeInsertionDict(dictionary& dict) const
(
dictionary& dict
)const
{ {
if(!dict.add("active", active_) ) if (!dict.add("active", active_))
{ {
fatalErrorInFunction<< fatalErrorInFunction <<"Error in writing active to dictionary "
" error in writing active to dictionary <<dict.globalName()<<endl;
"<<dict.globalName()<<endl; return false; return false;
} }
if(!dict.add("checkForCollision", checkForCollision_) ) if (!dict.add("checkForCollision", checkForCollision_))
{ {
fatalErrorInFunction<< fatalErrorInFunction <<
" error in writing checkForCollision to "Error in writing checkForCollision to dictionary "<<
dictionary dict.globalName()<<endl;
"<<dict.globalName()<<endl; return false; return false;
} }
return true; return true;
}
bool pFlow::insertion::write(iOstream & os, const IOPattern & iop) const
{
dictionary newDict(fileDictionary::dictionary::name(), true);
if( iop.thisProcWriteData() )
{
if( !writeInsertionDict(newDict) ||
!newDict.write(os))
{
fatalErrorInFunction<<
" error in writing to dictionary "<< newDict.globalName()<<endl;
return false;
}
}
return true;
}
/*bool
pFlow::insertion::read(iIstream& is, const IOPattern& iop)
{
if (fileDictionary::read(is, iop))
{
readFromFile_ = true;
return true;
}
else
{
return false;
}
}*/ }*/

View File

@ -46,16 +46,22 @@ private:
/// to be inserted due to collision /// to be inserted due to collision
Logical increaseVelocity_ = "No"; Logical increaseVelocity_ = "No";
word diameterName_ = "diameter";
word velocityName_ = "velocity";
/// Ref to particles /// Ref to particles
particles& particles_; particles& particles_;
bool readFromFile_ = false; bool readFromFile_ = false;
/// Read from dictionary /// Read from dictionary
bool readInsertionDict(const dictionary& dict); bool readInsertionDict();
protected:
/// Write to dictionary /// Write to dictionary
// bool writeInsertionDict(dictionary& dict)const; virtual bool writeInsertionDict(dictionary& dict)const;
public: public:
@ -71,7 +77,7 @@ public:
/// is Insertion active /// is Insertion active
inline bool isActive() const inline bool isActive() const
{ {
return active_(); return readFromFile_ && active_();
} }
inline bool checkForCollision() const inline bool checkForCollision() const
@ -96,14 +102,24 @@ public:
return readFromFile_; return readFromFile_;
} }
const word& diameterName()const
{
return diameterName_;
}
const word& velocityName()const
{
return velocityName_;
}
/// read from stream /// read from stream
bool read(iIstream& is, const IOPattern& iop) override; //bool read(iIstream& is, const IOPattern& iop) override;
/*/// read from iIstream /*/// read from iIstream
virtual bool read(iIstream& is) = 0; virtual bool read(iIstream& is) = 0;*/
/// write to iOstream /// write to iOstream
virtual bool write(iOstream& os)const = 0;*/ bool write(iOstream& os, const IOPattern& iop)const override ;
}; };
} }

View File

@ -101,9 +101,15 @@ pFlow::insertionRegion::readInsertionRegion(const dictionary& dict)
bool bool
pFlow::insertionRegion::writeInsertionRegion(dictionary& dict) const pFlow::insertionRegion::writeInsertionRegion(dictionary& dict) const
{ {
if (!dict.add("type", type_))
if(!dict.add("rate", rate_))
return false; return false;
if(!tControl_.write(dict))
return false;
if (!dict.add("regionType", type_))
return false;
if (pRegion_) if (pRegion_)
{ {
auto& prDict = dict.subDictOrCreate(type_ + "Info"); auto& prDict = dict.subDictOrCreate(type_ + "Info");
@ -118,11 +124,11 @@ pFlow::insertionRegion::writeInsertionRegion(dictionary& dict) const
return false; return false;
} }
/*if(setFields_) if(setFieldDict_)
{ {
auto& sfDict = dict.subDictOrCreate("setFields"); if(!dict.addDict("setFields", setFieldDict_()))
setFields_().write(sfDict); return false;
}*/ }
return true; return true;
} }

View File

@ -159,6 +159,11 @@ public:
return type_; return type_;
} }
const auto& dict()const
{
return dict_;
}
const auto& Insertion() const const auto& Insertion() const
{ {
return insertion_; return insertion_;
@ -206,16 +211,13 @@ public:
return false; return false;
return readInsertionRegion(dict); return readInsertionRegion(dict);
} }*/
/// write to dictionary /// write to dictionary
bool write(dictionary& dict) const bool write(dictionary& dict) const
{ {
if (!timeFlowControl::write(dict))
return false;
return writeInsertionRegion(dict); return writeInsertionRegion(dict);
}*/ }
}; };
} // pFlow } // pFlow

View File

@ -58,7 +58,9 @@ private:
uint32Vector numberInserted_{"numberInserted"}; uint32Vector numberInserted_{"numberInserted"};
/// Current number of inserted /// Current number of inserted
uint32Vector current_{"currentInserted"}; uint32Vector current_{"currentInserted"};
uint32 lastPeaked_ = 0;
public: public:

View File

@ -61,7 +61,7 @@ pFlow::particleIdHandler::hearChanges(
auto idRange = getIdRange(numNew); auto idRange = getIdRange(numNew);
uint32Vector newId("newId",numNew,numNew,RESERVE()); uint32Vector newId("newId",numNew,numNew,RESERVE());
fillSequence(newId, idRange.first); fillSequence(newId, idRange.first);
output<< "id "<< idRange<<endl;
return this->field().insertSetElement(indices, newId); return this->field().insertSetElement(indices, newId);
} }
else else

View File

@ -26,8 +26,7 @@ bool pFlow::internalField<T, MemorySpace>::insert(const anyList& varList)
const auto& indices = varList.getObject<uint32IndexContainer>( const auto& indices = varList.getObject<uint32IndexContainer>(
eventName); eventName);
bool success = false; bool success = false;
output<<"insert for field "<< name()<<endl;
if(varList.contains(name())) if(varList.contains(name()))
{ {
// a single value is assigned // a single value is assigned

View File

@ -121,6 +121,9 @@ bool pFlow::dataEntry::writeDataEntry
} }
else else
{ {
if(tok != tokens.cbegin())os<<spaceToken();
os << *tok; os << *tok;
} }
lastPuncBegin = true; lastPuncBegin = true;
@ -141,6 +144,7 @@ bool pFlow::dataEntry::writeDataEntry
} }
else else
{ {
if(!lastPuncBegin&&applySpace) os<<spaceToken(); if(!lastPuncBegin&&applySpace) os<<spaceToken();
os << *tok; os << *tok;
lastPuncEnd = false; lastPuncEnd = false;

View File

@ -27,6 +27,8 @@ pFlow::baseTimeControl::baseTimeControl
const word& intervalPrefix, const word& intervalPrefix,
real defStartTime real defStartTime
) )
:
intervalPrefix_(intervalPrefix)
{ {
auto tControl = dict.getVal<word>("timeControl"); auto tControl = dict.getVal<word>("timeControl");
if(tControl == "timeStep") if(tControl == "timeStep")
@ -162,3 +164,32 @@ pFlow::baseTimeControl::iInterval() const
fatalExit; fatalExit;
return 0; return 0;
} }
bool
pFlow::baseTimeControl::write(dictionary& dict) const
{
if(isTimeStep_)
{
dict.add("timeControl", "timeStep");
}
else
{
dict.add("timeControl", "runTime");
}
word intervalWord = intervalPrefix_.size()==0? word("interval"): intervalPrefix_+"Interval";
if(!isTimeStep_)
{
dict.add(intervalWord,rRange_.stride());
dict.add("startTime",rRange_.begin());
dict.add("endTime", rRange_.end());
}
else
{
dict.add(intervalWord,iRange_.stride());
dict.add("startTime",iRange_.begin());
dict.add("endTime", iRange_.end());
}
return true;
}

View File

@ -1,20 +1,20 @@
/*------------------------------- phasicFlow --------------------------------- /*------------------------------- phasicFlow ---------------------------------
O C enter of O C enter of
O O E ngineering and O O E ngineering and
O O M ultiscale modeling of O O M ultiscale modeling of
OOOOOOO F luid flow OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence: Licence:
This file is part of phasicFlow code. It is a free software for simulating 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 granular and multiphase flows. You can redistribute it and/or modify it
the terms of GNU General Public License v3 or any other later versions. 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 phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
#ifndef __baseTimeControl_hpp__ #ifndef __baseTimeControl_hpp__
@ -23,50 +23,51 @@ Licence:
#include "dictionary.hpp" #include "dictionary.hpp"
#include "ranges.hpp" #include "ranges.hpp"
namespace pFlow namespace pFlow
{ {
class baseTimeControl class baseTimeControl
{ {
private: private:
bool isTimeStep_; bool isTimeStep_;
int32StridedRagne iRange_; int32StridedRagne iRange_;
realStridedRange rRange_; realStridedRange rRange_;
const word intervalPrefix_;
public: public:
baseTimeControl( baseTimeControl(
const dictionary& dict, const dictionary& dict,
const word& intervalPrefix = "", const word& intervalPrefix = "",
real defStartTime = 0.0); real defStartTime = 0.0
);
inline
bool isTimeStep()const inline bool isTimeStep() const
{ {
return isTimeStep_; return isTimeStep_;
} }
bool timeEvent(uint32 iter, real t, real dt)const; bool timeEvent(uint32 iter, real t, real dt) const;
bool isInRange(uint32 iter, real t, real dt)const; bool isInRange(uint32 iter, real t, real dt) const;
real startTime()const; real startTime() const;
real endTime()const; real endTime() const;
real rInterval()const; real rInterval() const;
int32 startIter()const; int32 startIter() const;
int32 endIter()const; int32 endIter() const;
int32 iInterval()const; int32 iInterval() const;
bool write(dictionary& dict) const;
}; };
} }

View File

@ -21,11 +21,13 @@ Licence:
#include "cylinder.hpp" #include "cylinder.hpp"
#include "zAxis.hpp" #include "zAxis.hpp"
#include "streams.hpp"
FUNCTION_H FUNCTION_H
bool pFlow::cylinder::calculateParams() bool pFlow::cylinder::calculateParams()
{ {
WARNING<<"Use of cylinder requires modifications to zAxis"<<END_WARNING;
auto p1p2 = p2_ - p1_; auto p1p2 = p2_ - p1_;
if( p1p2.length() > smallValue ) if( p1p2.length() > smallValue )

View File

@ -33,7 +33,7 @@ Vector<T> selectedFieldVals(const pStructSelector& selector, const word& name)
{ {
fatalErrorInFunction<< fatalErrorInFunction<<
"Type of field "<< name << " in time repository does not match with"<< "Type of field "<< name << " in time repository does not match with"<<
FieldType::TYEPANME()<<endl; FieldType::TYPENAME()<<endl;
fatalExit; fatalExit;
} }

View File

@ -32,6 +32,16 @@ pFlow::pStructSelector::pStructSelector
pStruct_(pStruct) pStruct_(pStruct)
{} {}
pFlow::pStructSelector::pStructSelector(
const word& ,
const pointStructure& pStruct,
const dictionary&
)
:
pStruct_(pStruct)
{
}
const pFlow::pointStructure& pFlow::pStructSelector::pStruct()const const pFlow::pointStructure& pFlow::pStructSelector::pStruct()const
{ {
return pStruct_; return pStruct_;
@ -63,7 +73,6 @@ pFlow::pStructSelector::create(
const dictionary& dict const dictionary& dict
) )
{ {
word selectorMethod = angleBracketsNames("selector", dict.getVal<word>("selector")); word selectorMethod = angleBracketsNames("selector", dict.getVal<word>("selector"));
if( dictionaryvCtorSelector_.search(selectorMethod) ) if( dictionaryvCtorSelector_.search(selectorMethod) )
@ -74,7 +83,7 @@ pFlow::pStructSelector::create(
{ {
printKeys printKeys
( (
fatalError << "Ctor Selector "<< selectorMethod << " dose not exist. \n" fatalError << "Ctor Selector "<< selectorMethod << " does not exist. \n"
<<"Avaiable ones are: \n\n" <<"Avaiable ones are: \n\n"
, ,
dictionaryvCtorSelector_ dictionaryvCtorSelector_
@ -83,3 +92,31 @@ pFlow::pStructSelector::create(
} }
return nullptr; return nullptr;
} }
pFlow::uniquePtr<pFlow::pStructSelector>
pFlow::pStructSelector::create(
const word& type,
const pointStructure& pStruct,
const dictionary& dict
)
{
word selectorMethod = angleBracketsNames("selector", type);
if( wordvCtorSelector_.search(selectorMethod) )
{
return wordvCtorSelector_[selectorMethod] (type, pStruct, dict);
}
else
{
printKeys
(
fatalError << "Ctor Selector "<< selectorMethod << " does not exist. \n"
<<"Avaiable ones are: \n\n"
,
wordvCtorSelector_
);
fatalExit;
}
return nullptr;
}

View File

@ -44,9 +44,16 @@ public:
// - type info // - type info
TypeInfo("pStructSelector"); TypeInfo("pStructSelector");
/// the dictionary contains the selector keyword and another dictionary which is
/// used for creating selector
pStructSelector(const pointStructure& pStruct, const dictionary& UNUSED(dict)); pStructSelector(const pointStructure& pStruct, const dictionary& UNUSED(dict));
/// construct using selector type and a dictionary that contains info of selector
pStructSelector(
const word& type,
const pointStructure& pStruct,
const dictionary& UNUSED(dict));
create_vCtor create_vCtor
( (
pStructSelector, pStructSelector,
@ -55,6 +62,18 @@ public:
(pStruct, dict) (pStruct, dict)
); );
create_vCtor
(
pStructSelector,
word,
(
const word& type,
const pointStructure& pStruct,
const dictionary& dict
),
(type, pStruct, dict)
);
virtual ~pStructSelector() = default; virtual ~pStructSelector() = default;
//// - Methods //// - Methods
@ -71,6 +90,11 @@ public:
static static
uniquePtr<pStructSelector> create(const pointStructure& pStruct, const dictionary& dict); uniquePtr<pStructSelector> create(const pointStructure& pStruct, const dictionary& dict);
static
uniquePtr<pStructSelector> create(
const word& type,
const pointStructure& pStruct,
const dictionary& dict);
}; };

View File

@ -1,20 +1,18 @@
template<typename GeomType> template<typename GeomType>
bool bool
pFlow::selectorGeometric<GeomType>::selectPoints() pFlow::selectorGeometric<GeomType>::selectPoints()
{ {
selectedPoints_.clear(); selectedPoints_.clear();
auto maskH = pStruct().activePointsMaskHost(); auto maskH = pStruct().activePointsMaskHost();
const auto aRange = maskH.activeRange(); const auto aRange = maskH.activeRange();
auto pPos = pStruct().pointPositionHost(); auto pPos = pStruct().pointPositionHost();
for(uint32 i=aRange.start(); i<aRange.end();i++) for (uint32 i = aRange.start(); i < aRange.end(); i++)
{ {
if(maskH.isActive(i)&& pRegion_.isInside( pPos[i] )) if (maskH.isActive(i) && pRegion_.isInside(pPos[i]))
{ {
selectedPoints_.push_back(i); selectedPoints_.push_back(i);
} }
@ -32,10 +30,24 @@ pFlow::selectorGeometric<GeomType>::selectorGeometric(
type_(dict.getVal<word>("selector")), type_(dict.getVal<word>("selector")),
pRegion_(type_, dict.subDict(type_ + "Info")) pRegion_(type_, dict.subDict(type_ + "Info"))
{ {
if (!selectPoints())
if(!selectPoints())
{ {
fatalExit; fatalExit;
} }
} }
template<typename GeomType>
pFlow::selectorGeometric<GeomType>::selectorGeometric(
const word& type,
const pointStructure& pStruct,
const dictionary& dict
)
: pStructSelector(type, pStruct, dict),
type_(type),
pRegion_(type_, dict)
{
if (!selectPoints())
{
fatalExit;
}
}

View File

@ -50,6 +50,11 @@ public:
selectorGeometric(const pointStructure& pStruct, const dictionary& dict); selectorGeometric(const pointStructure& pStruct, const dictionary& dict);
selectorGeometric(
const word& type,
const pointStructure& pStruct,
const dictionary& dict);
add_vCtor add_vCtor
( (
pStructSelector, pStructSelector,
@ -57,6 +62,13 @@ public:
dictionary dictionary
); );
add_vCtor
(
pStructSelector,
selectorGeometric,
word
);
~selectorGeometric() override = default; ~selectorGeometric() override = default;
const uint32Vector& selectedPoints()const override const uint32Vector& selectedPoints()const override

View File

@ -2,56 +2,54 @@
O C enter of O C enter of
O O E ngineering and O O E ngineering and
O O M ultiscale modeling of O O M ultiscale modeling of
OOOOOOO F luid flow OOOOOOO F luid flow
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Copyright (C): www.cemf.ir Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Licence: Licence:
This file is part of phasicFlow code. It is a free software for simulating 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 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. 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 phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
#include "selectorRandomPoints.hpp" #include "selectorRandomPoints.hpp"
#include "Set.hpp"
#include "dictionary.hpp" #include "dictionary.hpp"
#include "uniformRandomUint32.hpp" #include "uniformRandomUint32.hpp"
#include "Set.hpp"
bool
bool pFlow::selectorRandomPoints::selectAllPointsInRange() pFlow::selectorRandomPoints::selectAllPointsInRange()
{ {
// to reduct allocations // to reduct allocations
uint32 maxNum = number_+1; uint32 maxNum = number_ + 1;
selectedPoints_.reserve (maxNum); selectedPoints_.reserve(maxNum);
selectedPoints_.clear(); selectedPoints_.clear();
uniformRandomUint32 intRand (begin_, end_);
uniformRandomUint32 intRand(begin_, end_);
uint32 n = 0; uint32 n = 0;
uint32 iter = 0; uint32 iter = 0;
bool finished = false; bool finished = false;
Set<uint32> selctedIndices; Set<uint32> selctedIndices;
while( iter < number_*100) while (iter < number_ * 100)
{ {
uint32 newInd = intRand.randomNumber(); uint32 newInd = intRand.randomNumber();
if( auto [it, inserted] = selctedIndices.insert(newInd); inserted ) if (auto [it, inserted] = selctedIndices.insert(newInd); inserted)
{ {
n++; n++;
if(n == number_) if (n == number_)
{ {
finished = true; finished = true;
break; break;
@ -60,62 +58,61 @@ bool pFlow::selectorRandomPoints::selectAllPointsInRange()
iter++; iter++;
} }
if (finished)
if(finished)
{ {
for(auto& ind:selctedIndices) for (auto& ind : selctedIndices)
{ {
selectedPoints_.push_back(ind); selectedPoints_.push_back(ind);
} }
return true; return true;
}else
{
fatalErrorInFunction<< "Could not find random indices in the range."<<endl;
return false;
} }
else
{
fatalErrorInFunction << "Could not find random indices in the range."
<< endl;
return false;
}
} }
pFlow::selectorRandomPoints::selectorRandomPoints pFlow::selectorRandomPoints::selectorRandomPoints(
( const pointStructure& pStruct,
const pointStructure& pStruct, const dictionary& dict
const dictionary& dict
) )
: : selectorRandomPoints(
pStructSelector "randomPoints",
( pStruct,
pStruct, dict dict.subDict("randomPointsInfo")
), )
begin_
(
dict.subDict("randomPointsInfo").getVal<uint32>("begin")
),
end_
(
dict.subDict("randomPointsInfo").getValOrSet("end", pStruct.size())
),
number_
(
dict.subDict("randomPointsInfo").getValOrSet("number", 1)
)
{ {
begin_ = max(begin_,1u); }
end_ = min(end_, static_cast<uint32>(pStruct.size()));
number_ = max(number_,0u); pFlow::selectorRandomPoints::selectorRandomPoints(
if(end_-begin_ < number_) const word& type,
const pointStructure& pStruct,
const dictionary& dict
)
: pStructSelector(type, pStruct, dict),
begin_(dict.getVal<uint32>("begin")),
end_(dict.getValOrSet("end", pStruct.size())),
number_(dict.getValOrSet("number", 1))
{
begin_ = max(begin_, 1u);
end_ = min(end_, static_cast<uint32>(pStruct.size()));
number_ = max(number_, 0u);
if (end_ - begin_ < number_)
{ {
warningInFunction
<< "In dictionary " << dict.globalName()
<< " number is greater than the interval defined by begine and end ["
<< begin_ << " " << end_ << "), resetting it to " << end_ - begin_
<< endl;
warningInFunction<< "In dictionary " << dict.globalName()<< number_ = end_ - begin_;
" number is greater than the interval defined by begine and end ["<<
begin_<<" "<<end_<<"), resetting it to "<<end_-begin_<<endl;
number_ = end_-begin_;
} }
if(!selectAllPointsInRange()) if (!selectAllPointsInRange())
{ {
fatalExit; fatalExit;
} }

View File

@ -58,6 +58,11 @@ public:
selectorRandomPoints(const pointStructure& pStruct, const dictionary& dict); selectorRandomPoints(const pointStructure& pStruct, const dictionary& dict);
selectorRandomPoints(
const word& type,
const pointStructure& pStruct,
const dictionary& UNUSED(dict));
add_vCtor add_vCtor
( (
pStructSelector, pStructSelector,
@ -65,6 +70,12 @@ public:
dictionary dictionary
); );
add_vCtor
(
pStructSelector,
selectorRandomPoints,
word
);
~selectorRandomPoints() final = default; ~selectorRandomPoints() final = default;
//// - Methods //// - Methods

View File

@ -2,67 +2,66 @@
O C enter of O C enter of
O O E ngineering and O O E ngineering and
O O M ultiscale modeling of O O M ultiscale modeling of
OOOOOOO F luid flow OOOOOOO F luid flow
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Copyright (C): www.cemf.ir Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Licence: Licence:
This file is part of phasicFlow code. It is a free software for simulating 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 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. 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 phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
#include "selectorStridedRange.hpp" #include "selectorStridedRange.hpp"
#include "dictionary.hpp" #include "dictionary.hpp"
void pFlow::selectorStridedRange::selectAllPointsInRange() void
pFlow::selectorStridedRange::selectAllPointsInRange()
{ {
// to reduct allocations // to reduct allocations
uint32 maxNum = (end_ - begin_)/stride_+2; uint32 maxNum = (end_ - begin_) / stride_ + 2;
selectedPoints_.reserve (maxNum); selectedPoints_.reserve(maxNum);
selectedPoints_.clear(); selectedPoints_.clear();
for(uint32 i = begin_; i<end_; i+= stride_) for (uint32 i = begin_; i < end_; i += stride_)
{ {
selectedPoints_.push_back(i); selectedPoints_.push_back(i);
} }
} }
pFlow::selectorStridedRange::selectorStridedRange pFlow::selectorStridedRange::selectorStridedRange(
( const pointStructure& pStruct,
const pointStructure& pStruct, const dictionary& dict
const dictionary& dict
) )
: : selectorStridedRange(
pStructSelector "stridedRange",
( pStruct,
pStruct, dict dict.subDict("stridedRangeInfo")
), )
begin_
(
dict.subDict("stridedRangeInfo").getVal<uint32>("begin")
),
end_
(
dict.subDict("stridedRangeInfo").getValOrSet<uint32>("end", pStruct.size())
),
stride_
(
dict.subDict("stridedRangeInfo").getValOrSet<uint32>("stride", 1u)
)
{ {
begin_ = max(begin_,1u); }
end_ = min(end_, static_cast<uint32>(pStruct.size()));
stride_ = max(stride_,1u); pFlow::selectorStridedRange::selectorStridedRange(
const word& type,
const pointStructure& pStruct,
const dictionary& dict
)
: pStructSelector(type, pStruct, dict),
begin_(dict.getVal<uint32>("begin")),
end_(dict.getValOrSet<uint32>("end", pStruct.size())),
stride_(dict.getValOrSet<uint32>("stride", 1u))
{
begin_ = max(begin_, 1u);
end_ = min(end_, static_cast<uint32>(pStruct.size()));
stride_ = max(stride_, 1u);
selectAllPointsInRange(); selectAllPointsInRange();
} }

View File

@ -58,6 +58,11 @@ public:
selectorStridedRange(const pointStructure& pStruct, const dictionary& dict); selectorStridedRange(const pointStructure& pStruct, const dictionary& dict);
selectorStridedRange(
const word& type,
const pointStructure& pStruct,
const dictionary& dict);
add_vCtor add_vCtor
( (
pStructSelector, pStructSelector,
@ -65,6 +70,13 @@ public:
dictionary dictionary
); );
add_vCtor
(
pStructSelector,
selectorStridedRange,
word
);
~selectorStridedRange() final = default; ~selectorStridedRange() final = default;
//// - Methods //// - Methods

View File

@ -50,17 +50,17 @@ struct triple
T y_; T y_;
T z_; T z_;
/// Type info for triple
TripleTypeInfoNV(T); TripleTypeInfoNV(T);
//// Constructors //// Constructors
/// Initilize to zero /// Initilize to zero
INLINE_FUNCTION_HD INLINE_FUNCTION_HD
triple() triple() = default;
: x_(),
y_(), INLINE_FUNCTION_HD
z_() ~triple() = default;
{
}
/// Construct from x, y, z /// Construct from x, y, z
INLINE_FUNCTION_HD INLINE_FUNCTION_HD