mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: base fvMesh driver for expressions
This commit is contained in:
@ -250,6 +250,15 @@ $(constraintFvsPatchFields)/wedge/wedgeFvsPatchFields.C
|
||||
fields/volFields/volFields.C
|
||||
fields/surfaceFields/surfaceFields.C
|
||||
|
||||
expr = expressions
|
||||
$(expr)/base/exprDriverWriter.C
|
||||
|
||||
$(expr)/base/fvExprDriver.C
|
||||
$(expr)/base/fvExprDriverFields.C
|
||||
$(expr)/base/fvExprDriverIO.C
|
||||
$(expr)/base/fvExprDriverNew.C
|
||||
|
||||
|
||||
fvMatrices/fvMatrices.C
|
||||
fvMatrices/fvScalarMatrix/fvScalarMatrix.C
|
||||
fvMatrices/solvers/MULES/MULES.C
|
||||
|
||||
100
src/finiteVolume/expressions/base/exprDriverWriter.C
Normal file
100
src/finiteVolume/expressions/base/exprDriverWriter.C
Normal file
@ -0,0 +1,100 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "exprDriverWriter.H"
|
||||
#include "fvExprDriver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
defineTypeName(exprDriverWriter);
|
||||
|
||||
} // namespace expressions
|
||||
} // namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::exprDriverWriter::exprDriverWriter
|
||||
(
|
||||
const word& name,
|
||||
fvExprDriver& driver
|
||||
)
|
||||
:
|
||||
regIOobject
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
name,
|
||||
driver.mesh().time().timeName(),
|
||||
"expressions",
|
||||
driver.mesh().time(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
)
|
||||
),
|
||||
driver_(driver)
|
||||
{
|
||||
if (headerOk())
|
||||
{
|
||||
readData(readStream("exprDriverWriter", true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::expressions::exprDriverWriter::readData(Istream& is)
|
||||
{
|
||||
dictionary dict(is);
|
||||
|
||||
// driver_.readDict(is);
|
||||
|
||||
driver_.getData(dict);
|
||||
|
||||
return !is.bad();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::exprDriverWriter::writeData(Ostream& os) const
|
||||
{
|
||||
// driver_.writeDict(os);
|
||||
|
||||
dictionary dict;
|
||||
driver_.prepareData(dict);
|
||||
dict.write(os, false);
|
||||
|
||||
return os.good();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
109
src/finiteVolume/expressions/base/exprDriverWriter.H
Normal file
109
src/finiteVolume/expressions/base/exprDriverWriter.H
Normal file
@ -0,0 +1,109 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::expressions::exprDriverWriter
|
||||
|
||||
Description
|
||||
Registered input/output for an expressions::fvExprDriver
|
||||
|
||||
SourceFiles
|
||||
exprDriverWriter.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_exprDriverWriter_H
|
||||
#define expressions_exprDriverWriter_H
|
||||
|
||||
#include "fvExprDriver.H"
|
||||
#include "regIOobject.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class exprDriverWriter Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class exprDriverWriter
|
||||
:
|
||||
public regIOobject
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The driver to read/write
|
||||
fvExprDriver& driver_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No null constructor
|
||||
exprDriverWriter() = delete;
|
||||
|
||||
//- No copy construct
|
||||
exprDriverWriter(const exprDriverWriter&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const exprDriverWriter&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeNameNoDebug("exprDriverWriter");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct for named driver
|
||||
exprDriverWriter(const word& name, fvExprDriver& driver);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~exprDriverWriter() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
virtual bool readData(Istream& is);
|
||||
virtual bool writeData(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
765
src/finiteVolume/expressions/base/fvExprDriver.C
Normal file
765
src/finiteVolume/expressions/base/fvExprDriver.C
Normal file
@ -0,0 +1,765 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvExprDriver.H"
|
||||
#include "exprDriverWriter.H"
|
||||
#include "expressionEntry.H"
|
||||
#include "exprResultGlobals.H"
|
||||
|
||||
#include "cellSet.H"
|
||||
#include "faceSet.H"
|
||||
#include "pointSet.H"
|
||||
#include "stringOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
defineTypeNameAndDebug(fvExprDriver, 0);
|
||||
defineRunTimeSelectionTable(fvExprDriver, dictionary);
|
||||
defineRunTimeSelectionTable(fvExprDriver, idName);
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
// Currently not working?
|
||||
bool Foam::expressions::fvExprDriver::cacheSets_ = true;
|
||||
|
||||
const Foam::fvMesh* Foam::expressions::fvExprDriver::defaultMeshPtr_ = nullptr;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
const Foam::fvMesh& Foam::expressions::fvExprDriver::defaultMesh()
|
||||
{
|
||||
if (!defaultMeshPtr_)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No default mesh set" << nl
|
||||
<< "Try the 'fvExprDriverFunctionObject' as a workaround"
|
||||
<< endl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return *defaultMeshPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::fvMesh* Foam::expressions::fvExprDriver::resetDefaultMesh
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const bool force
|
||||
)
|
||||
{
|
||||
const fvMesh* ptr = defaultMeshPtr_;
|
||||
|
||||
if (force || (ptr != nullptr))
|
||||
{
|
||||
defaultMeshPtr_ = &mesh;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::fvExprDriver::fvExprDriver
|
||||
(
|
||||
bool cacheReadFields,
|
||||
bool searchInMemory,
|
||||
bool searchOnDisc,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
expressions::exprDriver
|
||||
(
|
||||
cacheReadFields,
|
||||
searchInMemory,
|
||||
searchOnDisc,
|
||||
dict
|
||||
),
|
||||
globalScopes_(),
|
||||
delayedVariables_(),
|
||||
storedVariables_(),
|
||||
specialVariablesIndex_(-1),
|
||||
otherMeshName_(),
|
||||
libs_(),
|
||||
writer_(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::fvExprDriver::fvExprDriver
|
||||
(
|
||||
const fvExprDriver& rhs
|
||||
)
|
||||
:
|
||||
expressions::exprDriver(rhs),
|
||||
globalScopes_(rhs.globalScopes_),
|
||||
delayedVariables_(rhs.delayedVariables_),
|
||||
storedVariables_(rhs.storedVariables_),
|
||||
specialVariablesIndex_(rhs.specialVariablesIndex_),
|
||||
otherMeshName_(),
|
||||
libs_(),
|
||||
writer_(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::fvExprDriver::fvExprDriver
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
fvExprDriver
|
||||
(
|
||||
dict.lookupOrDefault("cacheReadFields", false),
|
||||
dict.lookupOrDefault("searchInMemory", true),
|
||||
dict.lookupOrDefault("searchOnDisc", false),
|
||||
dict
|
||||
)
|
||||
{
|
||||
readDict(dict);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::fvExprDriver::~fvExprDriver()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::expressions::fvExprDriver::readDict
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
expressions::exprDriver::readDict(dict);
|
||||
|
||||
// wordList plugins;
|
||||
// if (dict.readIfPresent("functionPlugins", plugins))
|
||||
// {
|
||||
// for (const word& plugin : plugins)
|
||||
// {
|
||||
// libs_.open("libswak" + plugin + "FunctionPlugin.so");
|
||||
// }
|
||||
// }
|
||||
|
||||
dict.readIfPresent("globalScopes", globalScopes_);
|
||||
|
||||
const entry* eptr = nullptr;
|
||||
|
||||
// Special variables
|
||||
|
||||
if
|
||||
(
|
||||
// storedVariables
|
||||
(eptr = dict.findEntry("storedVariables", keyType::LITERAL))
|
||||
!= nullptr
|
||||
)
|
||||
{
|
||||
ITstream& is = eptr->stream();
|
||||
|
||||
if (writer_.valid() && storedVariables_.size())
|
||||
{
|
||||
WarningInFunction
|
||||
// << "Context: " << driverContext_ << nl
|
||||
<< "The 'storedVariables' was already read."
|
||||
<< " No update from " << is
|
||||
<< endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
storedVariables_ = List<exprResultStored>(is);
|
||||
|
||||
// Check for excess tokens
|
||||
dict.checkITstream(is, "storedVariables");
|
||||
}
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
// delayedVariables
|
||||
(eptr = dict.findEntry("delayedVariables", keyType::LITERAL))
|
||||
!= nullptr
|
||||
)
|
||||
{
|
||||
ITstream& is = eptr->stream();
|
||||
|
||||
if (writer_.valid() && delayedVariables_.size())
|
||||
{
|
||||
WarningInFunction
|
||||
// << "Context: " << driverContext_ << nl
|
||||
<< "Seems like 'delayedVariables' was already read."
|
||||
<< " No update from " << is
|
||||
<< endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<exprResultDelayed> inputs(is);
|
||||
|
||||
// Check for excess tokens
|
||||
dict.checkITstream(is, "delayedVariables");
|
||||
|
||||
for (auto& var : inputs)
|
||||
{
|
||||
delayedVariables_.insert(var.name(), var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::Time& Foam::expressions::fvExprDriver::runTime() const
|
||||
{
|
||||
return this->mesh().time();
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::fvExprDriver::timeName() const
|
||||
{
|
||||
return runTime().timeName();
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::expressions::fvExprDriver::timeValue() const
|
||||
{
|
||||
return runTime().value();
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::updateSpecialVariables(bool force)
|
||||
{
|
||||
const bool updated = this->update();
|
||||
|
||||
const label eventIndex = mesh().time().timeIndex();
|
||||
const scalar eventTime = mesh().time().value();
|
||||
|
||||
DebugInfo
|
||||
<< "fvExprDriver::updateSpecialVariables(force="
|
||||
<< force << ") Updated: " << updated << endl;
|
||||
|
||||
if (specialVariablesIndex_ < 0)
|
||||
{
|
||||
DebugInfo
|
||||
<< "First update: " << eventIndex << endl;
|
||||
|
||||
specialVariablesIndex_ = eventIndex;
|
||||
|
||||
for (exprResultStored& v : storedVariables_)
|
||||
{
|
||||
DebugInfo
|
||||
<< v.name() << " = " << v.initialValueExpression()
|
||||
<< " (has value "
|
||||
<< v.hasValue() << ")" << endl;
|
||||
|
||||
if (!v.hasValue())
|
||||
{
|
||||
DebugInfo
|
||||
<< "First value: " << v.initialValueExpression()
|
||||
<< " -> " << v.name() << endl;
|
||||
|
||||
parse(v.initialValueExpression());
|
||||
v = result_;
|
||||
DebugInfo
|
||||
<< "Parser size: " << this->size() << nl
|
||||
<< "Calculated: " << result_ << nl
|
||||
<< "Stored: " << v << nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (force || specialVariablesIndex_ != eventIndex)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Store variables: " << force << ' '
|
||||
<< specialVariablesIndex_ << ' '
|
||||
<< eventIndex << endl;
|
||||
|
||||
for (exprResultStored& v : storedVariables_)
|
||||
{
|
||||
if (variables_.found(v.name()))
|
||||
{
|
||||
DebugInfo
|
||||
<< "Storing variable: " << v.name() << " "
|
||||
<< variables_[v.name()] << endl;
|
||||
|
||||
v = variables_[v.name()];
|
||||
}
|
||||
}
|
||||
specialVariablesIndex_ = eventIndex;
|
||||
}
|
||||
|
||||
forAllIters(delayedVariables_, iter)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Updating delayed variable " << iter().name() << endl;
|
||||
|
||||
if (!iter().updateReadValue(eventTime))
|
||||
{
|
||||
const exprString& expr = iter().startupValueExpression();
|
||||
|
||||
DebugInfo
|
||||
<< "Evaluate: " << expr << endl;
|
||||
|
||||
parse(expr);
|
||||
iter().setReadValue(result_);
|
||||
|
||||
DebugInfo
|
||||
<< "Value " << iter() << nl
|
||||
<< "Type " << iter().valueType() << "("
|
||||
<< result_.valueType() << ")" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugInfo
|
||||
<< iter().name() << " updated without problem" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::clearVariables()
|
||||
{
|
||||
DebugInfo
|
||||
<< "Clearing variables" << endl;
|
||||
|
||||
const scalar eventTime = mesh().time().value();
|
||||
|
||||
(void)this->update();
|
||||
|
||||
updateSpecialVariables();
|
||||
variables_.clear();
|
||||
for (exprResultStored& v : storedVariables_)
|
||||
{
|
||||
variables_.insert(v.name(), v);
|
||||
}
|
||||
|
||||
addVariables(variableStrings_, false);
|
||||
|
||||
forAllIters(delayedVariables_, iter)
|
||||
{
|
||||
iter().storeValue(eventTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::evaluateVariable
|
||||
(
|
||||
const word& varName,
|
||||
const expressions::exprString& expr
|
||||
)
|
||||
{
|
||||
const regIOobject* objPtr = mesh().findObject<regIOobject>(varName);
|
||||
|
||||
if (!allowShadowing_ && objPtr)
|
||||
{
|
||||
WarningInFunction
|
||||
// << "Context: " << driverContext_ << nl
|
||||
<< "Field '" << varName << "' (type " << objPtr->headerClassName()
|
||||
<< ") is shadowed by a variable of the same name." << nl
|
||||
<< "This may lead to trouble" << nl
|
||||
<< "If this is OK set 'allowShadowing'"
|
||||
<< " in the relevant parser" << nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
parse(expr);
|
||||
result_.testIfSingleValue();
|
||||
|
||||
DebugInfo
|
||||
<< "Evaluating: " << expr << " -> " << varName << endl
|
||||
<< result_;
|
||||
|
||||
|
||||
// Assign
|
||||
if (delayedVariables_.found(varName))
|
||||
{
|
||||
// Avoid potential conflicts?
|
||||
variables_.erase(varName);
|
||||
|
||||
DebugInfo
|
||||
<< varName << " is delayed" << endl;
|
||||
|
||||
// Copy assignment
|
||||
delayedVariables_[varName] = result_;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Overwrite with a copy
|
||||
variables_.set(varName, exprResult(result_));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::evaluateVariableRemote
|
||||
(
|
||||
string remote,
|
||||
const word& varName,
|
||||
const expressions::exprString& expr
|
||||
)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Evaluating remote " << remote.c_str()
|
||||
<< " : " << expr << " -> " << varName << endl;
|
||||
|
||||
word driverType("patch"); // default is patch
|
||||
word identName, regionName;
|
||||
|
||||
const auto slashPos = remote.find('/');
|
||||
if (slashPos != std::string::npos)
|
||||
{
|
||||
regionName = word::validate(remote.substr(slashPos+1));
|
||||
remote.resize(slashPos);
|
||||
}
|
||||
|
||||
const auto quotePos = remote.find('\'');
|
||||
if (quotePos != std::string::npos)
|
||||
{
|
||||
driverType = word::validate(remote.substr(0, quotePos));
|
||||
identName = word::validate(remote.substr(quotePos+1));
|
||||
}
|
||||
else
|
||||
{
|
||||
identName = word::validate(remote);
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
driverType == "patch"
|
||||
&&
|
||||
(
|
||||
identName.empty()
|
||||
|| identName == "volume"
|
||||
|| identName == "internalField"
|
||||
)
|
||||
)
|
||||
{
|
||||
driverType = "internalField";
|
||||
}
|
||||
|
||||
const fvMesh* pRegion = &(this->mesh());
|
||||
|
||||
if (!regionName.empty())
|
||||
{
|
||||
pRegion = pRegion->time().cfindObject<fvMesh>(regionName);
|
||||
|
||||
if (!pRegion)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Cannot resolve mesh region: " << regionName << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
DebugInfo
|
||||
<< "Call other with ("
|
||||
<< driverType << ", " << identName << ", " << regionName << ")\n";
|
||||
|
||||
autoPtr<fvExprDriver> otherDriver =
|
||||
fvExprDriver::New(driverType, identName, *pRegion);
|
||||
|
||||
otherDriver->setSearchBehaviour(*this);
|
||||
otherDriver->setGlobalScopes(this->globalScopes_);
|
||||
|
||||
otherDriver->parse(expr);
|
||||
|
||||
exprResult otherResult(this->getRemoteResult(*otherDriver));
|
||||
|
||||
// Check / re-check for uniform. Not normally needed
|
||||
if (!otherResult.isUniform())
|
||||
{
|
||||
otherResult.testIfSingleValue();
|
||||
}
|
||||
|
||||
DebugInfo
|
||||
<< "Remote result: " << otherResult << nl;
|
||||
|
||||
// Assign
|
||||
if (delayedVariables_.found(varName))
|
||||
{
|
||||
// Avoid potential conflicts?
|
||||
variables_.erase(varName);
|
||||
|
||||
DebugInfo
|
||||
<< varName << " is delayed - setting" << nl;
|
||||
|
||||
// Move assignment
|
||||
delayedVariables_[varName] = std::move(otherResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Overwrite with a copy
|
||||
variables_.set(varName, std::move(otherResult));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Foam::fvMesh&
|
||||
Foam::expressions::fvExprDriver::regionMesh
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh,
|
||||
bool readIfNecessary
|
||||
)
|
||||
{
|
||||
word regionName;
|
||||
|
||||
if (!dict.readIfPresent("region", regionName))
|
||||
{
|
||||
DebugInFunction << "Using original mesh " << nl;
|
||||
return mesh;
|
||||
}
|
||||
|
||||
DebugInFunction << "Using mesh " << regionName << endl;
|
||||
|
||||
fvMesh* meshPtr = mesh.time().getObjectPtr<fvMesh>(regionName);
|
||||
|
||||
if (!meshPtr && readIfNecessary)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Region " << regionName
|
||||
<< " not in memory. Loading it" << endl;
|
||||
|
||||
meshPtr = new fvMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
regionName,
|
||||
mesh.time().constant(),
|
||||
mesh.time(),
|
||||
IOobject::MUST_READ
|
||||
)
|
||||
);
|
||||
|
||||
meshPtr->polyMesh::store();
|
||||
}
|
||||
|
||||
if (!meshPtr)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No mesh region loaded: " << regionName
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return *meshPtr;
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::fvExprDriver::getTypeOfField
|
||||
(
|
||||
const word& fieldName
|
||||
) const
|
||||
{
|
||||
return getHeaderClassName(this->mesh(), fieldName);
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::fvExprDriver::getFieldClassName
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
if (searchInMemory())
|
||||
{
|
||||
const regIOobject* ioptr = this->mesh().findObject<regIOobject>(name);
|
||||
|
||||
if (ioptr)
|
||||
{
|
||||
return ioptr->type();
|
||||
}
|
||||
}
|
||||
|
||||
if (searchOnDisc())
|
||||
{
|
||||
return getHeaderClassName(this->mesh(), name);
|
||||
}
|
||||
|
||||
return word::null;
|
||||
}
|
||||
|
||||
|
||||
Foam::topoSetSource::sourceType
|
||||
Foam::expressions::fvExprDriver::topoSetType(const word& setName) const
|
||||
{
|
||||
IOobject io(topoSet::findIOobject(mesh(), setName));
|
||||
|
||||
if (cellSet::typeName == io.headerClassName())
|
||||
{
|
||||
return topoSetSource::sourceType::CELLSET_SOURCE;
|
||||
}
|
||||
if (faceSet::typeName == io.headerClassName())
|
||||
{
|
||||
return topoSetSource::sourceType::FACESET_SOURCE;
|
||||
}
|
||||
if (pointSet::typeName == io.headerClassName())
|
||||
{
|
||||
return topoSetSource::sourceType::POINTSET_SOURCE;
|
||||
}
|
||||
|
||||
return topoSetSource::sourceType::UNKNOWN_SOURCE;
|
||||
}
|
||||
|
||||
|
||||
Foam::topoSetSource::sourceType
|
||||
Foam::expressions::fvExprDriver::topoZoneType(const word& setName) const
|
||||
{
|
||||
if (mesh().cellZones().findZoneID(setName) >= 0)
|
||||
{
|
||||
return topoSetSource::sourceType::CELLZONE_SOURCE;
|
||||
}
|
||||
|
||||
if (mesh().faceZones().findZoneID(setName) >= 0)
|
||||
{
|
||||
return topoSetSource::sourceType::FACEZONE_SOURCE;
|
||||
}
|
||||
|
||||
if (mesh().pointZones().findZoneID(setName) >= 0)
|
||||
{
|
||||
return topoSetSource::sourceType::POINTZONE_SOURCE;
|
||||
}
|
||||
|
||||
return topoSetSource::sourceType::UNKNOWN_SOURCE;
|
||||
}
|
||||
|
||||
|
||||
Foam::topoSetSource::sourceType
|
||||
Foam::expressions::fvExprDriver::topoSourceType(const word& setName) const
|
||||
{
|
||||
auto setType = topoZoneType(setName);
|
||||
|
||||
if (topoSetSource::sourceType::UNKNOWN_SOURCE == setType)
|
||||
{
|
||||
setType = topoSetType(setName);
|
||||
}
|
||||
|
||||
return setType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isCellSet(const word& setName) const
|
||||
{
|
||||
return
|
||||
(
|
||||
topoSetSource::sourceType::CELLSET_SOURCE
|
||||
== topoSetType(setName)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isFaceSet(const word& setName) const
|
||||
{
|
||||
return
|
||||
(
|
||||
topoSetSource::sourceType::FACESET_SOURCE
|
||||
== topoSetType(setName)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isPointSet(const word& setName) const
|
||||
{
|
||||
return
|
||||
(
|
||||
topoSetSource::sourceType::POINTSET_SOURCE
|
||||
== topoSetType(setName)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isCellZone(const word& name) const
|
||||
{
|
||||
return (mesh().cellZones().findZoneID(name) >= 0);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isFaceZone(const word& name) const
|
||||
{
|
||||
return (mesh().faceZones().findZoneID(name) >= 0);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isPointZone(const word& name) const
|
||||
{
|
||||
return (mesh().pointZones().findZoneID(name) >= 0);
|
||||
}
|
||||
|
||||
|
||||
const Foam::expressions::exprResult&
|
||||
Foam::expressions::fvExprDriver::lookupGlobal
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return exprResultGlobals::New(this->mesh()).get(name, globalScopes_);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::hasDataToWrite() const
|
||||
{
|
||||
return (!storedVariables_.empty() || !delayedVariables_.empty());
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::getData
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
dict.readIfPresent("storedVariables", storedVariables_);
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::prepareData
|
||||
(
|
||||
dictionary& dict
|
||||
) const
|
||||
{
|
||||
auto& driver = const_cast<fvExprDriver&>(*this);
|
||||
|
||||
(void)driver.update();
|
||||
|
||||
if (storedVariables_.size())
|
||||
{
|
||||
driver.updateSpecialVariables(true);
|
||||
|
||||
dict.add("storedVariables", storedVariables_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
646
src/finiteVolume/expressions/base/fvExprDriver.H
Normal file
646
src/finiteVolume/expressions/base/fvExprDriver.H
Normal file
@ -0,0 +1,646 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2010-2018 Bernhard Gschaider
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::expressions::fvExprDriver
|
||||
|
||||
Description
|
||||
Base driver for parsing value expressions associated with an fvMesh.
|
||||
|
||||
Largely based on code and ideas from swak4foam
|
||||
|
||||
Properties
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
variables | List of variables for expressions | no | ()
|
||||
delayedVariables | List of delayed variables | no | ()
|
||||
storedVariables | List of stored variables | no | ()
|
||||
globalScopes | Scopes for global variables | no | ()
|
||||
allowShadowing | Allow variables to shadow field names | no | false
|
||||
\endtable
|
||||
|
||||
Debug Properties
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
debugBaseDriver | Debug level (int) for base driver | no |
|
||||
debugScanner | Add debug for scanner | no | false
|
||||
debugParser | Add debug for parser | no | false
|
||||
\endtable
|
||||
|
||||
SourceFiles
|
||||
fvExprDriverI.H
|
||||
fvExprDriver.C
|
||||
fvExprDriverFields.C
|
||||
fvExprDriverIO.C
|
||||
fvExprDriverNew.C
|
||||
fvExprDriverTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_fvExprDriver_H
|
||||
#define expressions_fvExprDriver_H
|
||||
|
||||
#include "exprDriver.H"
|
||||
#include "exprResultDelayed.H"
|
||||
#include "exprResultStored.H"
|
||||
#include "pointMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "topoSetSource.H"
|
||||
#include "dlLibraryTable.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class exprDriverWriter;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class fvExprDriver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class fvExprDriver
|
||||
:
|
||||
public expressions::exprDriver
|
||||
{
|
||||
// Static Data
|
||||
|
||||
//- Pointer to the "default" mesh
|
||||
static const fvMesh *defaultMeshPtr_;
|
||||
|
||||
//- Cache cellSets, faceSets insted of reading from disc each time
|
||||
static bool cacheSets_;
|
||||
|
||||
|
||||
// Protected Data
|
||||
|
||||
// Stored Data
|
||||
|
||||
//- The scopes for global variables
|
||||
List<word> globalScopes_;
|
||||
|
||||
//- The (delayed) variables table
|
||||
HashTable<exprResultDelayed> delayedVariables_;
|
||||
|
||||
//- Stored expressions. Read from dictionary and updated as required
|
||||
List<exprResultStored> storedVariables_;
|
||||
|
||||
//- Time index when handling special variables
|
||||
label specialVariablesIndex_;
|
||||
|
||||
//- The name of the other mesh (if it is to be required)
|
||||
word otherMeshName_;
|
||||
|
||||
//- Additional libraries
|
||||
dlLibraryTable libs_;
|
||||
|
||||
//- Writing and restoring
|
||||
autoPtr<exprDriverWriter> writer_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Read the IOobject and return the headerClassName
|
||||
static word getHeaderClassName
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& name
|
||||
);
|
||||
|
||||
//- Read the set IOobject and return its headerClassName
|
||||
static word getSetClassName
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& name
|
||||
);
|
||||
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const fvExprDriver&) = delete;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Static Member Functions
|
||||
|
||||
//- Determine mesh or region mesh as specified in the dictionary
|
||||
//- with the keyword "region"
|
||||
static const fvMesh& regionMesh
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh,
|
||||
bool readIfNecessary
|
||||
);
|
||||
|
||||
//- Default boundary type is calculated
|
||||
template<class T>
|
||||
static inline word defaultBoundaryType(const T&)
|
||||
{
|
||||
return "calculated";
|
||||
}
|
||||
|
||||
//- Default boundary type for volume fields is zeroGradient
|
||||
template<class Type>
|
||||
static inline word defaultBoundaryType
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>&
|
||||
)
|
||||
{
|
||||
return "zeroGradient";
|
||||
}
|
||||
|
||||
|
||||
//- Apply correctBoundaryConditions (volume fields only)
|
||||
template<class T>
|
||||
static inline void correctField(T&) {}
|
||||
|
||||
template<class Type>
|
||||
static inline void correctField
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>& fld
|
||||
)
|
||||
{
|
||||
fld.correctBoundaryConditions();
|
||||
}
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
// Mesh related
|
||||
|
||||
//- The mesh we are attached to
|
||||
virtual const fvMesh& mesh() const = 0;
|
||||
|
||||
|
||||
// Variables
|
||||
|
||||
//- Define scopes for global variables
|
||||
void setGlobalScopes(const wordUList& scopes)
|
||||
{
|
||||
globalScopes_ = scopes;
|
||||
}
|
||||
|
||||
//- Non-const access to the named variable (sub-classes only)
|
||||
inline virtual exprResult& variable(const word& name);
|
||||
|
||||
//- Test existence of a global variable
|
||||
template<class T>
|
||||
bool isGlobalVariable
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label expectedSize = -1
|
||||
) const;
|
||||
|
||||
//- Return the global variable if available or a null result
|
||||
const exprResult& lookupGlobal(const word& name) const;
|
||||
|
||||
|
||||
// Fields
|
||||
|
||||
//- Test for the existence of a mesh field
|
||||
template<class Type>
|
||||
bool isField
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal = false,
|
||||
label expectSize = -1 //!< ignored
|
||||
) const;
|
||||
|
||||
|
||||
//- Retrieve field from memory or disk
|
||||
template<class GeomField>
|
||||
inline tmp<GeomField> getOrReadField
|
||||
(
|
||||
const word& name,
|
||||
bool mandatory = true,
|
||||
bool getOldTime = false
|
||||
);
|
||||
|
||||
//- Retrieve point field from memory or disk
|
||||
template<class GeomField>
|
||||
inline tmp<GeomField> getOrReadPointField
|
||||
(
|
||||
const word& name,
|
||||
bool mandatory = true,
|
||||
bool getOldTime = false
|
||||
);
|
||||
|
||||
//- Retrieve field from memory or disk (implementation)
|
||||
template<class GeomField, class MeshRef>
|
||||
tmp<GeomField> getOrReadFieldImpl
|
||||
(
|
||||
const word& name,
|
||||
const MeshRef& meshRef,
|
||||
bool mandatory = true,
|
||||
bool getOldTime = false
|
||||
);
|
||||
|
||||
//- Helper function for getOrReadField
|
||||
template<class GeomField, class MeshRef>
|
||||
inline tmp<GeomField> readAndRegister
|
||||
(
|
||||
const word& name,
|
||||
const MeshRef& meshRef
|
||||
);
|
||||
|
||||
//- Create a random field
|
||||
//
|
||||
// \param field the field to populate
|
||||
// \param seed the seed value. If zero or negative, use as an offset
|
||||
// to the current timeIndex
|
||||
// \param gaussian generate a Gaussian distribution
|
||||
void fill_random
|
||||
(
|
||||
scalarField& field,
|
||||
label seed = 0,
|
||||
const bool gaussian = false
|
||||
) const;
|
||||
|
||||
|
||||
// Sets
|
||||
|
||||
//- The origin of the topoSet
|
||||
enum SetOrigin { INVALID = 0, NEW, FILE, MEMORY, CACHE };
|
||||
|
||||
//- Get topoSet
|
||||
template<class T>
|
||||
autoPtr<T> getTopoSet
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& setName,
|
||||
SetOrigin& origin
|
||||
) const;
|
||||
|
||||
//- Update topoSet
|
||||
template<class T>
|
||||
inline bool updateSet
|
||||
(
|
||||
autoPtr<T>& setPtr,
|
||||
const word& setName,
|
||||
SetOrigin origin
|
||||
) const;
|
||||
|
||||
|
||||
// Updating
|
||||
|
||||
//- Examine current variable values and update stored variables
|
||||
virtual void updateSpecialVariables(bool force=false);
|
||||
|
||||
//- Do we need a data file to be written
|
||||
virtual bool hasDataToWrite() const;
|
||||
|
||||
//- Prepare/update special variables and add to dictionary,
|
||||
//- normally via the reader/writer
|
||||
virtual void prepareData(dictionary& dict) const;
|
||||
|
||||
//- Read data from dictionary, normally via the reader/writer
|
||||
virtual void getData(const dictionary& dict);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Friends
|
||||
friend class exprDriverWriter;
|
||||
|
||||
|
||||
// Static Member Functions
|
||||
|
||||
//- Get the default mesh, if one is defined
|
||||
static const fvMesh& defaultMesh();
|
||||
|
||||
//- Set the default mesh (if not already set)
|
||||
static const fvMesh* resetDefaultMesh
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const bool force = false //!< Force reset, even if already set
|
||||
);
|
||||
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("fvExprDriver");
|
||||
|
||||
|
||||
// Run-time selection
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
fvExprDriver,
|
||||
dictionary,
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh
|
||||
),
|
||||
(dict,mesh)
|
||||
);
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
fvExprDriver,
|
||||
idName,
|
||||
(
|
||||
const word& ident,
|
||||
const fvMesh& mesh
|
||||
),
|
||||
(ident, mesh)
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Null constructor, and null construct with search preferences
|
||||
explicit fvExprDriver
|
||||
(
|
||||
bool cacheReadFields = false,
|
||||
bool searchInMemory = true,
|
||||
bool searchOnDisc = false,
|
||||
const dictionary& dict = dictionary::null
|
||||
);
|
||||
|
||||
//- Copy construct
|
||||
fvExprDriver(const fvExprDriver&);
|
||||
|
||||
//- Construct from a dictionary
|
||||
explicit fvExprDriver(const dictionary& dict);
|
||||
|
||||
|
||||
//- Return a reference to the selected value driver
|
||||
static autoPtr<fvExprDriver> New
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh
|
||||
);
|
||||
|
||||
//- Return a reference to the selected value driver
|
||||
static autoPtr<fvExprDriver> New
|
||||
(
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
//- Return a reference to the selected value driver
|
||||
static autoPtr<fvExprDriver> New
|
||||
(
|
||||
const word& type,
|
||||
const word& id,
|
||||
const fvMesh& mesh
|
||||
);
|
||||
|
||||
//- Clone
|
||||
virtual autoPtr<fvExprDriver> clone() const = 0;
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~fvExprDriver();
|
||||
|
||||
|
||||
// Public Member Functions
|
||||
|
||||
//- The underlying field size for the expression
|
||||
virtual label size() const = 0;
|
||||
|
||||
//- The underlying point field size for the expression
|
||||
virtual label pointSize() const = 0;
|
||||
|
||||
|
||||
// Mesh Related
|
||||
|
||||
//- The Time associated with the mesh
|
||||
const Time& runTime() const;
|
||||
|
||||
//- The current time name
|
||||
virtual word timeName() const;
|
||||
|
||||
//- The current time value
|
||||
virtual scalar timeValue() const;
|
||||
|
||||
|
||||
// General Controls
|
||||
|
||||
//- Status of cache-sets (static variable)
|
||||
bool cacheSets() const { return cacheSets_; }
|
||||
|
||||
|
||||
// Variables
|
||||
|
||||
//- Clear temporary variables and resets from expression strings
|
||||
virtual void clearVariables();
|
||||
|
||||
//- True if named variable exists
|
||||
inline virtual bool hasVariable(const word& name) const;
|
||||
|
||||
//- Return const-access to the named variable
|
||||
inline virtual const exprResult& variable(const word& name) const;
|
||||
|
||||
//- Test for existence of a local/global variable or a field
|
||||
template<class Type>
|
||||
inline bool isVariableOrField
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal = false,
|
||||
label expectSize = -1
|
||||
) const;
|
||||
|
||||
//- Retrieve local/global variable as a tmp field
|
||||
//
|
||||
// \param name The name of the local/global field
|
||||
// \param expectSize The size check on the variable, -1 to ignore
|
||||
// \param mandatory A missing variable is Fatal, or return
|
||||
// an invalid tmp
|
||||
template<class Type>
|
||||
tmp<Field<Type>> getVariable
|
||||
(
|
||||
const word& name,
|
||||
label expectSize,
|
||||
const bool mandatory = true
|
||||
) const;
|
||||
|
||||
|
||||
//- Lookup the field class name (memory or read from disk)
|
||||
//
|
||||
// Return empty if the name cannot be resolved.
|
||||
word getFieldClassName(const word& name) const;
|
||||
|
||||
|
||||
// Types
|
||||
|
||||
//- Return cell/face/point set type or unknown
|
||||
topoSetSource::sourceType topoSetType(const word& name) const;
|
||||
|
||||
//- Return cell/face/point zone type or unknown
|
||||
topoSetSource::sourceType topoZoneType(const word& name) const;
|
||||
|
||||
//- Return cell/face/point zone/set type or unknown
|
||||
topoSetSource::sourceType topoSourceType(const word& name) const;
|
||||
|
||||
//- Read and return labels associated with the topo set
|
||||
labelList getTopoSetLabels
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const;
|
||||
|
||||
//- Test if name is a known cellZone
|
||||
bool isCellZone(const word& name) const;
|
||||
|
||||
//- Test if name is a known faceZone
|
||||
bool isFaceZone(const word& name) const;
|
||||
|
||||
//- Test if name is a known pointZone
|
||||
bool isPointZone(const word& name) const;
|
||||
|
||||
//- Test if name is a known cellSet
|
||||
bool isCellSet(const word& name) const;
|
||||
|
||||
//- Test if name is a known faceSet
|
||||
bool isFaceSet(const word& name) const;
|
||||
|
||||
//- Test if name is a known pointSet
|
||||
bool isPointSet(const word& name) const;
|
||||
|
||||
|
||||
// Evaluation
|
||||
|
||||
//- Evaluate the expression
|
||||
//- and save as the specified named variable
|
||||
virtual void evaluateVariable
|
||||
(
|
||||
const word& varName,
|
||||
const expressions::exprString& expr
|
||||
);
|
||||
|
||||
//- Evaluate an expression on a remote
|
||||
//- and save as the specified named variable
|
||||
//
|
||||
// The fully qualified form of the remote is given as follows
|
||||
// \verbatim
|
||||
// type'name/region
|
||||
// \endverbatim
|
||||
//
|
||||
// If not specified, the default type is "patch", which means the
|
||||
// following are equivalent
|
||||
// \verbatim
|
||||
// patch'name/region
|
||||
// name/region
|
||||
// \endverbatim
|
||||
//
|
||||
// If region is identical to the current region, it can be omitted:
|
||||
// \verbatim
|
||||
// patch'name
|
||||
// name (default is patch)
|
||||
// \endverbatim
|
||||
virtual void evaluateVariableRemote
|
||||
(
|
||||
string remote,
|
||||
const word& varName,
|
||||
const expressions::exprString& expr
|
||||
);
|
||||
|
||||
|
||||
// Fields
|
||||
|
||||
//- Test existence of a local/global variable
|
||||
template<class Type>
|
||||
inline bool isVariable
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal = false,
|
||||
label expectSize = -1
|
||||
) const;
|
||||
|
||||
//- Test if specified field can be found in memory or disk
|
||||
template<class Type>
|
||||
bool foundField(const word& name) const;
|
||||
|
||||
//- Read the IOobject for fieldName and return its headerClassName
|
||||
// Empty if the field could not be found.
|
||||
word getTypeOfField(const word& fieldName) const;
|
||||
|
||||
|
||||
// Handling remote data (future)
|
||||
|
||||
// //- Access the other mesh name (future)
|
||||
// const word& otherMeshName() const { return otherMeshName_; }
|
||||
//
|
||||
// //- Access the other mesh name (future)
|
||||
// word& otherMeshName() { return otherMeshName_; }
|
||||
|
||||
|
||||
// Reading
|
||||
|
||||
//- Read variables, tables etc.
|
||||
// Also usable for objects not constructed from a dictionary.
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
|
||||
// Writing
|
||||
|
||||
//- Write "variables", "storedVariables", "delayedVariables",
|
||||
//- "globalScopes" if they are present.
|
||||
Ostream& writeCommon(Ostream& os, bool debug=false) const;
|
||||
|
||||
//- Create a writer for this object
|
||||
void createWriterAndRead(const word& name);
|
||||
|
||||
//- Write data if apropriate
|
||||
//- Should enable exact restarts
|
||||
void tryWrite() const;
|
||||
|
||||
|
||||
// Plugins (future)
|
||||
|
||||
/// //- Tests for a plugin-function
|
||||
/// virtual bool hasPlugin(const word& name) = 0;
|
||||
///
|
||||
/// //- Return a new plugin-function
|
||||
/// virtual autoPtr<CommonPluginFunction>
|
||||
/// getPlugin(const word& name) = 0;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "fvExprDriverI.H"
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "fvExprDriverTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
49
src/finiteVolume/expressions/base/fvExprDriverFields.C
Normal file
49
src/finiteVolume/expressions/base/fvExprDriverFields.C
Normal file
@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvExprDriver.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::expressions::fvExprDriver::fill_random
|
||||
(
|
||||
scalarField& field,
|
||||
label seed,
|
||||
const bool gaussian
|
||||
) const
|
||||
{
|
||||
exprDriver::fill_random
|
||||
(
|
||||
field, (seed <= 0 ? (runTime().timeIndex() - seed) : seed),
|
||||
gaussian
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
179
src/finiteVolume/expressions/base/fvExprDriverI.H
Normal file
179
src/finiteVolume/expressions/base/fvExprDriverI.H
Normal file
@ -0,0 +1,179 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline bool Foam::expressions::fvExprDriver::hasVariable
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return delayedVariables_.found(name) || variables_.found(name);
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::expressions::exprResult&
|
||||
Foam::expressions::fvExprDriver::variable
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
if (delayedVariables_.found(name))
|
||||
{
|
||||
return delayedVariables_[name];
|
||||
}
|
||||
|
||||
return variables_[name];
|
||||
}
|
||||
|
||||
|
||||
inline Foam::expressions::exprResult&
|
||||
Foam::expressions::fvExprDriver::variable
|
||||
(
|
||||
const word& name
|
||||
)
|
||||
{
|
||||
if (delayedVariables_.found(name))
|
||||
{
|
||||
return delayedVariables_[name];
|
||||
}
|
||||
|
||||
return variables_[name];
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
inline bool Foam::expressions::fvExprDriver::isVariable
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label expectedSize
|
||||
) const
|
||||
{
|
||||
return
|
||||
(
|
||||
this->isLocalVariable<Type>(name, isPointVal, expectedSize)
|
||||
|| this->isGlobalVariable<Type>(name, isPointVal, expectedSize)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
inline bool Foam::expressions::fvExprDriver::isVariableOrField
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label expectedSize
|
||||
)
|
||||
const
|
||||
{
|
||||
return
|
||||
(
|
||||
this->isVariable<Type>(name, isPointVal, expectedSize)
|
||||
|| this->isField<Type>(name, isPointVal)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField>
|
||||
inline Foam::tmp<GeomField>
|
||||
Foam::expressions::fvExprDriver::getOrReadField
|
||||
(
|
||||
const word& name,
|
||||
bool mandatory,
|
||||
bool getOldTime
|
||||
)
|
||||
{
|
||||
return this->getOrReadFieldImpl<GeomField>
|
||||
(
|
||||
name,
|
||||
this->mesh(),
|
||||
mandatory,
|
||||
getOldTime
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField>
|
||||
inline Foam::tmp<GeomField>
|
||||
Foam::expressions::fvExprDriver::getOrReadPointField
|
||||
(
|
||||
const word& name,
|
||||
bool mandatory,
|
||||
bool getOldTime
|
||||
)
|
||||
{
|
||||
return this->getOrReadFieldImpl<GeomField>
|
||||
(
|
||||
name,
|
||||
pointMesh::New(this->mesh()),
|
||||
mandatory,
|
||||
getOldTime
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField, class Mesh>
|
||||
inline Foam::tmp<GeomField>
|
||||
Foam::expressions::fvExprDriver::readAndRegister
|
||||
(
|
||||
const word& name,
|
||||
const Mesh& meshRef
|
||||
)
|
||||
{
|
||||
GeomField* ptr = new GeomField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
name,
|
||||
meshRef.thisDb().time().timeName(),
|
||||
meshRef.thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Unregistered
|
||||
),
|
||||
meshRef
|
||||
);
|
||||
|
||||
if (cacheReadFields())
|
||||
{
|
||||
DebugInfo
|
||||
<< "Registering a copy of " << name << " with mesh" << nl;
|
||||
|
||||
// This is clunky
|
||||
ptr->checkIn();
|
||||
return tmp<GeomField>(regIOobject::store(ptr));
|
||||
}
|
||||
|
||||
return tmp<GeomField>(ptr);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
280
src/finiteVolume/expressions/base/fvExprDriverIO.C
Normal file
280
src/finiteVolume/expressions/base/fvExprDriverIO.C
Normal file
@ -0,0 +1,280 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvExprDriver.H"
|
||||
#include "exprDriverWriter.H"
|
||||
#include "cellSet.H"
|
||||
#include "faceSet.H"
|
||||
#include "pointSet.H"
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const
|
||||
{
|
||||
// Zones first - they are cheap to handle (no IO)
|
||||
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::CELLZONE_SOURCE:
|
||||
{
|
||||
const auto& zones = mesh().cellZones();
|
||||
const word& zoneTypeName = cellZone::typeName;
|
||||
|
||||
const label zoneID = zones.findZoneID(name);
|
||||
if (zoneID < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No " << zoneTypeName << " named "
|
||||
<< name << "found. Has zones: " << zones.names() << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return zones[zoneID];
|
||||
break;
|
||||
}
|
||||
|
||||
case topoSetSource::sourceType::FACEZONE_SOURCE:
|
||||
{
|
||||
const auto& zones = mesh().faceZones();
|
||||
const word& zoneTypeName = faceZone::typeName;
|
||||
|
||||
const label zoneID = zones.findZoneID(name);
|
||||
if (zoneID < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No " << zoneTypeName << " named "
|
||||
<< name << "found. Has zones: " << zones.names() << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return zones[zoneID];
|
||||
break;
|
||||
}
|
||||
|
||||
case topoSetSource::sourceType::POINTZONE_SOURCE:
|
||||
{
|
||||
const auto& zones = mesh().pointZones();
|
||||
const word& zoneTypeName = pointZone::typeName;
|
||||
|
||||
const label zoneID = zones.findZoneID(name);
|
||||
if (zoneID < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No " << zoneTypeName << " named "
|
||||
<< name << "found. Has zones: " << zones.names() << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return zones[zoneID];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
IOobject io(topoSet::findIOobject(mesh(), name));
|
||||
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::CELLSET_SOURCE:
|
||||
{
|
||||
typedef cellSet classType;
|
||||
|
||||
if (classType::typeName != io.headerClassName())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Error reading " << classType::typeName
|
||||
<< " <" << name << "> : found "
|
||||
<< io.headerClassName() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
classType set(io);
|
||||
return set.sortedToc();
|
||||
break;
|
||||
}
|
||||
|
||||
case topoSetSource::sourceType::FACESET_SOURCE:
|
||||
{
|
||||
typedef faceSet classType;
|
||||
|
||||
if (classType::typeName != io.headerClassName())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Error reading " << classType::typeName
|
||||
<< " <" << name << "> : found "
|
||||
<< io.headerClassName() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
classType set(io);
|
||||
return set.sortedToc();
|
||||
break;
|
||||
}
|
||||
|
||||
case topoSetSource::sourceType::POINTSET_SOURCE:
|
||||
{
|
||||
typedef pointSet classType;
|
||||
|
||||
if (classType::typeName != io.headerClassName())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Error reading " << classType::typeName
|
||||
<< " <" << name << "> : found "
|
||||
<< io.headerClassName() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
classType set(io);
|
||||
return set.sortedToc();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unexpected sourceType: " << int(setType) << nl
|
||||
<< " for set <" << name << ">" << nl
|
||||
<< exit(FatalError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return labelList::null();
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::fvExprDriver::getHeaderClassName
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& name
|
||||
)
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
name,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
io.typeHeaderOk<IOobject>(false);
|
||||
|
||||
DebugInfo
|
||||
<< "Registry: " << mesh.path()
|
||||
<< " Name: " << name
|
||||
<< " Time: " << mesh.time().timeName()
|
||||
<< " Path: " << io.localFilePath(io.headerClassName())
|
||||
<< " Class: " << io.headerClassName() << endl;
|
||||
|
||||
return io.headerClassName();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Ostream& Foam::expressions::fvExprDriver::writeCommon
|
||||
(
|
||||
Ostream& os,
|
||||
bool debug
|
||||
) const
|
||||
{
|
||||
// Write "variables", even if empty
|
||||
writeVariableStrings(os, "variables");
|
||||
|
||||
if (debug)
|
||||
{
|
||||
os.writeEntry("variableValues", variables_);
|
||||
}
|
||||
|
||||
if (!storedVariables_.empty() || !delayedVariables_.empty())
|
||||
{
|
||||
const_cast<fvExprDriver&>
|
||||
(
|
||||
*this
|
||||
).updateSpecialVariables(true);
|
||||
}
|
||||
|
||||
if (!storedVariables_.empty())
|
||||
{
|
||||
os.writeEntry("storedVariables", storedVariables_);
|
||||
}
|
||||
|
||||
if (!delayedVariables_.empty())
|
||||
{
|
||||
List<exprResultDelayed> list(delayedVariables_.size());
|
||||
|
||||
auto outIter = list.begin();
|
||||
|
||||
forAllConstIters(delayedVariables_, iter)
|
||||
{
|
||||
*outIter = *iter;
|
||||
++outIter;
|
||||
}
|
||||
|
||||
os.writeEntry("delayedVariables", list);
|
||||
}
|
||||
|
||||
if (!globalScopes_.empty())
|
||||
{
|
||||
os.writeEntry("globalScopes", globalScopes_);
|
||||
}
|
||||
|
||||
// writeTable(os, "timelines", lines_);
|
||||
// writeTable(os, "lookuptables", lookup_);
|
||||
// writeTable(os, "lookuptables2D", lookup2D_);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::createWriterAndRead(const word& name)
|
||||
{
|
||||
if (hasDataToWrite() && !writer_.valid())
|
||||
{
|
||||
writer_.set(new exprDriverWriter(name + "_" + this->type(), *this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::tryWrite() const
|
||||
{
|
||||
if (writer_.valid() && mesh().time().outputTime())
|
||||
{
|
||||
writer_->write();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
105
src/finiteVolume/expressions/base/fvExprDriverNew.C
Normal file
105
src/finiteVolume/expressions/base/fvExprDriverNew.C
Normal file
@ -0,0 +1,105 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvExprDriver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::expressions::fvExprDriver>
|
||||
Foam::expressions::fvExprDriver::New
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
return fvExprDriver::New
|
||||
(
|
||||
dict,
|
||||
defaultMesh()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::expressions::fvExprDriver>
|
||||
Foam::expressions::fvExprDriver::New
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh
|
||||
)
|
||||
{
|
||||
const word driverType(dict.get<word>("valueType"));
|
||||
|
||||
auto cstrIter = dictionaryConstructorTablePtr_->cfind(driverType);
|
||||
|
||||
if (!cstrIter.found())
|
||||
{
|
||||
FatalIOErrorInLookup
|
||||
(
|
||||
dict,
|
||||
"valueType",
|
||||
driverType,
|
||||
*dictionaryConstructorTablePtr_
|
||||
) << exit(FatalIOError);
|
||||
}
|
||||
|
||||
DebugInFunction << "Creating driver of type " << driverType << endl;
|
||||
|
||||
resetDefaultMesh(mesh, false); // lazy
|
||||
|
||||
return autoPtr<fvExprDriver>(cstrIter()(dict, mesh));
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::expressions::fvExprDriver>
|
||||
Foam::expressions::fvExprDriver::New
|
||||
(
|
||||
const word& driverType,
|
||||
const word& id,
|
||||
const fvMesh& mesh
|
||||
)
|
||||
{
|
||||
auto cstrIter = idNameConstructorTablePtr_->cfind(driverType);
|
||||
|
||||
if (!cstrIter.found())
|
||||
{
|
||||
FatalErrorInLookup
|
||||
(
|
||||
"valueType",
|
||||
driverType,
|
||||
*idNameConstructorTablePtr_
|
||||
) << exit(FatalError);
|
||||
}
|
||||
|
||||
DebugInFunction << "Creating driver of type " << driverType << endl;
|
||||
|
||||
resetDefaultMesh(mesh, false); // lazy
|
||||
|
||||
return autoPtr<fvExprDriver>(cstrIter()(id, mesh));
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
627
src/finiteVolume/expressions/base/fvExprDriverTemplates.C
Normal file
627
src/finiteVolume/expressions/base/fvExprDriverTemplates.C
Normal file
@ -0,0 +1,627 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "surfaceMesh.H"
|
||||
#include "fvsPatchField.H"
|
||||
#include "pointPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
bool Foam::expressions::fvExprDriver::isGlobalVariable
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label expectedSize
|
||||
) const
|
||||
{
|
||||
DebugInfo
|
||||
<< "Looking for global" << (isPointVal ? " point" : "")
|
||||
<< " field name:" << name;
|
||||
|
||||
const exprResult& result = lookupGlobal(name);
|
||||
|
||||
DebugInfo
|
||||
<< " - found (" << result.valueType() << ' ' << result.isPointValue() << ')';
|
||||
|
||||
|
||||
bool good = (result.isType<Type>() && result.isPointValue(isPointVal));
|
||||
|
||||
// Do size checking if requested
|
||||
if (good && expectedSize >= 0)
|
||||
{
|
||||
good = (result.size() == expectedSize);
|
||||
reduce(good, andOp<bool>());
|
||||
|
||||
if (debug && !good)
|
||||
{
|
||||
Info<< " size is";
|
||||
}
|
||||
}
|
||||
|
||||
DebugInfo << (good ? " good" : " bad") << endl;
|
||||
|
||||
return good;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::expressions::fvExprDriver::getVariable
|
||||
(
|
||||
const word& name,
|
||||
label expectedSize,
|
||||
const bool mandatory
|
||||
) const
|
||||
{
|
||||
tmp<Field<Type>> tresult;
|
||||
|
||||
bool isSingleValue = false;
|
||||
|
||||
if (hasVariable(name) && variable(name).isType<Type>())
|
||||
{
|
||||
isSingleValue = variable(name).isUniform();
|
||||
tresult = variable(name).cref<Type>().clone();
|
||||
}
|
||||
else if (isGlobalVariable<Type>(name, false))
|
||||
{
|
||||
const exprResult& var = lookupGlobal(name);
|
||||
|
||||
isSingleValue = var.isUniform();
|
||||
|
||||
tresult = var.cref<Type>().clone();
|
||||
}
|
||||
|
||||
if (tresult.valid())
|
||||
{
|
||||
if
|
||||
(
|
||||
expectedSize < 0
|
||||
|| returnReduce((tresult->size() == expectedSize), andOp<bool>())
|
||||
)
|
||||
{
|
||||
return tresult;
|
||||
}
|
||||
|
||||
if (!isSingleValue)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Variable " << name
|
||||
<< " is not a single value and does not fit the size "
|
||||
<< expectedSize << ". Using average" << endl;
|
||||
}
|
||||
|
||||
return tmp<Field<Type>>::New(expectedSize, gAverage(tresult()));
|
||||
}
|
||||
|
||||
if (mandatory)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Variable (" << name << ") not found." << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::expressions::fvExprDriver::foundField
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "fvExprDriver::foundField. Name: " << name
|
||||
<< " Type: " << Type::typeName
|
||||
<< " search memory:" << searchInMemory()
|
||||
<< " disc:" << searchOnDisc() << endl;
|
||||
}
|
||||
|
||||
// if (std::is_void<Type>::value) ...
|
||||
|
||||
if (searchInMemory())
|
||||
{
|
||||
const regIOobject* ioptr =
|
||||
this->mesh().findObject<regIOobject>(name);
|
||||
|
||||
if (this->mesh().foundObject<Type>(name))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Found " << name << " in memory" << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "No " << name << " of type " << Type::typeName
|
||||
<< " found in memory";
|
||||
|
||||
if (ioptr)
|
||||
{
|
||||
Info<< " but of type " << ioptr->headerClassName();
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (searchOnDisc() && getTypeOfField(name) == Type::typeName)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Found " << name << " on disc" << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< name << " not found" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::expressions::fvExprDriver::isField
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label
|
||||
) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "fvExprDriver::isField <" << name << '>' << endl;
|
||||
}
|
||||
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> vfieldType;
|
||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sfieldType;
|
||||
typedef GeometricField<Type, pointPatchField, pointMesh> pfieldType;
|
||||
|
||||
return
|
||||
(
|
||||
isPointVal
|
||||
? this->foundField<pfieldType>(name)
|
||||
:
|
||||
(
|
||||
this->foundField<vfieldType>(name)
|
||||
|| this->foundField<sfieldType>(name)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField, class Mesh>
|
||||
Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
|
||||
(
|
||||
const word& name,
|
||||
const Mesh& meshRef,
|
||||
bool mandatory,
|
||||
bool getOldTime
|
||||
)
|
||||
{
|
||||
typedef typename GeomField::value_type Type;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "fvExprDriver::getOrReadField <" << name
|
||||
<< "> Type: " << GeomField::typeName << endl;
|
||||
}
|
||||
|
||||
tmp<GeomField> tfield;
|
||||
|
||||
if
|
||||
(
|
||||
(hasVariable(name) && variable(name).isType<Type>())
|
||||
|| isGlobalVariable<Type>(name, false)
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting " << name << " from variables" << endl;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Creating field " << name << " of type "
|
||||
<< GeomField::typeName << nl;
|
||||
}
|
||||
|
||||
tfield.reset
|
||||
(
|
||||
GeomField::New(name, meshRef, dimensioned<Type>(Zero))
|
||||
);
|
||||
|
||||
GeomField& fld = tfield.ref();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "New field: " << name << " ownedByRegistry"
|
||||
<< fld.ownedByRegistry() << endl;
|
||||
}
|
||||
|
||||
Field<Type> vals;
|
||||
|
||||
if (hasVariable(name) && variable(name).isType<Type>())
|
||||
{
|
||||
vals = variable(name).cref<Type>();
|
||||
}
|
||||
else
|
||||
{
|
||||
vals = lookupGlobal(name).cref<Type>();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "sizes: " << vals.size() << ' ' << fld.size() << endl;
|
||||
}
|
||||
|
||||
if (returnReduce((vals.size() == fld.size()), andOp<bool>()))
|
||||
{
|
||||
fld.primitiveFieldRef() = vals;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type avg = gAverage(vals);
|
||||
|
||||
bool noWarn = false;
|
||||
|
||||
if (!noWarn)
|
||||
{
|
||||
MinMax<Type> range = gMinMax(vals);
|
||||
|
||||
if (range.mag() > SMALL)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "The min/max ranges differ " << range
|
||||
<< " - using average " << avg << nl;
|
||||
}
|
||||
}
|
||||
|
||||
fld.primitiveFieldRef() = avg;
|
||||
}
|
||||
|
||||
correctField(fld);
|
||||
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
const objectRegistry& obr = meshRef.thisDb();
|
||||
|
||||
if (searchInMemory() && obr.foundObject<GeomField>(name))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting " << name << " from memory" << endl;
|
||||
}
|
||||
|
||||
const GeomField& origFld = obr.lookupObject<GeomField>(name);
|
||||
|
||||
// Avoid shadowing the original object
|
||||
|
||||
tfield.reset
|
||||
(
|
||||
GeomField::New(name + "_exprDriverCopy", origFld)
|
||||
);
|
||||
|
||||
if (getOldTime)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting oldTime of " << name << " has "
|
||||
<< origFld.nOldTimes() << endl;
|
||||
}
|
||||
|
||||
if (!origFld.nOldTimes() && this->prevIterIsOldTime())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "No oldTime, using previous iteration" << endl;
|
||||
}
|
||||
tfield.ref().oldTime() = origFld.prevIter();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (searchOnDisc() && getTypeOfField(name) == GeomField::typeName)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Reading " << name << " from disc" << endl;
|
||||
}
|
||||
|
||||
tfield.reset
|
||||
(
|
||||
this->readAndRegister<GeomField>(name, meshRef)
|
||||
);
|
||||
// oldTime automatically read
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "field: valid()=" << tfield.valid() << endl;
|
||||
}
|
||||
|
||||
if (tfield.valid())
|
||||
{
|
||||
GeomField& fld = tfield.ref();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Valid " << name << " found. Removing dimensions" << nl;
|
||||
}
|
||||
|
||||
fld.dimensions().clear();
|
||||
|
||||
if (fld.nOldTimes())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Removing dimensions of oldTime of " << name
|
||||
<< " has " << fld.nOldTimes() << nl;
|
||||
}
|
||||
|
||||
// Switch dimension checking off
|
||||
const int oldDebug = dimensionSet::debug;
|
||||
dimensionSet::debug = 0;
|
||||
|
||||
// go through ALL old times
|
||||
GeomField* fp = &(fld);
|
||||
|
||||
while (fp->nOldTimes())
|
||||
{
|
||||
fp = &(fp->oldTime());
|
||||
fp->dimensions().clear();
|
||||
}
|
||||
|
||||
// Restore old value of dimension checking
|
||||
dimensionSet::debug = oldDebug;
|
||||
}
|
||||
}
|
||||
else if (mandatory)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Could not find field " << name
|
||||
<< " in memory or on disc" << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::autoPtr<T> Foam::expressions::fvExprDriver::getTopoSet
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& name,
|
||||
SetOrigin& origin
|
||||
) const
|
||||
{
|
||||
// Avoid possible name clashes
|
||||
const word regName = name + "RegisteredNameFor" + T::typeName;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Looking for " << T::typeName << " named " << name;
|
||||
|
||||
Info<< " or registered as " << regName << " with mesh "
|
||||
<< "Caching:" << cacheSets()
|
||||
<< " Found:" << (mesh.foundObject<T>(name))
|
||||
<< " Found registered:" << mesh.foundObject<T>(regName)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
origin = SetOrigin::INVALID;
|
||||
autoPtr<T> setPtr;
|
||||
|
||||
if
|
||||
(
|
||||
!cacheSets()
|
||||
||
|
||||
(
|
||||
!mesh.thisDb().foundObject<T>(regName)
|
||||
&& !mesh.thisDb().foundObject<T>(name)
|
||||
)
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Constructing new " << T::typeName << ' ' << name << nl;
|
||||
|
||||
if (debug > 1)
|
||||
{
|
||||
Pout<< mesh.thisDb().names();
|
||||
}
|
||||
}
|
||||
|
||||
origin = SetOrigin::FILE;
|
||||
setPtr.reset(new T(mesh, name, IOobject::MUST_READ));
|
||||
|
||||
if (cacheSets())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Registering a copy of " << name << " with mesh" << nl;
|
||||
}
|
||||
|
||||
autoPtr<T> toCache(new T(mesh, regName, *setPtr));
|
||||
toCache->store(toCache);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const T* ptr = mesh.thisDb().findObject<T>(name);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting existing " << name << endl;
|
||||
}
|
||||
|
||||
origin = SetOrigin::MEMORY;
|
||||
setPtr.reset(new T(mesh, name, *ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting existing " << regName << endl;
|
||||
}
|
||||
|
||||
origin = SetOrigin::CACHE;
|
||||
setPtr.reset(new T(mesh, name, mesh.lookupObject<T>(regName)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return setPtr;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Foam::expressions::fvExprDriver::updateSet
|
||||
(
|
||||
autoPtr<T>& setPtr,
|
||||
const word& name,
|
||||
SetOrigin origin
|
||||
) const
|
||||
{
|
||||
const label oldSize = setPtr->size();
|
||||
|
||||
bool updated = false;
|
||||
const polyMesh& mesh = dynamic_cast<const polyMesh&>(setPtr->db());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "UpdateSet: " << setPtr->name() << " Id: " << name
|
||||
<< " Origin: " << int(origin) << endl;
|
||||
}
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
case SetOrigin::FILE:
|
||||
{
|
||||
IOobject header
|
||||
(
|
||||
name,
|
||||
mesh.time().timeName(),
|
||||
polyMesh::meshSubDir/"sets",
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (header.typeHeaderOk<T>())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Rereading from "
|
||||
<< header.localFilePath(T::typeName) << endl;
|
||||
}
|
||||
setPtr.reset(new T(header));
|
||||
updated = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SetOrigin::NEW:
|
||||
case SetOrigin::MEMORY:
|
||||
case SetOrigin::CACHE:
|
||||
{
|
||||
if (origin == SetOrigin::NEW)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "State NEW shouldn't exist"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
word sName = name;
|
||||
|
||||
const T* ptr = mesh.thisDb().findObject<T>(name);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Found " << name
|
||||
<< " and rereading it" << endl;
|
||||
}
|
||||
|
||||
setPtr.reset(new T(mesh, name, *ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< name << " Not found" << endl
|
||||
<< "In registry: " << mesh.thisDb().names() << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
updated = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case INVALID:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< T::typeName << ' ' << name << " is invalid" << endl
|
||||
<< exit(FatalError);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Origin " << int(origin) << " not implemented" << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< name << " old size " << oldSize << " new: "
|
||||
<< setPtr->size() << endl;
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user