mirror of
https://github.com/PhasicFlow/phasicFlow.git
synced 2025-06-22 16:28:30 +00:00
postprocessPhasicFlow is now updated with new postprocessData auxFunction. It now uses postprocessDataDict.
This commit is contained in:
@ -24,7 +24,7 @@ Licence:
|
||||
#include "systemControl.hpp"
|
||||
#include "fieldsDataBase.hpp"
|
||||
#include "fieldFunctions.hpp"
|
||||
|
||||
#include "dictionary.hpp"
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
@ -38,19 +38,6 @@ bool pFlow::fieldsDataBase::loadPointStructureToTime()
|
||||
return false;
|
||||
}
|
||||
|
||||
pFlow::word pFlow::fieldsDataBase::getPointFieldType(const word &name) const
|
||||
{
|
||||
word pfType = time_.lookupObjectTypeName(name);
|
||||
word type, space;
|
||||
if(!pointFieldGetType(pfType, type, space))
|
||||
{
|
||||
fatalErrorInFunction
|
||||
<<"Error in retriving the type of pointField "
|
||||
<< pfType<<endl;
|
||||
fatalExit;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
bool pFlow::fieldsDataBase::checkForUpdate(const word &compoundName, bool forceUpdate)
|
||||
{
|
||||
@ -195,6 +182,78 @@ pFlow::span<pFlow::real> pFlow::fieldsDataBase::createOrGetOne(bool forceUpdate)
|
||||
field.size());
|
||||
}
|
||||
|
||||
pFlow::span<pFlow::real> pFlow::fieldsDataBase::createOrGetMass(bool forceUpdate)
|
||||
{
|
||||
const word fName = "mass";
|
||||
|
||||
bool shouldUpdate = checkForUpdate(fName, forceUpdate);
|
||||
|
||||
if(shouldUpdate)
|
||||
{
|
||||
const auto index = updateFieldUint32("shapeIndex", true);
|
||||
const auto ms = getShape().mass();
|
||||
|
||||
FieldTypeHost<real> massField
|
||||
(
|
||||
fName,
|
||||
"value",
|
||||
pointFieldSize()
|
||||
);
|
||||
|
||||
for(uint32 i=0; i< massField.size(); i++)
|
||||
{
|
||||
massField[i] = ms[index[i]];
|
||||
}
|
||||
|
||||
allFields_.emplaceBackOrReplace<FieldTypeHost<real>>
|
||||
(
|
||||
fName,
|
||||
std::move(massField)
|
||||
);
|
||||
}
|
||||
|
||||
auto& field = allFields_.getObject<FieldTypeHost<real>>(fName);
|
||||
return span<real>(
|
||||
field.data(),
|
||||
field.size());
|
||||
}
|
||||
|
||||
pFlow::span<pFlow::real> pFlow::fieldsDataBase::createOrGetI(bool forceUpdate)
|
||||
{
|
||||
const word fName = "I";
|
||||
|
||||
bool shouldUpdate = checkForUpdate(fName, forceUpdate);
|
||||
|
||||
if(shouldUpdate)
|
||||
{
|
||||
const auto index = updateFieldUint32("shapeIndex", true);
|
||||
const auto Is = getShape().Inertia();
|
||||
|
||||
FieldTypeHost<real> IField
|
||||
(
|
||||
fName,
|
||||
"value",
|
||||
pointFieldSize()
|
||||
);
|
||||
|
||||
for(uint32 i=0; i< IField.size(); i++)
|
||||
{
|
||||
IField[i] = Is[index[i]];
|
||||
}
|
||||
|
||||
allFields_.emplaceBackOrReplace<FieldTypeHost<real>>
|
||||
(
|
||||
fName,
|
||||
std::move(IField)
|
||||
);
|
||||
}
|
||||
|
||||
auto& field = allFields_.getObject<FieldTypeHost<real>>(fName);
|
||||
return span<real>(
|
||||
field.data(),
|
||||
field.size());
|
||||
}
|
||||
|
||||
bool pFlow::fieldsDataBase::findFunction(
|
||||
const word &compoundFieldName,
|
||||
word &fieldName,
|
||||
@ -399,11 +458,35 @@ bool pFlow::fieldsDataBase::inputOutputType
|
||||
return false;
|
||||
}
|
||||
|
||||
pFlow::fieldsDataBase::fieldsDataBase(systemControl& control, bool inSimulation)
|
||||
pFlow::fieldsDataBase::fieldsDataBase
|
||||
(
|
||||
systemControl& control,
|
||||
const dictionary& postDict,
|
||||
bool inSimulation,
|
||||
timeValue startTime
|
||||
)
|
||||
:
|
||||
time_(control.time()),
|
||||
inSimulation_(inSimulation)
|
||||
{}
|
||||
{
|
||||
if(!inSimulation_)
|
||||
{
|
||||
shapeType_ = postDict.getValOrSet<word>("shapeType", "");
|
||||
|
||||
if(shapeType_.empty())
|
||||
{
|
||||
WARNING
|
||||
<< "shapeType is not set in dictionary: "
|
||||
<< postDict.globalName()
|
||||
<< " and you may need to set for some postprocess operations"<<END_WARNING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is not required for execution during simulation
|
||||
shapeType_ = "";
|
||||
}
|
||||
}
|
||||
|
||||
pFlow::timeValue pFlow::fieldsDataBase::currentTime() const
|
||||
{
|
||||
@ -808,7 +891,13 @@ pFlow::allPointFieldTypes pFlow::fieldsDataBase::updateFieldAll
|
||||
|
||||
|
||||
pFlow::uniquePtr<pFlow::fieldsDataBase>
|
||||
pFlow::fieldsDataBase::create(systemControl& control, bool inSimulation)
|
||||
pFlow::fieldsDataBase::create
|
||||
(
|
||||
systemControl& control,
|
||||
const dictionary& postDict,
|
||||
bool inSimulation,
|
||||
timeValue startTime
|
||||
)
|
||||
{
|
||||
word dbType;
|
||||
if(inSimulation)
|
||||
@ -823,7 +912,7 @@ pFlow::uniquePtr<pFlow::fieldsDataBase>
|
||||
if( boolvCtorSelector_.search(dbType) )
|
||||
{
|
||||
auto objPtr =
|
||||
boolvCtorSelector_[dbType](control, inSimulation);
|
||||
boolvCtorSelector_[dbType](control, postDict, inSimulation, startTime);
|
||||
return objPtr;
|
||||
}
|
||||
else
|
||||
|
@ -33,6 +33,7 @@ Licence:
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
class dictionary;
|
||||
class systemControl;
|
||||
class Time;
|
||||
|
||||
@ -83,16 +84,9 @@ private:
|
||||
/// Flag indicating if we're in simulation mode
|
||||
bool inSimulation_ = false;
|
||||
|
||||
protected:
|
||||
word shapeType_;
|
||||
|
||||
/// Map of reserved field names with their corresponding types
|
||||
static const inline std::map<word, word> reservedFieldNames_
|
||||
{
|
||||
{"position", "realx3"},
|
||||
{"one", "real"},
|
||||
{"volume", "real"},
|
||||
{"density", "real"}
|
||||
};
|
||||
protected:
|
||||
|
||||
/// check if pointField name exists in Time or time folder
|
||||
virtual
|
||||
@ -104,12 +98,28 @@ protected:
|
||||
|
||||
virtual
|
||||
bool loadPointStructureToTime()=0;
|
||||
|
||||
virtual
|
||||
const shape& getShape() const= 0;
|
||||
|
||||
const word& shapeTypeName()const
|
||||
{
|
||||
return shapeType_;
|
||||
}
|
||||
|
||||
/// get the type name of the pointField in the Time object
|
||||
word getPointFieldType(const word& name)const;
|
||||
virtual
|
||||
word getPointFieldType(const word& name)const = 0;
|
||||
|
||||
/// Checks if a field needs to be updated based on capture time
|
||||
bool checkForUpdate(const word& compoundName, bool forceUpdate = false);
|
||||
|
||||
/// @brief return the size of pointStructure
|
||||
uint32 pointFieldSize()
|
||||
{
|
||||
auto s = updatePoints();
|
||||
return s.size();
|
||||
}
|
||||
|
||||
template<ValidFieldType T>
|
||||
span<T> updateField(const word& name, bool forceUpdate = false);
|
||||
@ -125,6 +135,21 @@ protected:
|
||||
|
||||
span<real> createOrGetOne(bool forceUpdate=false);
|
||||
|
||||
span<real> createOrGetMass(bool forceUpdate=false);
|
||||
|
||||
span<real> createOrGetI(bool forceUpdate=false);
|
||||
|
||||
/// Map of reserved field names with their corresponding types
|
||||
static const inline std::map<word, word> reservedFieldNames_
|
||||
{
|
||||
{"position", "realx3"},
|
||||
{"one", "real"},
|
||||
{"volume", "real"},
|
||||
{"density", "real"},
|
||||
{"mass", "real"},
|
||||
{"I", "real"}
|
||||
};
|
||||
|
||||
static
|
||||
bool findFunction(
|
||||
const word& compoundFieldName,
|
||||
@ -137,25 +162,7 @@ protected:
|
||||
const word& inputType,
|
||||
word& outputType);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// - protected member functions
|
||||
|
||||
|
||||
virtual
|
||||
bool checkTimeFolder(const word& fieldName) const = 0;
|
||||
|
||||
virtual
|
||||
const shape& getShape() const= 0;
|
||||
|
||||
|
||||
/// @brief return the size of pointStructure
|
||||
uint32 pointFieldSize()
|
||||
{
|
||||
auto s = updatePoints();
|
||||
return s.size();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@ -165,7 +172,11 @@ public:
|
||||
|
||||
// - constructors
|
||||
|
||||
fieldsDataBase(systemControl& control, bool inSimulation);
|
||||
fieldsDataBase(
|
||||
systemControl& control,
|
||||
const dictionary& postDict,
|
||||
bool inSimulation,
|
||||
timeValue startTime);
|
||||
|
||||
/// no copy constructor
|
||||
fieldsDataBase(const fieldsDataBase&) = delete;
|
||||
@ -186,8 +197,13 @@ public:
|
||||
(
|
||||
fieldsDataBase,
|
||||
bool,
|
||||
(systemControl& control, bool inSimulation),
|
||||
(control, inSimulation)
|
||||
(
|
||||
systemControl& control,
|
||||
const dictionary& postDict,
|
||||
bool inSimulation,
|
||||
timeValue startTime
|
||||
),
|
||||
(control, postDict, inSimulation, startTime)
|
||||
);
|
||||
|
||||
|
||||
@ -260,14 +276,39 @@ public:
|
||||
|
||||
virtual
|
||||
const pointStructure& pStruct()const = 0;
|
||||
|
||||
/// Get the next avaiable time folder after the current time folder
|
||||
/// This is only used for post-simulation processing
|
||||
virtual
|
||||
timeValue getNextTimeFolder()const
|
||||
{
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
/// Sets the current folder to the next time folder.
|
||||
/// This is used only for post-simulation processing
|
||||
/// @returns the time value of the next folder.
|
||||
virtual
|
||||
void resetTimeFolder() = 0;
|
||||
|
||||
timeValue setToNextTimeFolder()
|
||||
{
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
/// Skips the next time folder.
|
||||
/// This is used only for post-simulation processing
|
||||
/// @returns the time value of the skipped folder
|
||||
virtual
|
||||
timeValue skipNextTimeFolder()
|
||||
{
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
static
|
||||
uniquePtr<fieldsDataBase> create(
|
||||
systemControl& control,
|
||||
bool inSimulation);
|
||||
const dictionary& postDict,
|
||||
bool inSimulation,
|
||||
timeValue startTime);
|
||||
};
|
||||
|
||||
} // namespace pFlow
|
||||
|
@ -116,6 +116,36 @@ pFlow::span<T> pFlow::fieldsDataBase::updateReservedField
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
else if( name == "mass")
|
||||
{
|
||||
if constexpr( std::same_as<T,real>)
|
||||
{
|
||||
return createOrGetMass(forceUpdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
fatalErrorInFunction
|
||||
<< "This type: "
|
||||
<< getTypeName<T>()
|
||||
<<" is not supported for field mass."<<endl;
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
else if( name == "I")
|
||||
{
|
||||
if constexpr( std::same_as<T,real>)
|
||||
{
|
||||
return createOrGetI(forceUpdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
fatalErrorInFunction
|
||||
<< "This type: "
|
||||
<< getTypeName<T>()
|
||||
<<" is not supported for field I."<<endl;
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
else if( name == "position")
|
||||
{
|
||||
if constexpr( std::same_as<T, realx3>)
|
||||
|
@ -24,23 +24,35 @@ bool pFlow::simulationFieldsDataBase::loadPointStructureToTime()
|
||||
return time().lookupObjectName(pointStructureFile__);
|
||||
}
|
||||
|
||||
bool pFlow::simulationFieldsDataBase::checkTimeFolder(const word &fieldName) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const pFlow::shape& pFlow::simulationFieldsDataBase::getShape() const
|
||||
{
|
||||
return shape_;
|
||||
}
|
||||
|
||||
pFlow::word pFlow::simulationFieldsDataBase::getPointFieldType(const word &name) const
|
||||
{
|
||||
word pfType = time().lookupObjectTypeName(name);
|
||||
word type, space;
|
||||
if(!pointFieldGetType(pfType, type, space))
|
||||
{
|
||||
fatalErrorInFunction
|
||||
<<"Error in retriving the type of pointField "
|
||||
<< pfType<<endl;
|
||||
fatalExit;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
pFlow::simulationFieldsDataBase::simulationFieldsDataBase
|
||||
(
|
||||
systemControl &control,
|
||||
bool inSimulation
|
||||
systemControl &control,
|
||||
const dictionary& postDict,
|
||||
bool inSimulation,
|
||||
timeValue startTime
|
||||
)
|
||||
:
|
||||
fieldsDataBase(control, inSimulation),
|
||||
fieldsDataBase(control, postDict, inSimulation, startTime),
|
||||
shape_
|
||||
(
|
||||
dynamic_cast<const shape&>(*control.caseSetup().lookupObjectPtr(shapeFile__))
|
||||
@ -57,6 +69,3 @@ const pFlow::pointStructure &pFlow::simulationFieldsDataBase::pStruct() const
|
||||
);
|
||||
}
|
||||
|
||||
void pFlow::simulationFieldsDataBase::resetTimeFolder()
|
||||
{
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ protected:
|
||||
|
||||
/// check if pointField name exists in Time or time folder
|
||||
bool pointFieldNameExists(const word& name)const override;
|
||||
|
||||
|
||||
/// Loads a pointField with a given name to the Time object.
|
||||
/// For simulation, it just checks if the name exists
|
||||
@ -47,15 +48,19 @@ protected:
|
||||
/// For simulation, it just checks if the name exists
|
||||
bool loadPointStructureToTime() override;
|
||||
|
||||
bool checkTimeFolder(const word& fieldName) const override;
|
||||
|
||||
const shape& getShape() const override;
|
||||
|
||||
word getPointFieldType(const word& name)const override;
|
||||
|
||||
public:
|
||||
|
||||
TypeInfo("fieldsDataBase<simulation>");
|
||||
|
||||
simulationFieldsDataBase(systemControl& control, bool inSimulation);
|
||||
simulationFieldsDataBase(
|
||||
systemControl& control,
|
||||
const dictionary& postDict,
|
||||
bool inSimulation,
|
||||
timeValue startTime);
|
||||
|
||||
~simulationFieldsDataBase() override = default;
|
||||
|
||||
@ -68,8 +73,6 @@ public:
|
||||
|
||||
const pointStructure& pStruct()const override;
|
||||
|
||||
void resetTimeFolder() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -22,22 +22,18 @@ Licence:
|
||||
#include "List.hpp"
|
||||
#include "systemControl.hpp"
|
||||
#include "postprocessData.hpp"
|
||||
#include "fileDictionary.hpp"
|
||||
#include "postprocessGlobals.hpp"
|
||||
#include "postprocessComponent.hpp"
|
||||
|
||||
pFlow::postprocessData::postprocessData(const systemControl &control)
|
||||
pFlow::postprocessData::postprocessData
|
||||
(
|
||||
const systemControl &control,
|
||||
timeValue startTime
|
||||
)
|
||||
:
|
||||
auxFunctions(control),
|
||||
inSimulation_(startTime<0.0?true:false),
|
||||
time_(control.time()),
|
||||
fieldsDataBasePtr_
|
||||
(
|
||||
fieldsDataBase::create
|
||||
(
|
||||
const_cast<systemControl&>(control),
|
||||
true
|
||||
)
|
||||
),
|
||||
dict_
|
||||
(
|
||||
objectFile
|
||||
@ -59,6 +55,15 @@ pFlow::postprocessData::postprocessData(const systemControl &control)
|
||||
<<" This feature is disabled in the current run."<<END_WARNING;
|
||||
return;
|
||||
}
|
||||
|
||||
fieldsDataBasePtr_= fieldsDataBase::create
|
||||
(
|
||||
const_cast<systemControl&>(control),
|
||||
dict_,
|
||||
inSimulation_,
|
||||
startTime
|
||||
);
|
||||
|
||||
|
||||
activeInSimulation_ = dict_.getValOrSet<Logical>(
|
||||
"activeInSimulation",
|
||||
@ -80,12 +85,6 @@ pFlow::postprocessData::postprocessData(const systemControl &control)
|
||||
control.time().saveInterval(),
|
||||
"execution");
|
||||
}
|
||||
|
||||
shapeType_ = dict_.getValOrSet<word>
|
||||
(
|
||||
"shapeType",
|
||||
word("sphere")
|
||||
);
|
||||
|
||||
componentsDictsPtr_ = makeUnique<dictionaryList>(readDictList("components", dict_));
|
||||
|
||||
@ -105,10 +104,10 @@ bool pFlow::postprocessData::execute()
|
||||
|
||||
for(auto& component:postprocesses_)
|
||||
{
|
||||
if(!component->execute(ti))
|
||||
if(!component->execute(ti, !inSimulation_) )
|
||||
{
|
||||
fatalErrorInFunction
|
||||
<<"Error occured in executing postprocess component: "
|
||||
<<"Error occurred in executing postprocess component: "
|
||||
<<component->name()<<endl;
|
||||
return false;
|
||||
}
|
||||
@ -125,6 +124,7 @@ bool pFlow::postprocessData::write() const
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!component->write(postProcessGlobals::defaultDir__/component->name()))
|
||||
{
|
||||
fatalErrorInFunction
|
||||
@ -135,3 +135,8 @@ bool pFlow::postprocessData::write() const
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void pFlow::postprocessData::setOutputDirectory(const fileSystem &path) const
|
||||
{
|
||||
postProcessGlobals::defaultDir__ = path;
|
||||
}
|
||||
|
@ -20,14 +20,14 @@ Licence:
|
||||
#ifndef __postprocessData_hpp__
|
||||
#define __postprocessData_hpp__
|
||||
|
||||
#include "auxFunctions.hpp"
|
||||
#include "Logical.hpp"
|
||||
#include "ListPtr.hpp"
|
||||
#include "fileDictionary.hpp"
|
||||
#include "baseTimeControl.hpp"
|
||||
#include "dictionaryList.hpp"
|
||||
#include "auxFunctions.hpp"
|
||||
#include "fieldsDataBase.hpp"
|
||||
#include "postprocessComponent.hpp"
|
||||
#include "dictionaryList.hpp"
|
||||
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
@ -36,6 +36,7 @@ class systemControl;
|
||||
class Time;
|
||||
class timeInfo;
|
||||
|
||||
|
||||
/**
|
||||
* @class postprocessData
|
||||
* @brief An interface class for handling post-processing of simulation data.
|
||||
@ -47,7 +48,11 @@ class postprocessData
|
||||
:
|
||||
public auxFunctions
|
||||
{
|
||||
/// Indicates if a post-processing is active during simulatoin
|
||||
/// Indicates if this is post-processing during simulation or
|
||||
/// post-simulation
|
||||
bool inSimulation_;
|
||||
|
||||
/// Indicates if a post-processing is active during simulation
|
||||
Logical activeInSimulation_{false};
|
||||
|
||||
/// a list of active post-process components
|
||||
@ -62,9 +67,6 @@ class postprocessData
|
||||
/// file dictionary that is constructed from the file (postProcessDataDict)
|
||||
fileDictionary dict_;
|
||||
|
||||
/// name of the shape for use in the time of postprocess after simulation
|
||||
word shapeType_;
|
||||
|
||||
/// list of dictionaries for postprocess components
|
||||
uniquePtr<dictionaryList> componentsDictsPtr_ = nullptr;
|
||||
|
||||
@ -79,7 +81,7 @@ public:
|
||||
/// this constructor is used when postprocesing is active
|
||||
/// during simulation.
|
||||
/// @param control const reference to systemControl
|
||||
postprocessData(const systemControl& control);
|
||||
postprocessData(const systemControl& control, timeValue startTime = -1.0);
|
||||
|
||||
~postprocessData()override = default;
|
||||
|
||||
@ -92,11 +94,19 @@ public:
|
||||
|
||||
bool execute() override;
|
||||
|
||||
|
||||
|
||||
bool write()const override;
|
||||
|
||||
fieldsDataBase& database()
|
||||
{
|
||||
return fieldsDataBasePtr_();
|
||||
}
|
||||
|
||||
const fieldsDataBase& database()const
|
||||
{
|
||||
return fieldsDataBasePtr_();
|
||||
}
|
||||
|
||||
void setOutputDirectory(const fileSystem& path)const;
|
||||
};
|
||||
|
||||
} // namespace pFlow
|
||||
|
@ -49,6 +49,7 @@ repository/Time/baseTimeControl.cpp
|
||||
repository/systemControl/systemControl.cpp
|
||||
repository/systemControl/auxFunctions/auxFunctions.cpp
|
||||
repository/systemControl/dynamicLinkLibs.cpp
|
||||
repository/systemControl/timeFolder.cpp
|
||||
|
||||
commandLine/commandLine.cpp
|
||||
|
||||
|
@ -128,6 +128,42 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
T minVal()const
|
||||
{
|
||||
T m = largestPositive<T>();
|
||||
for(const auto& sr:sRanges_)
|
||||
{
|
||||
m = min(m, sr.begin());
|
||||
}
|
||||
for(const auto& iR:iRanges_)
|
||||
{
|
||||
m = min(m, iR.begin());
|
||||
}
|
||||
for(const auto& i:individuals_)
|
||||
{
|
||||
m = min(m, i);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
T maxVal()const
|
||||
{
|
||||
T m = largestNegative<T>();
|
||||
for(const auto& sr:sRanges_)
|
||||
{
|
||||
m = max(m, sr.begin());
|
||||
}
|
||||
for(const auto& iR:iRanges_)
|
||||
{
|
||||
m = max(m, iR.begin());
|
||||
}
|
||||
for(const auto& i:individuals_)
|
||||
{
|
||||
m = max(m, i);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
bool isMember(T val)const
|
||||
{
|
||||
for(auto& sR:sRanges_)
|
||||
|
@ -68,6 +68,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
T begin()const
|
||||
{
|
||||
return begin_;
|
||||
}
|
||||
|
||||
T end()const
|
||||
{
|
||||
return end_;
|
||||
}
|
||||
|
||||
inline
|
||||
bool isMember(T val)const
|
||||
|
@ -30,6 +30,25 @@ Licence:
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
constexpr T getEpsilon()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr float getEpsilon<float>()
|
||||
{
|
||||
return 10*std::numeric_limits<float>::epsilon();
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr double getEpsilon<double>()
|
||||
{
|
||||
return 10*std::numeric_limits<double>::epsilon();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
class
|
||||
stridedRange
|
||||
@ -107,7 +126,7 @@ public:
|
||||
}
|
||||
|
||||
inline
|
||||
bool isMember(T val, T epsilon = 0)const
|
||||
bool isMember(T val, T epsilon = getEpsilon<T>())const
|
||||
{
|
||||
|
||||
if(!isInRange(val)) return false;
|
||||
@ -151,7 +170,7 @@ public:
|
||||
|
||||
template<>
|
||||
inline
|
||||
bool stridedRange<float>::isMember(float val, float epsilon)const
|
||||
bool stridedRange<float>::isMember(float val, float epsilon )const
|
||||
{
|
||||
|
||||
if(!isInRange(val)) return false;
|
||||
@ -171,7 +190,7 @@ bool stridedRange<float>::isMember(float val, float epsilon)const
|
||||
|
||||
template<>
|
||||
inline
|
||||
bool stridedRange<double>::isMember(double val, double epsilon)const
|
||||
bool stridedRange<double>::isMember(double val, double epsilon )const
|
||||
{
|
||||
/*if(!isInRange(val)) return false;
|
||||
if(const double dist = val-begin_; abs(remainder(dist,stride_)<= epsilon)) return true;
|
||||
|
131
src/phasicFlow/repository/systemControl/timeFolder.cpp
Normal file
131
src/phasicFlow/repository/systemControl/timeFolder.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
/*------------------------------- 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 "timeFolder.hpp"
|
||||
#include "vocabs.hpp"
|
||||
|
||||
|
||||
bool pFlow::timeFolder::validateForPointStructure()
|
||||
{
|
||||
std::erase_if
|
||||
(
|
||||
folders_,
|
||||
[this](const auto& folder)
|
||||
{
|
||||
return !containsPointStructure(folder.second);
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pFlow::timeFolder::validFieldFile(const fileSystem &filePath) const
|
||||
{
|
||||
IOfileHeader fieldHeader(
|
||||
objectFile(
|
||||
filePath.fileName(),
|
||||
filePath.dirPath(),
|
||||
objectFile::READ_ALWAYS,
|
||||
objectFile::WRITE_NEVER)
|
||||
);
|
||||
return fieldHeader.headerOk(true);
|
||||
}
|
||||
|
||||
bool pFlow::timeFolder::validFieldFile
|
||||
(
|
||||
const fileSystem &filePath,
|
||||
word &fieldName,
|
||||
word &objectType
|
||||
) const
|
||||
{
|
||||
IOfileHeader fieldHeader(
|
||||
objectFile(
|
||||
filePath.fileName(),
|
||||
filePath.dirPath(),
|
||||
objectFile::READ_ALWAYS,
|
||||
objectFile::WRITE_NEVER)
|
||||
);
|
||||
|
||||
if(!fieldHeader.headerOk(true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldName = fieldHeader.objectName();
|
||||
objectType = fieldHeader.objectType();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
pFlow::timeFolder::timeFolder
|
||||
(
|
||||
const systemControl& control,
|
||||
bool pointStructureOnly
|
||||
)
|
||||
:
|
||||
timeFolder(control.path(), pointStructureOnly)
|
||||
{}
|
||||
|
||||
|
||||
pFlow::timeFolder::timeFolder
|
||||
(
|
||||
const fileSystem& path,
|
||||
bool pointStructureOnly
|
||||
)
|
||||
:
|
||||
folders_(getTimeFolders(path)),
|
||||
currentFolder_(folders_.begin())
|
||||
{
|
||||
if(pointStructureOnly)
|
||||
{
|
||||
validateForPointStructure();
|
||||
}
|
||||
currentFolder_ = folders_.begin();
|
||||
}
|
||||
|
||||
bool pFlow::timeFolder::containsPointStructure(const fileSystem &dirPath) const
|
||||
{
|
||||
auto files = containingFiles(dirPath);
|
||||
for (const auto &file : files)
|
||||
{
|
||||
if (file.fileName() == pointStructureFile__)
|
||||
{
|
||||
return validFieldFile(file);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pFlow::Map<pFlow::word, pFlow::word> pFlow::timeFolder::currentFolderFiles() const
|
||||
{
|
||||
Map<word,word> fileList;
|
||||
if( folders_.empty()) return fileList;
|
||||
|
||||
auto files = containingFiles(folder());
|
||||
word name, objectType;
|
||||
for (const auto &file : files)
|
||||
{
|
||||
if(validFieldFile(file, name, objectType))
|
||||
{
|
||||
fileList.insertIf(name, objectType);
|
||||
}
|
||||
}
|
||||
return fileList;
|
||||
}
|
@ -27,38 +27,55 @@ Licence:
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
Map<real, fileSystem> getTimeFolders(const fileSystem& path);
|
||||
Map<timeValue, fileSystem> getTimeFolders(const fileSystem& path);
|
||||
|
||||
class timeFolder
|
||||
{
|
||||
using timeList = Map<real, fileSystem>;
|
||||
using timeList = Map<timeValue, fileSystem>;
|
||||
|
||||
protected:
|
||||
|
||||
timeList folders_;
|
||||
|
||||
timeList::iterator currentFolder_;
|
||||
|
||||
|
||||
bool validateForPointStructure();
|
||||
|
||||
bool validFieldFile(const fileSystem& filePath)const;
|
||||
|
||||
bool validFieldFile(
|
||||
const fileSystem& filePath,
|
||||
word& fieldName,
|
||||
word& objectType)const;
|
||||
|
||||
public:
|
||||
|
||||
timeFolder(const systemControl& control )
|
||||
:
|
||||
timeFolder(control.path())
|
||||
{}
|
||||
|
||||
timeFolder(const fileSystem& path)
|
||||
:
|
||||
folders_(getTimeFolders(path)),
|
||||
currentFolder_(folders_.begin())
|
||||
timeFolder(const systemControl& control, bool pointStructureOnly = false );
|
||||
|
||||
timeFolder(const fileSystem& path, bool pointStructureOnly = false);
|
||||
|
||||
inline
|
||||
bool empty()const
|
||||
{
|
||||
|
||||
return folders_.empty();
|
||||
}
|
||||
|
||||
real time()const
|
||||
inline
|
||||
timeValue currentTime()const
|
||||
{
|
||||
if(folders_.empty()) return -1;
|
||||
return currentFolder_->first;
|
||||
}
|
||||
|
||||
inline
|
||||
timeValue nextTime()const
|
||||
{
|
||||
auto next = currentFolder_;
|
||||
next++;
|
||||
if(next == folders_.end()) return -1;
|
||||
return next->first;
|
||||
}
|
||||
|
||||
fileSystem folder()const
|
||||
{
|
||||
return currentFolder_->second;
|
||||
@ -81,6 +98,27 @@ public:
|
||||
return !finished();
|
||||
}
|
||||
|
||||
bool setTime(timeValue upto)
|
||||
{
|
||||
timeList::iterator orgFolder = currentFolder_;
|
||||
|
||||
rewind();
|
||||
|
||||
while(!finished())
|
||||
{
|
||||
auto t = currentTime();
|
||||
if( equal(upto, t) || t>upto)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
(*this)++;
|
||||
}
|
||||
|
||||
currentFolder_ = orgFolder;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
explicit operator bool()const
|
||||
{
|
||||
return !finished();
|
||||
@ -102,30 +140,38 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
real startTime()const
|
||||
timeValue startTime()const
|
||||
{
|
||||
if(folders_.empty()) return -1;
|
||||
auto [t,f] = *folders_.begin();
|
||||
return t;
|
||||
}
|
||||
|
||||
real endTime()const
|
||||
timeValue endTime()const
|
||||
{
|
||||
if(folders_.empty()) return -1;
|
||||
auto [t,f] = *(--folders_.end());
|
||||
return t;
|
||||
}
|
||||
|
||||
bool containsPointStructure(const fileSystem& dirPath)const;
|
||||
|
||||
/// Get the list of files in the current folder
|
||||
/// the first element is file name and the second is the objectType
|
||||
Map<word, word> currentFolderFiles()const;
|
||||
};
|
||||
|
||||
inline
|
||||
Map<real, fileSystem> getTimeFolders(const fileSystem& path)
|
||||
Map<timeValue, fileSystem> getTimeFolders(const fileSystem& path)
|
||||
{
|
||||
Map<real, fileSystem> tFolders;
|
||||
Map<timeValue, fileSystem> tFolders;
|
||||
|
||||
auto subDirs = subDirectories(path);
|
||||
|
||||
for(auto& subD: subDirs)
|
||||
{
|
||||
auto timeName = tailName(subD.wordPath(), '/');
|
||||
real TIME;
|
||||
timeValue TIME;
|
||||
if( auto success = readReal(timeName, TIME); success)
|
||||
{
|
||||
if(!tFolders.insertIf(TIME, subD))
|
||||
|
Reference in New Issue
Block a user