1
0
mirror of https://github.com/PhasicFlow/phasicFlow.git synced 2025-06-22 16:28:30 +00:00

first modifications for coupling

This commit is contained in:
hamidrezanorouzi
2022-12-03 12:12:56 +03:30
parent 14ef70bfdf
commit 2b514d0302
31 changed files with 701 additions and 47 deletions

11
DEMSystems/CMakeLists.txt Normal file

@ -0,0 +1,11 @@
set(SourceFiles
sphereDEMSystem/sphereDEMSystem.C
)
set(link_libs Kokkos::kokkos phasicFlow Particles Geometry Property Interaction Interaction)
pFlow_add_library_install(DEMSystems SourceFiles link_libs)

@ -0,0 +1,27 @@
/*------------------------------- 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 "sphereDEMSystem.H"
pFlow::sphereDEMSystem::sphereDEMSystem()
{
}

@ -0,0 +1,86 @@
/*------------------------------- 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 __sphereDEMSystem_H__
#define __sphereDEMSystem_H__
#include "systemControl.H"
#include "property.H"
#include "uniquePtr.H"
#include "geometry.H"
#include "sphereParticles.H"
#include "interaction.H"
#include "Insertions.H"
namespace pFlow
{
class sphereDEMSystem
{
protected:
systemControl Control_;
uniquePtr<property> property_ = nullptr;
uniquePtr<geometry> geometry_ = nullptr;
uniquePtr<sphereParticles> particles_ = nullptr;
uniquePtr<interaction> interaction_ = nullptr;
uniquePtr<sphereInsertion> insertion_ = nullptr;
auto& Control()
{
return Control_;
}
auto& Property()
{
return property_();
}
auto& Geometry()
{
return geometry_();
}
auto& Particles()
{
return particles_();
}
auto& Interaction()
{
return interaction_();
}
public:
sphereDEMSystem();
};
} // pFlow
#endif

@ -2,6 +2,6 @@
set(source_files
iterateGeometry.C
)
set(link_lib phasicFlow Geometry MotionModel Kokkos::kokkos)
set(link_lib phasicFlow Geometry MotionModel Kokkos::kokkos Utilities)
pFlow_make_executable_install(iterateGeometry source_files link_lib)

@ -20,12 +20,28 @@ Licence:
#include "systemControl.H"
#include "geometryMotion.H"
#include "commandLine.H"
#include "readControlDict.H"
using pFlow::commandLine;
int main( int argc, char* argv[] )
{
commandLine cmds(
"iterateGeometry",
"Performs simulation without particles, only geometry is solved");
bool isCoupling = false;
cmds.add_flag(
"-c,--coupling",
isCoupling,
"Is this a fluid-particle coupling simulation?");
if(!cmds.parse(argc, argv)) return 0;
// this should be palced in each main
#include "initialize_Control.H"

@ -2,6 +2,6 @@
set(source_files
sphereGranFlow.C
)
set(link_lib Kokkos::kokkos phasicFlow Particles Geometry Property Interaction Interaction)
set(link_lib Kokkos::kokkos phasicFlow Particles Geometry Property Interaction Interaction Utilities)
pFlow_make_executable_install(sphereGranFlow source_files link_lib)

@ -26,6 +26,7 @@ Licence:
#include "contactSearch.H"
#include "sphereInteraction.H"
#include "commandLine.H"
#include "readControlDict.H"
using pFlow::output;
using pFlow::endl;
@ -47,6 +48,8 @@ commandLine cmds(
"DEM solver for non-cohesive spherical particles with particle insertion "
"mechanism and moving geometry");
bool isCoupling = false;
if(!cmds.parse(argc, argv)) return 0;
// this should be palced in each main

@ -47,6 +47,37 @@ pFlow::Time::Time
}
pFlow::Time::Time(
repository* owner,
dictionary& setiingsDict,
real startTime,
real endTime,
real saveInterval,
word startTimeName)
:
repository("Time", "", owner),
timeControl(
setiingsDict,
startTime,
endTime,
saveInterval,
startTimeName),
geometry_
(
geometryRepository_,
geometryFolder__,
this
),
integration_
(
integrationRepository__,
integrationFolder__,
this
)
{
}
bool pFlow::Time::write
(
bool verbose

@ -55,6 +55,14 @@ public:
// Constructor with owner and settings dict
Time( repository* owner, const dictionary& setiingsDict);
Time(
repository* owner,
dictionary& setiingsDict,
real startTime,
real endTime,
real saveInterval,
word startTimeName);
//// - Methods
virtual fileSystem localPath()const

@ -63,13 +63,47 @@ pFlow::timeControl::timeControl
)
{
checkForOutputToFile();
}
pFlow::timeControl::timeControl(
dictionary& dict,
real startTime,
real endTime,
real saveInterval,
word startTimeName)
:
dt_
(
dict.getVal<real>("dt")
),
startTime_(startTime),
endTime_(endTime),
currentTime_(startTime_),
saveInterval_(saveInterval),
lastSaved_(startTime_),
currentIter_(0),
timePrecision_
(
dict.getValOrSet("timePrecision", 4)
),
managedExternaly_(true),
timeName_(startTimeName),
timersReportInterval_
(
startTime_,
dict.getValOrSet("timersReportInterval", 0.04)
)
{
checkForOutputToFile();
}
void pFlow::timeControl::checkForOutputToFile()
{
if(managedExternaly_) return;
bool save = false;
if ( abs(currentTime_ - lastSaved_ - saveInterval_) < 0.5 * dt_ )
@ -92,4 +126,14 @@ bool pFlow::timeControl::timersReportTime()const
return timersReportInterval_.isMember(currentTime_, dt_);
}
void pFlow::timeControl::setSaveTimeFolder(
bool saveToFile,
const word& timeName)
{
if(managedExternaly_)
{
outputToFile_ = saveToFile;
timeName_ = timeName;
}
}

@ -65,6 +65,10 @@ protected:
// - time precision for output time folders
int32 timePrecision_;
bool managedExternaly_ = false;
word timeName_ = "wrongSettings";
realStridedRange timersReportInterval_;
int32StridedRagne screenReportInterval_ ={0,100};
@ -78,6 +82,13 @@ protected:
public:
timeControl(const dictionary& dict);
timeControl(
dictionary& dict,
real startTime,
real endTime,
real saveInterval,
word startTimeName);
virtual ~timeControl()
{}
@ -103,9 +114,19 @@ public:
return currentTime_;
}
word currentTimeWord() const
word currentTimeWord(bool forSave = true)const
{
return real2FixedStripZeros( currentTime(), timePrecision());;
if(forSave)
{
if(!managedExternaly_)
return real2FixedStripZeros( currentTime(), timePrecision());
else
return timeName_;
}
else
{
return real2FixedStripZeros( currentTime(), timePrecision());
}
}
int32 currentIter()const
@ -145,6 +166,9 @@ public:
return true;
}
void setSaveTimeFolder(
bool saveToFile,
const word& timeName = "wrongTimeFolder");
int32 timePrecision()const
{

@ -154,6 +154,75 @@ pFlow::systemControl::systemControl
writeToFileTimer_("Write to file", &timers_)
{}
pFlow::systemControl::systemControl(
const real startTime,
const real endTime,
const real saveInterval,
const word startTimeName,
const fileSystem path)
:
repository
(
"systemControl",
path, // local path
nullptr // no owner
),
runName_
(
getRunName(path)
),
topLevelFolder_
(
getTopFolder(path)
),
settings_
(
settingsRepository__,
settingsFolder__,
this
),
caseSetup_
(
caseSetupRepository__,
caseSetupFolder__,
this
),
settingsDict_
(
settings().emplaceObject<dictionary>
(
objectFile
(
settingsFile__,
"",
objectFile::READ_ALWAYS,
objectFile::WRITE_NEVER
),
settingsFile__,
true
)
),
Time_
(
this,
settingsDict_
),
externalTimeControl_(true),
g_(
settingsDict_.getVal<realx3>("g")
),
domain_(
settingsDict_.subDict("domain")
),
timers_(runName_),
timersReport_
(
settingsDict_.getValOrSet("timersReport", Logical("Yes"))
),
writeToFileTimer_("Write to file", &timers_)
{}
bool pFlow::systemControl::operator ++(int)
{
@ -188,27 +257,4 @@ bool pFlow::systemControl::operator ++(int)
}
pFlow::Map<pFlow::real, pFlow::fileSystem>
pFlow::systemControl::getTimeFolders()const
{
Map<real, fileSystem> tFolders;
auto subDirs = subDirectories(this->path());
for(auto& subD: subDirs)
{
auto timeName = tailName(subD.wordPath(), '/');
real TIME;
if( auto success = readReal(timeName, TIME); success)
{
if(!tFolders.insertIf(TIME, subD))
{
fatalErrorInFunction<<
" duplicate time folder! time = " << TIME <<endl;
fatalExit;
}
}
}
return tFolders;
}

@ -61,6 +61,10 @@ protected:
// - time repository
Time Time_;
// - if time control is managed externaly
bool externalTimeControl_ = false;
// - acceleration
realx3 g_;
@ -78,10 +82,18 @@ protected:
static word getTopFolder(const fileSystem& path);
public:
systemControl( const fileSystem path = CWD() );
systemControl(const fileSystem path = CWD());
systemControl(
const real startTime,
const real endTime,
const real saveInterval,
const word startTimeName,
const fileSystem path = CWD() );
const repository& settings() const{
return settings_;
}
@ -159,7 +171,12 @@ public:
bool operator ++(int);
Map<real, fileSystem> getTimeFolders()const;
void setSaveTimeFolder(
bool saveToFile,
const word& timeName = "wrongTimeFolder")
{
Time_.setSaveTimeFolder(saveToFile, timeName);
}
};

@ -27,13 +27,13 @@ Licence:
namespace pFlow
{
Map<real, fileSystem> getTimeFolders(const fileSystem& path);
class timeFolder
{
using timeList = Map<real, fileSystem>;
protected:
const systemControl& control_;
timeList folders_;
timeList::iterator currentFolder_;
@ -41,12 +41,19 @@ protected:
public:
timeFolder(const systemControl& control ):
control_(control),
folders_(control.getTimeFolders()),
currentFolder_(folders_.begin())
timeFolder(const systemControl& control )
:
timeFolder(control.path())
{}
timeFolder(const fileSystem& path)
:
folders_(getTimeFolders(path)),
currentFolder_(folders_.begin())
{
}
real time()const
{
return currentFolder_->first;
@ -108,6 +115,32 @@ public:
}
};
inline
Map<real, fileSystem> getTimeFolders(const fileSystem& path)
{
Map<real, fileSystem> tFolders;
auto subDirs = subDirectories(path);
for(auto& subD: subDirs)
{
auto timeName = tailName(subD.wordPath(), '/');
real TIME;
if( auto success = readReal(timeName, TIME); success)
{
if(!tFolders.insertIf(TIME, subD))
{
fatalErrorInFunction<<
" duplicate time folder! time = " << TIME <<endl;
fatalExit;
}
}
}
return tFolders;
}
} // pFlow

@ -447,7 +447,7 @@ pFlow::iIstream& pFlow::Istream::read(token& t)
putback(c);
word val;
if (read(val).bad())
if (readString(val).bad())
{
t.setBad();
}

@ -61,6 +61,7 @@ bool pFlow::iIstream::findToken( const word & w )
{
rewind();
token next;
bool isFirstToken = true;
while( !eof() && good() )
{
@ -73,10 +74,17 @@ bool pFlow::iIstream::findToken( const word & w )
return false;
}
if( next.isWord() )
if( next.isWord() && isFirstToken)
{
if(next.wordToken() == w) return true;
if(next.wordToken() == w ) return true;
}
if(next.isEndStatement()|| next.isEndBlock())
isFirstToken = true;
else
isFirstToken = false;
}
return false;
@ -86,6 +94,7 @@ bool pFlow::iIstream::findTokenSilent( const word & w, int32 limitLine )
{
rewind();
token next;
bool isFirstToken = true;
while( !eof() && good() && lineNumber()<limitLine )
{
@ -95,10 +104,15 @@ bool pFlow::iIstream::findTokenSilent( const word & w, int32 limitLine )
return false;
}
if( next.isWord() )
if( next.isWord() && isFirstToken)
{
if(next.wordToken() == w) return true;
}
if(next.isEndStatement()|| next.isEndBlock())
isFirstToken = true;
else
isFirstToken = false;
}
return false;

@ -133,11 +133,11 @@ public:
virtual bool findToken( const word & w );
// - search for all tokesn and find the first word token tbat matchs
// - search for all tokesn and find the first word token that matchs
virtual bool findTokenSilent( const word & w, int32 limitLine = 100 );
// - search for all tokens and find the first word token and also next word token
// chekck if it i seneded with end statement ;
// chekck if it is eneded with end statement ;
virtual bool findTokenAndNext( const word& w, word& nextW, bool checkEndStatement = true);

@ -313,6 +313,8 @@ public:
//- Tolen is end statement
inline bool isEndStatement() const;
inline bool isEndBlock()const;
//- Token is INT64
inline bool isInt64() const;

@ -439,6 +439,16 @@ inline bool pFlow::token::isEndStatement() const
}
inline bool pFlow::token::isEndBlock() const
{
if( type_ == tokenType::PUNCTUATION )
{
return pToken() == punctuationToken::END_BLOCK;
}
return false;
}
inline pFlow::token::punctuationToken pFlow::token::pToken() const
{
if (type_ == tokenType::PUNCTUATION)

@ -191,6 +191,17 @@ bool pFlow::validWord(char c)
);
}
bool pFlow::validWordWithQuote(char c)
{
return
(
!isspace(c)
&& c != ';' // end statement
&& c != '{' // beg subdict
&& c != '}' // end subdict
);
}
bool pFlow::validWord(const word& w)
{
for(auto wi:w)
@ -201,6 +212,16 @@ bool pFlow::validWord(const word& w)
return true;
}
bool pFlow::validWordWithQuote(const word& w)
{
for(auto wi:w)
{
char c = wi;
if ( !validWordWithQuote(c) ) return false;
}
return true;
}
bool pFlow::readLabel( const word& w, label & val)
{

@ -81,9 +81,12 @@ word tailName(const word& w, char sep = '.');
// is the character valid for a word name
bool validWord(char c);
bool validWordWithQuote(char c);
bool validWord(const word& w);
bool validWordWithQuote(const word& c);
bool readLabel( const word& w, label & val);

@ -25,6 +25,25 @@ Licence:
#include "initialize.H"
Report(0)<<"\nCreating Control repository . . ."<<endReport;
pFlow::systemControl Control;
pFlow::uniquePtr<pFlow::systemControl> ControlPtr = nullptr;
if(isCoupling)
{
pFlow::readControlDict controlDict;
ControlPtr = pFlow::makeUnique<pFlow::systemControl>
(
controlDict.startTime(),
controlDict.endTime(),
controlDict.saveInterval(),
controlDict.startTimeName()
);
}
else
{
ControlPtr = pFlow::makeUnique<pFlow::systemControl>();
}
auto& Control = ControlPtr();
#endif

@ -2,6 +2,7 @@
set(SourceFiles
vtkFile.C
readFromTimeFolder.C
readControlDict.C
)
set(link_libs Kokkos::kokkos phasicFlow Particles Geometry)

@ -0,0 +1,121 @@
/*------------------------------- 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 "readControlDict.H"
#include "iFstream.H"
#include "timeFolder.H"
pFlow::word pFlow::readControlDict::convertTimeToName(
const real t,
const int32 precision)const
{
std::ostringstream buf;
if( formatType_ == "general")
buf.setf(ios_base::fmtflags(0), ios_base::floatfield);
else if(formatType_ == "scientific")
buf.setf(ios_base::fmtflags(ios_base::scientific), ios_base::floatfield);
else if(formatType_ == "fixed")
buf.setf(ios_base::fmtflags(ios_base::fixed), ios_base::floatfield);
else
{
fatalErrorInFunction<<"the timeFormat is not correct, it should be "
" (genral, scientific, fixe) but you supplied "<< formatType_<<endl;
fatalExit;
}
buf.precision(precision);
buf << t;
return buf.str();
}
bool pFlow::readControlDict::read()
{
iFstream cdFile(cdPath_);
word startFrom;
if( !cdFile.findTokenAndNextSilent("startFrom", startFrom))
{
startFrom = "latestTime";
}
if(startFrom == "startTime")
{
if(!cdFile.findKeywordAndVal("startTime", startTime_ ))
{
fatalErrorInFunction<<"Could not read startTime from file "<< cdPath_<<endl;
return false;
}
}
else
{
timeFolder folders(rootPath_);
if(startFrom == "firstTime")
{
startTime_ = folders.startTime();
}
else if( startFrom == "latestTime")
{
startTime_ = folders.endTime();
}
else
{
fatalErrorInFunction<<
"expected firstTime, latestTime, or startTime in front of StartFrom, "<<endl<<
"but found "<<startFrom<<endl;
return false;
}
}
if(!cdFile.findKeywordAndVal("endTime", endTime_ ))
{
fatalErrorInFunction<<
"Could not read endTime from file "<< cdPath_<<endl;
return false;
}
if(!cdFile.findKeywordAndVal("writeInterval", saveInterval_))
{
fatalErrorInFunction<<
"Could not read writeInterval from file "<< cdPath_<<endl;
return false;
}
formatType_ = cdFile.lookupDataOrSet<word>("timeFormat", "general");
precision_ = cdFile.lookupDataOrSet("timePrecision", 6);
return true;
}
pFlow::readControlDict::readControlDict(
const fileSystem& rootPath,
const fileSystem& cdPath)
:
rootPath_(rootPath),
cdPath_(cdPath)
{
if(!read())
{
fatalExit;
}
}

@ -0,0 +1,87 @@
/*------------------------------- 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 __readControlDict_H__
#define __readControlDict_H__
#include "fileSystem.H"
namespace pFlow
{
class
readControlDict
{
protected:
fileSystem rootPath_;
fileSystem cdPath_;
real startTime_;
real endTime_;
real saveInterval_;
word formatType_;
int32 precision_;
inline static fileSystem defaultRootPath = CWD();
inline static fileSystem defaultCDPath = CWD()/"system"+"controlDict";
word convertTimeToName(const real t, const int32 precision)const;
bool read();
public:
readControlDict(
const fileSystem& rootPath = defaultRootPath,
const fileSystem& cdPath = defaultCDPath);
auto startTime()const
{
return startTime_;
}
auto endTime()const
{
return endTime_;
}
auto saveInterval()const
{
return saveInterval_;
}
auto startTimeName()const
{
return convertTimeToName(startTime_, precision_);
}
};
}
#endif //__readControlDict_H__

@ -7,6 +7,6 @@ stlWall/stlWall.C
cylinderWall/cylinderWall.C
cuboidWall/cuboidWall.C
)
set(link_lib phasicFlow Geometry Kokkos::kokkos)
set(link_lib phasicFlow Geometry Kokkos::kokkos Utilities)
pFlow_make_executable_install(geometryPhasicFlow source_files link_lib)

@ -23,6 +23,8 @@ Licence:
#include "Wall.H"
#include "multiTriSurface.H"
#include "geometryMotion.H"
#include "commandLine.H"
#include "readControlDict.H"
using pFlow::output;
using pFlow::endl;
@ -33,10 +35,25 @@ using pFlow::wordVector;
using pFlow::Wall;
using pFlow::geometry;
using pFlow::multiTriSurface;
using pFlow::commandLine;
int main( int argc, char* argv[] )
{
commandLine cmds(
"geometryPhasicFlow",
"Converts the supplied informaiton for sufraces in"
" geometryDict into PhasicFlow geometry data structure");
bool isCoupling = false;
cmds.add_flag(
"-c,--coupling",
isCoupling,
"Is this a fluid-particle coupling simulation?");
if(!cmds.parse(argc, argv)) return 0;
// this should be palced in each main
#include "initialize_Control.H"

@ -25,6 +25,8 @@ Licence:
#include "timeFolder.H"
#include "commandLine.H"
#include "ranges.H"
#include "readControlDict.H"
using pFlow::word;
using pFlow::wordVector;
@ -80,6 +82,8 @@ int main(int argc, char** argv )
"a space separated lists of time folders, or a strided range begin:stride:end, or an interval begin:end",
" ");
bool isCoupling = false;
if(!cmds.parse(argc, argv)) return 0;

@ -6,6 +6,6 @@ positionOrdered/positionOrdered.C
positionRandom/positionRandom.C
empty/empty.C
)
set(link_lib phasicFlow Kokkos::kokkos Interaction)
set(link_lib phasicFlow Kokkos::kokkos Interaction Utilities)
pFlow_make_executable_install(particlesPhasicFlow source_files link_lib)

@ -24,6 +24,7 @@ Licence:
#include "setFields.H"
#include "systemControl.H"
#include "commandLine.H"
#include "readControlDict.H"
using pFlow::output;
using pFlow::endl;
@ -45,7 +46,7 @@ int main( int argc, char* argv[] )
"createParticles",
"Read the dictionary createParticles and create particles"
" based on the two sub-dictionaries positionParticles and setFields.\n"
"First executespositionParticles and then setFields, except "
"First executes positionParticles and then setFields, except "
"otherwise selected in the command line.");
@ -62,6 +63,11 @@ int main( int argc, char* argv[] )
"Exectue the setFields part only. Read the pointStructure from "
"time folder and setFields and save the result in the same time folder.");
bool isCoupling = false;
cmds.add_flag(
"-c,--coupling",
isCoupling,
"Is this a fluid-particle coupling simulation");
if(!cmds.parse(argc, argv)) return 0;

@ -22,6 +22,7 @@ Licence:
#include "timeFolder.H"
#include "commandLine.H"
#include "ranges.H"
#include "readControlDict.H"
#include "postprocess.H"
@ -65,6 +66,8 @@ int main(int argc, char** argv )
withZeroFolder,
"Do NOT exclude zero folder from processing time folders");
bool isCoupling = false;
if(!cmds.parse(argc, argv)) return 0;
#include "initialize_Control.H"