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/volFields/volFields.C
|
||||||
fields/surfaceFields/surfaceFields.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/fvMatrices.C
|
||||||
fvMatrices/fvScalarMatrix/fvScalarMatrix.C
|
fvMatrices/fvScalarMatrix/fvScalarMatrix.C
|
||||||
fvMatrices/solvers/MULES/MULES.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