diff --git a/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp b/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp index 25064346..ee414f3b 100644 --- a/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp +++ b/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp @@ -34,7 +34,7 @@ pFlow::particleWallContactSearchs::particleWallContactSearchs domainBox_(domain), updateInterval_ ( - dict.getValOrSet("updateInterval", 1) + max(dict.getValOrSet("updateInterval", 1),1u) ) { diff --git a/src/Particles/Insertion/Insertion/Insertion.cpp b/src/Particles/Insertion/Insertion/Insertion.cpp index 5a8111f9..a0e2cc77 100644 --- a/src/Particles/Insertion/Insertion/Insertion.cpp +++ b/src/Particles/Insertion/Insertion/Insertion.cpp @@ -18,31 +18,7 @@ Licence: -----------------------------------------------------------------------------*/ -/*template -bool pFlow::Insertion::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)< bool pFlow::Insertion::writeInsertionDict @@ -50,7 +26,8 @@ bool pFlow::Insertion::writeInsertionDict dictionary& dict )const { - if( !insertion::writeInsertionDict(dict) ) return false; + + if(!insertion::writeInsertionDict(dict))return false; if( !this->isActive() ) return true; @@ -60,16 +37,18 @@ bool pFlow::Insertion::writeInsertionDict if( !regions_[i].write(rgnDict) ) { + fatalErrorInFunction<< + "Error in writing to dictionary "< bool -pFlow::Insertion::setInsertionRegions() +pFlow::Insertion::readInsertionDict() { regions_.clear(); @@ -102,7 +81,7 @@ pFlow::Insertion::Insertion( insertion(prtcl), shapes_(shapes) { - if(!setInsertionRegions()) + if(!readInsertionDict()) { fatalErrorInFunction; fatalExit; diff --git a/src/Particles/Insertion/Insertion/Insertion.hpp b/src/Particles/Insertion/Insertion/Insertion.hpp index 1e55bdb2..ddeb9c56 100644 --- a/src/Particles/Insertion/Insertion/Insertion.hpp +++ b/src/Particles/Insertion/Insertion/Insertion.hpp @@ -62,12 +62,11 @@ private: // - insertion regions ListPtr> regions_; + bool readInsertionDict(); - bool setInsertionRegions(); +protected: - // bool readInsertionDict(const dictionary& dict); - - // bool writeInsertionDict(dictionary& dict)const; + bool writeInsertionDict(dictionary& dict)const override; public: diff --git a/src/Particles/Insertion/InsertionRegion/InsertionRegion.cpp b/src/Particles/Insertion/InsertionRegion/InsertionRegion.cpp index 18f7c23e..4434f64b 100644 --- a/src/Particles/Insertion/InsertionRegion/InsertionRegion.cpp +++ b/src/Particles/Insertion/InsertionRegion/InsertionRegion.cpp @@ -55,8 +55,8 @@ bool pFlow::InsertionRegion::insertParticles uint32 iter, real t, real dt, - wordVector& names, - realx3Vector& pos, + wordVector& names, + realx3Vector& positions, bool& insertionOccured ) { @@ -65,65 +65,185 @@ bool pFlow::InsertionRegion::insertParticles if(!insertionTime(iter, t, dt)) return true; uint32 newNum = numberToBeInserted(iter, t, dt); - if(newNum == 0) return true; + // get the internal box auto internalBox = pStruct().internalDomainBox(); - if( !(internalBox.minPoint() < internalBox.maxPoint())) { WARNING<<"Minimum point of internal point is not lower than "<< "the maximum point \n"<< "minimum point: "<< internalBox.minPoint()<< "\nmaximum point:"< + ( + selector(), + Insertion().diameterName() + ); + } + + auto collCheck = collisionCheck( + {minP, maxP}, + maxDiam, + allPositions, + allDiameters); + + uint32 numInserted = 0; + + 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(pos, diams, p, d) ) + if( collCheck.checkPoint( p, d) ) { names.push_back(name); - pos.push_back(p); - diams.push_back(d); - n++; - - if( n == newNum ) - { - addToNumInserted(newNum); - insertionOccured = true; - return true; - } - + 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); } - + } - - addToNumInserted(n); + insertionOccured = true; - return false; -} \ No newline at end of file + 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(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); + } + + } + }*/ \ No newline at end of file diff --git a/src/Particles/Insertion/InsertionRegion/InsertionRegion.hpp b/src/Particles/Insertion/InsertionRegion/InsertionRegion.hpp index a1bc383c..526dde6b 100644 --- a/src/Particles/Insertion/InsertionRegion/InsertionRegion.hpp +++ b/src/Particles/Insertion/InsertionRegion/InsertionRegion.hpp @@ -21,9 +21,15 @@ Licence: #ifndef __InsertionRegion_hpp__ #define __InsertionRegion_hpp__ +#include "insertionRegion.hpp" #include "dictionary.hpp" #include "pointStructure.hpp" -#include "insertionRegion.hpp" +#include "insertion.hpp" +#include "collisionCheck.hpp" +#include "pStructSelector.hpp" +#include "fieldSelector.hpp" + + namespace pFlow { diff --git a/src/Particles/Insertion/collisionCheck/collisionCheck.cpp b/src/Particles/Insertion/collisionCheck/collisionCheck.cpp index b5abe370..5cb7b470 100644 --- a/src/Particles/Insertion/collisionCheck/collisionCheck.cpp +++ b/src/Particles/Insertion/collisionCheck/collisionCheck.cpp @@ -49,16 +49,29 @@ pFlow::collisionCheck::checkPoint(const realx3& p, const real d) const if(!searchBox_.isInside(p)) return false; const auto ind = pointIndex(p); - - uint32 n = head_(ind.x(), ind.y(), ind.z()); - while( n != -1) + const auto startInd = max(ind - 1 ,int32x3(0)); + const auto endInd = min( ind+1 ,nCells_-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; } diff --git a/src/Particles/Insertion/insertion/insertion.cpp b/src/Particles/Insertion/insertion/insertion.cpp index 09f29f98..d8d0881d 100644 --- a/src/Particles/Insertion/insertion/insertion.cpp +++ b/src/Particles/Insertion/insertion/insertion.cpp @@ -30,13 +30,42 @@ pFlow::insertion::insertion(particles& prtcl) insertionFile__, "", objectFile::READ_IF_PRESENT, - objectFile::WRITE_NEVER + objectFile::WRITE_ALWAYS ), - &prtcl.control().caseSetup() + &prtcl.time() ), 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& @@ -45,27 +74,18 @@ pFlow::insertion::pStruct() const 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 -pFlow::insertion::readInsertionDict(const dictionary& dict) +pFlow::insertion::readInsertionDict() { - active_ = dict.getVal("active"); + active_ = getVal("active"); if (active_) { + checkForCollision_ = getVal("checkForCollision"); + REPORT(1) << "Particle insertion mechanism is " << Yellow_Text("active") << " in the simulation." << END_REPORT; } @@ -78,26 +98,56 @@ pFlow::insertion::readInsertionDict(const dictionary& dict) return true; } -/* -bool pFlow::insertion::writeInsertionDict -( - dictionary& dict -)const +bool +pFlow::insertion::writeInsertionDict(dictionary& dict) const { - if(!dict.add("active", active_) ) - { - fatalErrorInFunction<< - " error in writing active to dictionary -"<field().insertSetElement(indices, newId); } else diff --git a/src/phasicFlow/containers/pointField/internalField/internalField.cpp b/src/phasicFlow/containers/pointField/internalField/internalField.cpp index c1c69bd5..c59faf3b 100644 --- a/src/phasicFlow/containers/pointField/internalField/internalField.cpp +++ b/src/phasicFlow/containers/pointField/internalField/internalField.cpp @@ -26,8 +26,7 @@ bool pFlow::internalField::insert(const anyList& varList) const auto& indices = varList.getObject( eventName); bool success = false; - output<<"insert for field "<< name()<("timeControl"); if(tControl == "timeStep") @@ -162,3 +164,32 @@ pFlow::baseTimeControl::iInterval() const fatalExit; 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; +} \ No newline at end of file diff --git a/src/phasicFlow/repository/Time/baseTimeControl.hpp b/src/phasicFlow/repository/Time/baseTimeControl.hpp index 3cde11ab..192973fc 100644 --- a/src/phasicFlow/repository/Time/baseTimeControl.hpp +++ b/src/phasicFlow/repository/Time/baseTimeControl.hpp @@ -1,20 +1,20 @@ /*------------------------------- phasicFlow --------------------------------- - O C enter of - O O E ngineering and - O O M ultiscale modeling of - OOOOOOO F luid flow + 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 ------------------------------------------------------------------------------ - 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. + 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 __baseTimeControl_hpp__ @@ -23,50 +23,51 @@ Licence: #include "dictionary.hpp" #include "ranges.hpp" - namespace pFlow { class baseTimeControl { private: - - bool isTimeStep_; + + bool isTimeStep_; int32StridedRagne iRange_; realStridedRange rRange_; - + + const word intervalPrefix_; public: baseTimeControl( - const dictionary& dict, - const word& intervalPrefix = "", - real defStartTime = 0.0); - - inline - bool isTimeStep()const + const dictionary& dict, + const word& intervalPrefix = "", + real defStartTime = 0.0 + ); + + inline bool isTimeStep() const { 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; }; } diff --git a/src/phasicFlow/structuredData/cylinder/cylinder.cpp b/src/phasicFlow/structuredData/cylinder/cylinder.cpp index e034fc44..b8ce3c68 100644 --- a/src/phasicFlow/structuredData/cylinder/cylinder.cpp +++ b/src/phasicFlow/structuredData/cylinder/cylinder.cpp @@ -21,11 +21,13 @@ Licence: #include "cylinder.hpp" #include "zAxis.hpp" +#include "streams.hpp" FUNCTION_H bool pFlow::cylinder::calculateParams() { + WARNING<<"Use of cylinder requires modifications to zAxis"< smallValue ) diff --git a/src/phasicFlow/types/triple/triple.hpp b/src/phasicFlow/types/triple/triple.hpp index 390c04f4..8b6735af 100644 --- a/src/phasicFlow/types/triple/triple.hpp +++ b/src/phasicFlow/types/triple/triple.hpp @@ -50,17 +50,17 @@ struct triple T y_; T z_; + /// Type info for triple TripleTypeInfoNV(T); + //// Constructors /// Initilize to zero INLINE_FUNCTION_HD - triple() - : x_(), - y_(), - z_() - { - } + triple() = default; + + INLINE_FUNCTION_HD + ~triple() = default; /// Construct from x, y, z INLINE_FUNCTION_HD