ENH: base driver for expressions

This commit is contained in:
Mark Olesen
2019-12-03 12:34:33 +01:00
parent d7aac83971
commit 17f5560cb9
8 changed files with 1650 additions and 0 deletions

View File

@ -154,6 +154,11 @@ $(expr)/exprResult/exprResultStoredStack.C
$(expr)/exprString/exprString.C
$(expr)/exprTools/exprTools.C
$(expr)/exprDriver/exprDriver.C
$(expr)/exprDriver/exprDriverFields.C
$(expr)/exprDriver/exprDriverIO.C
ops = primitives/ops
$(ops)/flipOp.C

View File

@ -0,0 +1,404 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "exprDriver.H"
#include "expressionEntry.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
defineTypeNameAndDebug(exprDriver, 0);
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
namespace Foam
{
#if 0
static string getEntryString
(
const dictionary& dict,
const string& key
)
{
const entry* eptr = dict.findEntry(key, keyType::REGEX_RECURSIVE);
if (!eptr)
{
FatalErrorInFunction
<< "Entry " << key << " not found in "
<< dict.name() << nl
<< exit(FatalError);
}
else if (eptr->isDict())
{
FatalErrorInFunction
<< "Entry " << key << " found in "
<< dict.name() << " but is a dictionary" << nl
<< exit(FatalError);
}
return exprTools::expressionEntry::evaluate(*eptr);
}
#endif
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::expressions::exprDriver::exprDriver
(
bool cacheReadFields,
bool searchInMemory,
bool searchFiles,
const dictionary& dict
)
:
dict_(dict),
result_(),
variableStrings_(),
variables_(),
stashedTokenId_(0),
// Controls
debugScanner_(dict.lookupOrDefault("debugScanner", false)),
debugParser_(dict.lookupOrDefault("debugParser", false)),
allowShadowing_
(
dict.lookupOrDefault("allowShadowing", false)
),
prevIterIsOldTime_
(
dict.lookupOrDefault("prevIterIsOldTime", false)
),
cacheReadFields_(cacheReadFields),
searchInMemory_(searchInMemory || cacheReadFields),
searchFiles_(searchFiles)
{}
Foam::expressions::exprDriver::exprDriver
(
const exprDriver& rhs
)
:
dict_(rhs.dict_),
result_(rhs.result_),
variableStrings_(rhs.variableStrings_),
variables_(rhs.variables_),
stashedTokenId_(0),
debugScanner_(rhs.debugScanner_),
debugParser_(rhs.debugParser_),
allowShadowing_(rhs.allowShadowing_),
prevIterIsOldTime_(rhs.prevIterIsOldTime_),
cacheReadFields_(rhs.cacheReadFields_),
searchInMemory_(rhs.searchInMemory_),
searchFiles_(rhs.searchFiles_)
{}
Foam::expressions::exprDriver::exprDriver
(
const dictionary& dict
)
:
exprDriver
(
dict.lookupOrDefault("cacheReadFields", false),
dict.lookupOrDefault("searchInMemory", true),
dict.lookupOrDefault("searchFiles", false),
dict
)
{
readDict(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::expressions::exprDriver::readDict
(
const dictionary& dict
)
{
dict.readIfPresent("debugBaseDriver", debug);
// Regular variables
variableStrings_ = readVariableStrings(dict);
// Other tables?
// readTable("timelines", dict, lines_);
// readTable("lookuptables", dict, lookup_);
// readTable("lookuptables2D", dict, lookup2D_);
return true;
}
void Foam::expressions::exprDriver::clearResult()
{
result_.clear();
}
bool Foam::expressions::exprDriver::update()
{
return true;
}
void Foam::expressions::exprDriver::updateSpecialVariables(bool force)
{}
void Foam::expressions::exprDriver::clearVariables()
{
variables_.clear();
addVariables(variableStrings_, false);
}
void Foam::expressions::exprDriver::evaluateVariable
(
const word& varName,
const expressions::exprString& expr
)
{
parse(expr);
result_.testIfSingleValue();
DebugInfo
<< "Evaluating: " << expr << " -> " << varName << endl
<< result_;
// Overwrite with a copy
variables_.set(varName, exprResult(result_));
}
void Foam::expressions::exprDriver::evaluateVariableRemote
(
string remote,
const word& varName,
const expressions::exprString& expr
)
{
NotImplemented;
}
Foam::expressions::exprResult
Foam::expressions::exprDriver::getRemoteResult
(
const exprDriver& other
) const
{
// With warnings (noWarn = false)
return other.result().getUniform(this->size(), false);
}
void Foam::expressions::exprDriver::addVariables
(
const expressions::exprString& expr,
bool clear
)
{
if (clear)
{
clearVariables();
}
// Allow inline list of semicolon-separated variables
const auto varExpressions =
stringOps::split<expressions::exprString>(expr, ';');
for (const auto& subMatch : varExpressions)
{
string varExpr(stringOps::trim(subMatch.str()));
if (varExpr.empty())
{
continue;
}
// Split on '=' for lhsExpr = rhsExpr
//
// varName = rhsExpr
// varName{where} = rhsExpr
const auto eqPos = varExpr.find('=');
if (eqPos == std::string::npos)
{
FatalIOErrorInFunction(dict_)
<< "No '=' found in expression " << varExpr << nl << nl
<< exit(FatalIOError);
}
// The RHS
expressions::exprString rhsExpr
(
expressions::exprString::toExpr
(
stringOps::trim(varExpr.substr(eqPos+1))
)
);
// The LHS
varExpr.resize(eqPos);
stringOps::inplaceTrim(varExpr);
// Check for varName{where}
const auto lbrace = varExpr.find('{');
if (lbrace != std::string::npos)
{
const auto rbrace = varExpr.find('}');
if (rbrace == std::string::npos || rbrace < lbrace)
{
FatalErrorInFunction
// << "Context: " << driverContext_ << nl
<< "No closing '}' found in " << varExpr << nl
<< exit(FatalError);
}
else if (lbrace+1 == rbrace)
{
FatalErrorInFunction
// << "Context: " << driverContext_ << nl
<< "Empty '{}' location in " << varExpr << nl
<< exit(FatalError);
}
const word varName(word::validate(varExpr.substr(0, lbrace)));
const expressions::exprString remoteExpr
(
expressions::exprString::toExpr
(
varExpr.substr(lbrace+1, rbrace-lbrace-1)
)
);
// Fails if derived class does not implement!
evaluateVariableRemote(remoteExpr, varName, rhsExpr);
}
else
{
const word varName(word::validate(varExpr));
evaluateVariable(varName, rhsExpr);
}
}
}
void Foam::expressions::exprDriver::addVariables
(
const UList<expressions::exprString>& list,
bool clear
)
{
if (clear)
{
clearVariables();
}
for (const auto& expr : list)
{
addVariables(expr, false); // No clear (already done)
}
}
void Foam::expressions::exprDriver::setDebugging
(
bool scannerDebug,
bool parserDebug
)
{
debugScanner_ = scannerDebug;
debugParser_ = parserDebug;
}
void Foam::expressions::exprDriver::setDebugging
(
const exprDriver& rhs
)
{
debugScanner_ = rhs.debugScanner_;
debugParser_ = rhs.debugParser_;
}
void Foam::expressions::exprDriver::setSearchBehaviour
(
bool cacheReadFields,
bool searchInMemory,
bool searchFiles
)
{
searchInMemory_ = searchInMemory_ || cacheReadFields_;
#ifdef FULLDEBUG
Info<< "Searching "
<< " registry:" << searchInMemory_
<< " disk:" << searchFiles_
<< " cache-read:" << cacheReadFields_ << nl;
#endif
}
void Foam::expressions::exprDriver::setSearchBehaviour
(
const exprDriver& rhs
)
{
setSearchBehaviour
(
rhs.cacheReadFields_,
rhs.searchInMemory_,
rhs.searchFiles_
);
}
// ************************************************************************* //

View File

@ -0,0 +1,519 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::exprDriver
Description
Base driver for parsing (field) values.
Largely based on code and ideas from swak4foam
Properties
\table
Property | Description | Required | Default
variables | List of variables for expressions | 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
exprDriverI.H
exprDriver.C
exprDriverFields.C
exprDriverIO.C
exprDriverTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef expressions_exprDriver_H
#define expressions_exprDriver_H
#include "exprString.H"
#include "exprResult.H"
#include "pointField.H"
#include "primitiveFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
/*---------------------------------------------------------------------------*\
Class exprDriver Declaration
\*---------------------------------------------------------------------------*/
class exprDriver
{
protected:
// Private Data
// Stored Data
//- The dictionary with all input data/specification
const dictionary& dict_;
//- The result
exprResult result_;
//- Variable definitions, as read from a dictionary
List<expressions::exprString> variableStrings_;
//- The variables table
HashTable<exprResult> variables_;
// Controls, tracing etc.
//- Internal bookkeeping as "look-behind" parsing context
mutable int stashedTokenId_;
//- Request debugging for scanner
bool debugScanner_;
//- Request debugging for parser
bool debugParser_;
//- Allow variable names to mask field names
bool allowShadowing_;
//- Use value of previous iteration when oldTime is requested
bool prevIterIsOldTime_;
//- Keep fields read from disc in memory
bool cacheReadFields_;
//- Search in registry before looking on disk
bool searchInMemory_;
//- Search on disk (eg, for a standalone application)
bool searchFiles_;
protected:
// Protected Member Functions
//- Read an interpolation table
template<typename TableType>
static bool readTable
(
const word& name,
const dictionary& dict,
HashTable<TableType>& tbl,
bool clear=true
);
//- Write an interpolation table
template<class TableType>
static void writeTable
(
Ostream& os,
const word& name,
const HashTable<TableType>& tbl
);
// Variables
//- Non-const access to the named variable (sub-classes only)
inline virtual exprResult& variable(const word& name);
// Fields
//- Fill a random field
//
// \param field the field to populate
// \param seed the seed value.
// \param gaussian generate a Gaussian distribution
void fill_random
(
scalarField& field,
label seed = 0,
const bool gaussian = false
) const;
//- The (global) weighted average of a field, with stabilisation
template<class Type>
static Type weightedAverage
(
const scalarField& weights,
const Field<Type>& fld
);
//- The (global) weighted sum (integral) of a field
template<class Type>
static Type weightedSum
(
const scalarField& weights,
const Field<Type>& fld
);
//- Return the location of the min value
static point getPositionOfMinimum
(
const scalarField& vals,
const pointField& locs
);
//- Return the location of the max value
static point getPositionOfMaximum
(
const scalarField& vals,
const pointField& locs
);
// Updating
//- Update things
virtual bool update();
//- Examine current variable values and update stored variables
virtual void updateSpecialVariables(bool force=false);
// Results
//- Get the result from another driver.
// Override to allow mapping
virtual exprResult getRemoteResult(const exprDriver& other) const;
//- No copy assignment
void operator=(const exprDriver&) = delete;
public:
//- Runtime type information
TypeName("exprDriver");
// Constructors
//- Null constructor, and null construct with search preferences
explicit exprDriver
(
bool cacheReadFields = false,
bool searchInMemory = true,
bool searchFiles = false,
const dictionary& dict = dictionary::null
);
//- Copy construct
exprDriver(const exprDriver&);
//- Construct from a dictionary
explicit exprDriver(const dictionary& dict);
//- Destructor
virtual ~exprDriver() = default;
// Public Member Functions
//- The underlying field size for the expression
virtual label size() const
{
return 1;
}
//- The underlying point field size for the expression
virtual label pointSize() const
{
return 1;
}
//- The dictionary with all input data/specification
const dictionary& dict() const
{
return dict_;
}
//- Const access to expression result
virtual const exprResult& result() const
{
return result_;
}
//- Non-const access to expression result
virtual exprResult& result()
{
return result_;
}
//- Clear the result
void clearResult();
//- Return the expression result as a tmp field
template<class Type>
tmp<Field<Type>> getResult(bool isPointVal=false);
//- The result type as word - same as result().valueType()
virtual word getResultType() const
{
return result_.valueType();
}
// General Controls
//- Get "look-behind" parsing context (internal bookkeeping)
inline int stashedTokenId() const;
//- Reset "look-behind" parsing context (mutable operation)
// \return the previous value
inline int resetStashedTokenId(int tokenId=0) const;
//- Set the scanner/parser debug
void setDebugging(bool scannerDebug, bool parserDebug);
//- Set the scanner/parser debug to match the input
void setDebugging(const exprDriver& rhs);
//- Set search behaviour
void setSearchBehaviour
(
bool cacheReadFields,
bool searchInMemory,
bool searchFiles
);
//- Set search behaviour to be identical to rhs
void setSearchBehaviour(const exprDriver& rhs);
//- Read access to scanner debug
bool debugScanner() const { return debugScanner_; }
//- Read access to parser debug
bool debugParser() const { return debugParser_; }
bool cacheReadFields() const { return cacheReadFields_; }
bool searchInMemory() const { return searchInMemory_; }
bool searchFiles() const { return searchFiles_; }
bool prevIterIsOldTime() const { return prevIterIsOldTime_; }
// 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;
//- Add/set string expressions for variables
// Can include multiple definitions inline
void addVariables
(
const expressions::exprString& expr,
bool clear = true //!< Remove previously defined variables
);
//- Add/set string expressions for variables
// Can include multiple definitions inline
void addVariables
(
const UList<expressions::exprString>& list,
bool clear = true //!< Remove previously defined variables
);
//- Add a uniform variable from an outside caller
template<class T>
inline void addUniformVariable
(
const word& name,
const T& val
);
// Fields
//- Test existence of a local variable
template<class T>
bool isLocalVariable
(
const word& name,
bool isPointVal,
label expectedSize = -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>> getLocalVariable
(
const word& name,
label expectSize,
const bool mandatory = true
) const;
// Evaluation
//- Execute the parser
virtual unsigned parse
(
const std::string& expr,
size_t pos = 0,
size_t len = std::string::npos
) = 0;
//- Evaluate the expression and return the field
template<class Type>
inline tmp<Field<Type>>
evaluate
(
const expressions::exprString& expr,
bool isPointVal = false
);
//- Evaluate the expression and return a single value
template<class Type>
inline Type evaluateUniform
(
const expressions::exprString& expr,
bool isPointVal = false
);
//- Evaluate the expression
//- and save as the specified named variable
void evaluateVariable
(
const word& varName,
const expressions::exprString& expr
);
//- Evaluate an expression on a remote
//- and save as the specified named variable
virtual void evaluateVariableRemote
(
string remote,
const word& varName,
const expressions::exprString& expr
);
// Fields
//- Return a new field with the size()
template<class Type>
tmp<Field<Type>>
newField(const Type& val = pTraits<Type>::zero) const;
//- Return a new field with the pointSize()
template<class Type>
tmp<Field<Type>>
newPointField(const Type& val = pTraits<Type>::zero) const;
// Reading
//- Read an expression string and do substitutions
static expressions::exprString readExpression
(
const word& name,
const dictionary& dict
);
//- Read the list of variable strings
// (or initialize with a single string)
static List<expressions::exprString> readVariableStrings
(
const dictionary& dict,
const word& name = "variables",
bool mandatory = false
);
//- Read an expression string (with the current dictionary)
//- and do substitutions
expressions::exprString readExpression(const word& name);
//- Read variables, tables etc.
// Also usable for objects not constructed from a dictionary.
virtual bool readDict(const dictionary& dict);
//- Read "variables" and assigns to the list of expression strings
// \return the number variable strings read.
label setVariableStrings
(
const dictionary& dict,
bool mandatory = false
);
// Writing
//- Write "variables"
Ostream& writeVariableStrings
(
Ostream& os,
const word& keyword = ""
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "exprDriverI.H"
#ifdef NoRepository
#include "exprDriverTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,133 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "exprDriver.H"
#include "Tuple2.H"
#include "FieldOps.H"
#include "Random.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
//! \cond file-scope
template<class T1, class T2>
static Foam::Tuple2<T1,T2> findMinData
(
const Field<T1>& vals,
const Field<T2>& data
)
{
typedef Tuple2<T1,T2> retType;
retType result(pTraits<T1>::max, Zero);
const label i = findMin(vals);
if (i != -1)
{
result.first() = vals[i];
result.second() = data[i];
}
Foam::combineReduce(result, minFirstEqOp<T1>());
return result;
}
template<class T1, class T2>
static Foam::Tuple2<T1,T2> findMaxData
(
const Field<T1>& vals,
const Field<T2>& data
)
{
typedef Tuple2<T1,T2> retType;
retType result(pTraits<T1>::min, Zero);
const label i = findMax(vals);
if (i != -1)
{
result.first() = vals[i];
result.second() = data[i];
}
Foam::combineReduce(result, maxFirstEqOp<T1>());
return result;
}
//! \endcond
} // End namespace Foam
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::expressions::exprDriver::fill_random
(
scalarField& field,
label seed,
const bool gaussian
) const
{
if (gaussian)
{
Random::gaussianGeneratorOp<scalar> gen(seed);
FieldOps::assign(field, field, gen);
}
else
{
Random::uniformGeneratorOp<scalar> gen(seed);
FieldOps::assign(field, field, gen);
}
}
Foam::point Foam::expressions::exprDriver::getPositionOfMinimum
(
const scalarField& vals,
const pointField& locs
)
{
return findMinData(vals, locs).second();
}
Foam::point Foam::expressions::exprDriver::getPositionOfMaximum
(
const scalarField& vals,
const pointField& locs
)
{
return findMaxData(vals, locs).second();
}
// ************************************************************************* //

View File

@ -0,0 +1,121 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::expressions::exprDriver::hasVariable
(
const word& name
) const
{
return variables_.found(name);
}
inline const Foam::expressions::exprResult&
Foam::expressions::exprDriver::variable
(
const word& name
) const
{
return variables_[name];
}
inline Foam::expressions::exprResult&
Foam::expressions::exprDriver::variable
(
const word& name
)
{
return variables_[name];
}
template<class Type>
inline void Foam::expressions::exprDriver::addUniformVariable
(
const word& name,
const Type& val
)
{
exprResult result;
result.setSingleValue(val);
variables_.set(name, std::move(result));
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::expressions::exprDriver::evaluate
(
const expressions::exprString& expr,
bool isPointVal
)
{
parse(expr);
return getResult<Type>(isPointVal);
}
template<class Type>
inline Type Foam::expressions::exprDriver::evaluateUniform
(
const expressions::exprString& expr,
bool isPointVal
)
{
parse(expr);
// noWarn = true
return result_.getUniform(1, true).cref<Type>().first();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline int Foam::expressions::exprDriver::stashedTokenId() const
{
return stashedTokenId_;
}
inline int Foam::expressions::exprDriver::resetStashedTokenId
(
int tokenId
) const
{
const int old = stashedTokenId_;
stashedTokenId_ = tokenId;
return old;
}
// ************************************************************************* //

View File

@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "exprDriver.H"
#include "exprTools.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
//! \cond file-scope
// Write list as single or multiple entries - see exprTools::getList()
static void writeList
(
Ostream& os,
const UList<expressions::exprString>& list
)
{
if (list.size() == 1)
{
os << list[0];
}
else
{
os << token::BEGIN_LIST;
if (!list.empty())
{
os << nl;
for (const expressions::exprString& str : list)
{
os << str << nl;
}
}
os << token::END_LIST;
}
}
//! \endcond
} // End namespace Foam
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::expressions::exprString
Foam::expressions::exprDriver::readExpression
(
const word& name,
const dictionary& dict
)
{
return expressions::exprString(dict.get<string>(name), dict);
}
Foam::expressions::exprString
Foam::expressions::exprDriver::readExpression
(
const word& name
)
{
return readExpression(name, dict());
}
Foam::List<Foam::expressions::exprString>
Foam::expressions::exprDriver::readVariableStrings
(
const dictionary& dict,
const word& keyword,
bool mandatory
)
{
return exprTools::getList(dict, keyword, mandatory);
}
Foam::label Foam::expressions::exprDriver::setVariableStrings
(
const dictionary& dict,
bool mandatory
)
{
variableStrings_ = readVariableStrings(dict, "variable", mandatory);
return variableStrings_.size();
}
Foam::Ostream& Foam::expressions::exprDriver::writeVariableStrings
(
Ostream& os,
const word& keyword
) const
{
if (keyword.size())
{
os.writeKeyword(keyword);
}
writeList(os, variableStrings_);
if (keyword.size())
{
os << token::END_STATEMENT << nl;
}
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,97 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
Namespace
Foam::expressions::exprDriverOps
Description
Miscellaneous operations used in combination with the
expressions::exprDriver
SourceFiles
exprDriverOps.H
\*---------------------------------------------------------------------------*/
#ifndef expressions_exprDriverOps_H
#define expressions_exprDriverOps_H
#include "scalarOps.H"
#include "FieldOps.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
namespace exprDriverOps
{
/*---------------------------------------------------------------------------*\
Namespace exprDriverOps Declarations
\*---------------------------------------------------------------------------*/
//- A modulo operation similar to that used in swak4foam
// This operation produces values in the -1/2 to +1/2 range.
struct swakModuloOp
{
scalar operator()(const scalar& a, const scalar& b) const
{
if (Foam::mag(b) < ROOTVSMALL)
{
return 0;
}
const scalar val = std::fmod(a, b);
if (Foam::mag(val) > (0.5*b))
{
if (val > 0)
{
return (val - b);
}
else
{
return (val + b);
}
}
return val;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace exprDriverOps
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,231 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class TableType>
bool Foam::expressions::exprDriver::readTable
(
const word& name,
const dictionary& dict,
HashTable<TableType>& tbl,
bool clear
)
{
if (clear)
{
tbl.clear();
}
if (!dict.found(name))
{
return false;
}
ITstream& is = dict.lookup(name);
List<dictionary> input(is);
for (const dictionary& d : input)
{
tbl.insert(dict.get<word>("name"), TableType(d));
}
return true;
}
template<class TableType>
void Foam::expressions::exprDriver::writeTable
(
Ostream& os,
const word& name,
const HashTable<TableType>& tbl
)
{
if (tbl.size())
{
os.writeKeyword(name);
os << token::BEGIN_LIST << nl;
forAllConstIters(tbl, iter)
{
os.beginBlock();
os.writeEntry("name", iter.key());
(*iter).write(os);
os.endBlock();
}
os << token::END_LIST
<< token::END_STATEMENT << nl;
}
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
Type Foam::expressions::exprDriver::exprDriver::weightedAverage
(
const scalarField& wfield,
const Field<Type>& fld
)
{
if (isNull(wfield))
{
const label n = returnReduce(fld.size(), sumOp<label>());
// stabilize
if (!n)
{
return Zero;
}
return gSum(fld) / scalar(n);
}
// #ifdef FULLDEBUG
// checkSize(wfield, fld);
// #endif
const scalar s = gSum(wfield);
// stabilize
if (mag(s) < ROOTVSMALL)
{
return Zero;
}
return gSum(wfield*fld) / s;
}
template<class Type>
Type Foam::expressions::exprDriver::exprDriver::weightedSum
(
const scalarField& wfield,
const Field<Type>& fld
)
{
if (isNull(wfield))
{
return gSum(fld);
}
// #ifdef FULLDEBUG
// checkSize(wfield, fld);
// #endif
return gSum(wfield*fld);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::expressions::exprDriver::getResult(bool isPointVal)
{
if (!result_.isPointValue(isPointVal))
{
FatalErrorInFunction
<< "Expected a" << (isPointVal ? " point" : "")
<< " field, but found a" << (!isPointVal ? " point" : "")
<< " field" << nl
<< exit(FatalError);
}
return result_.getResult<Type>();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::expressions::exprDriver::isLocalVariable
(
const word& name,
bool isPointVal,
label expectedSize
) const
{
DebugInfo
<< "Looking for local" << (isPointVal ? " point" : "")
<< " field name:" << name << " type:"
<< pTraits<Type>::typeName << " size:" << expectedSize;
bool good = hasVariable(name);
if (good)
{
const exprResult& var = variable(name);
DebugInfo
<< " - found (" << var.valueType() << ' ' << var.isPointValue() << ')';
good = (var.isType<Type>() && var.isPointValue(isPointVal));
// Do size checking if requested
if (good && expectedSize >= 0)
{
good = (var.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::exprDriver::newField
(
const Type& val
) const
{
return tmp<Field<Type>>::New(size(), val);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::expressions::exprDriver::newPointField
(
const Type& val
) const
{
return tmp<Field<Type>>::New(pointSize(), val);
}
// ************************************************************************* //