ENH: addition of expressions::exprResult

- polymorphic field/result
This commit is contained in:
Mark Olesen
2019-11-18 11:29:53 +01:00
committed by Andrew Heather
parent 241dee29b2
commit daac96f165
15 changed files with 4163 additions and 0 deletions

View File

@ -145,6 +145,12 @@ $(expr)/exprEntry/expressionEntryBool.C
$(expr)/exprEntry/expressionEntryDimensioned.C
$(expr)/exprEntry/expressionEntryStrings.C
$(expr)/exprEntry/expressionEntryVectors.C
$(expr)/exprResult/exprResult.C
$(expr)/exprResult/exprResultGlobals.C
$(expr)/exprResult/exprResultDelayed.C
$(expr)/exprResult/exprResultStack.C
$(expr)/exprResult/exprResultStored.C
$(expr)/exprResult/exprResultStoredStack.C
$(expr)/exprString/exprString.C
$(expr)/exprTools/exprTools.C

View File

@ -0,0 +1,735 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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 "exprResult.H"
#include "vector.H"
#include "tensor.H"
#include "symmTensor.H"
#include "sphericalTensor.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
defineTypeNameAndDebug(exprResult,0);
defineRunTimeSelectionTable(exprResult, dictionary);
defineRunTimeSelectionTable(exprResult, empty);
addToRunTimeSelectionTable(exprResult, exprResult, dictionary);
addToRunTimeSelectionTable(exprResult, exprResult, empty);
} // End namespace expressions
} // End namespace Foam
const Foam::expressions::exprResult Foam::expressions::exprResult::null;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::expressions::exprResult::singleValue::singleValue()
{
std::memset(static_cast<void*>(this), '\0', sizeof(*this));
}
Foam::expressions::exprResult::singleValue::singleValue
(
const singleValue& val
)
{
std::memcpy(static_cast<void*>(this), &val, sizeof(*this));
}
void Foam::expressions::exprResult::singleValue::operator=
(
const singleValue& val
)
{
if (this != &val)
{
// Self-assignment is a no-op
std::memcpy(static_cast<void*>(this), &val, sizeof(*this));
}
}
Foam::expressions::exprResult::exprResult()
:
refCount(),
valType_(),
isUniform_(false),
isPointVal_(false),
noReset_(false),
needsReset_(false),
size_(0),
single_(),
fieldPtr_(nullptr),
objectPtr_(nullptr)
{
clear();
}
Foam::expressions::exprResult::exprResult(const exprResult& rhs)
:
exprResult()
{
this->operator=(rhs);
}
Foam::expressions::exprResult::exprResult(exprResult&& rhs)
:
exprResult()
{
this->operator=(std::move(rhs));
}
Foam::expressions::exprResult::exprResult
(
const dictionary& dict,
bool uniform,
bool needsValue
)
:
refCount(),
valType_(dict.getOrDefault<word>("valueType", "")),
isUniform_(dict.getOrDefault("isSingleValue", uniform)),
isPointVal_(dict.getOrDefault("isPointValue", false)),
noReset_(dict.getOrDefault("noReset", false)),
needsReset_(false),
size_(0),
single_(),
fieldPtr_(nullptr),
objectPtr_(nullptr)
{
DebugInFunction << nl;
if (dict.found("value"))
{
const label len =
(
isUniform_
? dict.getOrDefault<label>("fieldSize", 1)
: dict.get<label>("fieldSize")
);
if (isUniform_)
{
const bool created =
(
createUniformChecked<bool>("value", dict, len)
|| createUniformChecked<scalar>("value", dict, len)
|| createUniformChecked<vector>("value", dict, len)
|| createUniformChecked<tensor>("value", dict, len)
|| createUniformChecked<symmTensor>("value", dict, len)
|| createUniformChecked<sphericalTensor>("value", dict, len)
);
if (!created)
{
if (valType_.empty())
{
// For the error message only
valType_ = "None";
}
FatalErrorInFunction
<< "Don't know how to read data type "
<< valType_
<< " as a single value" << nl
<< exit(FatalError);
}
}
else
{
const bool created =
(
createNonUniformChecked<bool>("value", dict, len)
|| createNonUniformChecked<scalar>("value", dict, len)
|| createNonUniformChecked<vector>("value", dict, len)
|| createNonUniformChecked<tensor>("value", dict, len)
|| createNonUniformChecked<symmTensor>("value", dict, len)
|| createNonUniformChecked<sphericalTensor>("value", dict, len)
);
if (!created)
{
if (valType_.empty())
{
// For the error message only
valType_ = "None";
}
FatalErrorInFunction
<< "Don't know how to read data type " << valType_ << nl
<< exit(FatalError);
}
}
}
else if (needsValue)
{
FatalIOErrorInFunction(dict)
<< "No entry 'value' defined in " << dict.name() << nl
<< exit(FatalIOError);
}
}
Foam::autoPtr<Foam::expressions::exprResult>
Foam::expressions::exprResult::New
(
const dictionary& dict
)
{
const word resultType
(
dict.getOrDefault<word>("resultType", "exprResult")
);
if (dict.getOrDefault("unsetValue", false))
{
auto cstrIter = emptyConstructorTablePtr_->cfind(resultType);
if (!cstrIter.found())
{
FatalErrorInLookup
(
"resultType",
resultType,
*emptyConstructorTablePtr_
) << exit(FatalError);
}
DebugInfo
<< "Creating unset result of type " << resultType << nl;
return autoPtr<exprResult>(cstrIter()());
}
auto cstrIter = dictionaryConstructorTablePtr_->cfind(resultType);
if (!cstrIter.found())
{
FatalErrorInLookup
(
"resultType",
resultType,
*dictionaryConstructorTablePtr_
) << exit(FatalError);
}
DebugInfo
<< "Creating result of type " << resultType << nl;
return autoPtr<exprResult>(cstrIter()(dict));
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::expressions::exprResult::~exprResult()
{
DebugInFunction << nl;
uglyDelete();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::expressions::exprResult::resetImpl()
{
clear();
}
bool Foam::expressions::exprResult::reset(bool force)
{
if (force || !noReset_ || needsReset_)
{
this->resetImpl();
return true;
}
return false;
}
void Foam::expressions::exprResult::clear()
{
uglyDelete();
valType_.clear();
objectPtr_.reset();
size_ = 0;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::expressions::exprResult::uglyDelete()
{
if (fieldPtr_)
{
const bool ok =
(
deleteChecked<scalar>()
|| deleteChecked<vector>()
|| deleteChecked<tensor>()
|| deleteChecked<symmTensor>()
|| deleteChecked<sphericalTensor>()
|| deleteChecked<bool>()
);
if (!ok)
{
FatalErrorInFunction
<< "Unknown type " << valType_
<< " probable memory loss" << nl
<< exit(FatalError);
}
fieldPtr_ = nullptr;
size_ = 0;
}
}
Foam::expressions::exprResult
Foam::expressions::exprResult::getUniform
(
const label size,
const bool noWarn,
const bool parRun
) const
{
if (fieldPtr_ == nullptr)
{
FatalErrorInFunction
<< "Not set. Cannot construct uniform value" << nl
<< exit(FatalError);
}
exprResult ret;
const bool ok =
(
getUniformChecked<scalar>(ret, size, noWarn, parRun)
|| getUniformChecked<vector>(ret, size, noWarn, parRun)
|| getUniformChecked<tensor>(ret, size, noWarn, parRun)
|| getUniformChecked<symmTensor>(ret, size, noWarn, parRun)
|| getUniformChecked<sphericalTensor>(ret, size, noWarn, parRun)
);
if (!ok)
{
FatalErrorInFunction
<< "Cannot get uniform value for type " << valType_ << nl
<< exit(FatalError);
}
return ret;
}
void Foam::expressions::exprResult::testIfSingleValue()
{
if (fieldPtr_ == nullptr)
{
FatalErrorInFunction
<< "Not set. Cannot determine if uniform" << nl
<< exit(FatalError);
}
const bool ok =
(
setAverageValueChecked<scalar>()
|| setAverageValueChecked<vector>()
|| setAverageValueChecked<tensor>()
|| setAverageValueChecked<symmTensor>()
|| setAverageValueChecked<sphericalTensor>()
);
if (!ok)
{
if (isBool())
{
FatalErrorInFunction
<< "This specialisation is not implemented" << nl
<< exit(FatalError);
}
FatalErrorInFunction
<< "Unknown type " << valType_ << nl
<< exit(FatalError);
}
}
void Foam::expressions::exprResult::operator=(const exprResult& rhs)
{
if (this == &rhs)
{
return; // Self-assignment is a no-op
}
DebugInFunction << "rhs:" << rhs << nl;
clear();
valType_ = rhs.valType_;
isUniform_ = rhs.isUniform_;
isPointVal_ = rhs.isPointVal_;
single_ = rhs.single_;
if (rhs.fieldPtr_)
{
const bool ok =
(
duplicateFieldChecked<scalar>(rhs.fieldPtr_)
|| duplicateFieldChecked<vector>(rhs.fieldPtr_)
|| duplicateFieldChecked<tensor>(rhs.fieldPtr_)
|| duplicateFieldChecked<symmTensor>(rhs.fieldPtr_)
|| duplicateFieldChecked<sphericalTensor>(rhs.fieldPtr_)
|| duplicateFieldChecked<bool>(rhs.fieldPtr_)
);
if (!ok)
{
FatalErrorInFunction
<< " Type " << valType_ << " can not be copied" << nl
<< exit(FatalError);
}
}
else if (objectPtr_.valid())
{
FatalErrorInFunction
<< "Assignment with general content not possible" << nl
<< exit(FatalError);
}
}
void Foam::expressions::exprResult::operator=(exprResult&& rhs)
{
if (this == &rhs)
{
return; // Self-assignment is a no-op
}
clear();
valType_ = rhs.valType_;
isUniform_ = rhs.isUniform_;
isPointVal_ = rhs.isPointVal_;
noReset_ = rhs.noReset_;
needsReset_ = rhs.needsReset_;
size_ = rhs.size_;
single_ = rhs.single_;
fieldPtr_ = rhs.fieldPtr_;
objectPtr_.reset(rhs.objectPtr_.release());
rhs.fieldPtr_ = nullptr; // Took ownership of field pointer
rhs.clear();
}
void Foam::expressions::exprResult::writeEntry
(
const word& keyword,
Ostream& os
) const
{
const bool ok =
(
writeEntryChecked<scalar>(keyword, os)
|| writeEntryChecked<vector>(keyword, os)
|| writeEntryChecked<tensor>(keyword, os)
|| writeEntryChecked<symmTensor>(keyword, os)
|| writeEntryChecked<sphericalTensor>(keyword, os)
|| writeEntryChecked<bool>(keyword, os)
);
if (!ok)
{
WarningInFunction
<< "Unknown data type " << valType_ << endl;
}
}
void Foam::expressions::exprResult::writeDict
(
Ostream& os,
const bool subDict
) const
{
// const auto oldFmt = os.format(IOstream::ASCII);
DebugInFunction
<< Foam::name(this) << nl
<< "Format: "
<< IOstreamOption::formatNames[os.format()] << nl;
if (subDict)
{
os.beginBlock();
}
os.writeEntry("resultType", valueType());
os.writeEntryIfDifferent<Switch>("noReset_", false, noReset_);
if (fieldPtr_ == nullptr)
{
os.writeEntry<Switch>("unsetValue", true);
}
else
{
os.writeEntry("valueType", valType_);
os.writeEntryIfDifferent<Switch>("isPointValue", false, isPointVal_);
os.writeEntry<Switch>("isSingleValue", isUniform_);
const bool ok =
(
writeValueChecked<scalar>(os)
|| writeValueChecked<vector>(os)
|| writeValueChecked<tensor>(os)
|| writeValueChecked<symmTensor>(os)
|| writeValueChecked<sphericalTensor>(os)
|| writeValueChecked<bool>(os)
);
if (!ok)
{
WarningInFunction
<< "Unknown data type " << valType_ << endl;
}
}
if (subDict)
{
os.endBlock();
}
// os.format(oldFmt);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
Foam::expressions::exprResult&
Foam::expressions::exprResult::operator*=
(
const scalar& b
)
{
if (isObject())
{
FatalErrorInFunction
<< "Can only multiply Field-type exprResult. Not "
<< valType_ << nl
<< exit(FatalError);
}
if (!fieldPtr_)
{
FatalErrorInFunction
<< "Can not multiply. Unallocated field of type" << valType_ << nl
<< exit(FatalError);
}
const bool ok =
(
multiplyEqChecked<scalar>(b)
|| multiplyEqChecked<vector>(b)
|| multiplyEqChecked<tensor>(b)
|| multiplyEqChecked<symmTensor>(b)
|| multiplyEqChecked<sphericalTensor>(b)
);
if (!ok)
{
FatalErrorInFunction
<< "Can not multiply field of type "
<< valType_ << nl
<< exit(FatalError);
}
return *this;
}
Foam::expressions::exprResult&
Foam::expressions::exprResult::operator+=
(
const exprResult& b
)
{
if (isObject())
{
FatalErrorInFunction
<< "Can only add Field-type, not type: "
<< valType_ << nl
<< exit(FatalError);
}
if (!fieldPtr_)
{
FatalErrorInFunction
<< "Can not add. Unallocated field of type " << valType_ << nl
<< exit(FatalError);
}
if (this->size() != b.size())
{
FatalErrorInFunction
<< "Different sizes " << this->size() << " and " << b.size() << nl
<< exit(FatalError);
}
const bool ok =
(
plusEqChecked<scalar>(b)
|| plusEqChecked<vector>(b)
|| plusEqChecked<tensor>(b)
|| plusEqChecked<symmTensor>(b)
|| plusEqChecked<sphericalTensor>(b)
);
if (!ok)
{
FatalErrorInFunction
<< "Can not add Field-type exprResult of type"
<< valType_ << nl
<< exit(FatalError);
}
return *this;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>
(
Istream& is,
expressions::exprResult& data
)
{
dictionary dict(is);
data = expressions::exprResult(dict);
return is;
}
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const expressions::exprResult& data
)
{
data.writeDict(os);
return os;
}
Foam::expressions::exprResult Foam::operator*
(
const scalar& a,
const expressions::exprResult& b
)
{
expressions::exprResult result(b);
return result *= a;
}
Foam::expressions::exprResult Foam::operator*
(
const expressions::exprResult& a,
const scalar& b
)
{
expressions::exprResult result(a);
result *= b;
return result;
}
Foam::expressions::exprResult Foam::operator+
(
const expressions::exprResult& a,
const expressions::exprResult& b
)
{
expressions::exprResult result(a);
result += b;
return result;
}
const void* Foam::expressions::exprResult::dataAddress() const
{
#undef defineExpressionMethod
#define defineExpressionMethod(Type) \
if (isType<Type>()) \
{ \
return static_cast<Field<Type>*>(fieldPtr_)->cdata(); \
}
defineExpressionMethod(scalar);
defineExpressionMethod(vector);
defineExpressionMethod(tensor);
defineExpressionMethod(symmTensor);
defineExpressionMethod(sphericalTensor);
#undef defineExpressionMethod
FatalErrorInFunction
<< "Unsupported type" << valType_ << nl
<< exit(FatalError);
return nullptr;
}
// ************************************************************************* //

View File

@ -0,0 +1,562 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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::exprResult
Description
A polymorphic field/result from evaluating an expression
\heading Dictionary parameters
\table
Property | Description | Required | Default
resultType | The type of result | no | exprResult
unsetValue | Create without reading the dictionary | no | false
noReset | Suppress reset on time | no | false
\endtable
When creating with values
\table
Property | Description | Required | Default
valueType | Result value type (scalar, vector,..) | yes |
isSingleValue | A single field value | no | false
isPointValue | Interpret values as point values | no | false
value | The field values | yes |
fieldSize | The size of the field (when not single-value) | no |
\endtable
SourceFiles
exprResult.C
exprResultI.H
\*---------------------------------------------------------------------------*/
#ifndef expressions_exprResult_H
#define expressions_exprResult_H
#include "vector.H"
#include "tensor.H"
#include "sphericalTensor.H"
#include "symmTensor.H"
#include "dimensionedType.H"
#include "IOField.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
/*---------------------------------------------------------------------------*\
Class exprResult Declaration
\*---------------------------------------------------------------------------*/
class exprResult
:
public refCount
{
// Private Data
//- The value type as string,
//- normally corresponds to pTraits or typeName
word valType_;
//- Is single, uniform value (can be a non-field)
bool isUniform_;
//- Is a point value
bool isPointVal_;
//- Whether or not the variable will be reset
bool noReset_;
//- Allow override of noReset_, but only accessible for subclasses
bool needsReset_;
//- Size of field or object
label size_;
//- A %union of single values, including standard VectorSpace types
union singleValue
{
bool bool_;
scalar scalar_;
vector vector_;
tensor tensor_;
symmTensor symmTensor_;
sphericalTensor sphTensor_;
//- Construct null, zero-initialized
singleValue();
//- Copy construct
singleValue(const singleValue& val);
//- Copy assignment
void operator=(const singleValue& val);
//- Return current value for specified type.
template<class T>
inline const T& get() const
{
NotImplemented;
return pTraits<T>::zero;
}
//- Set new value for specified type. Returns updated value.
template<class T>
inline const T& set(const T& val)
{
NotImplemented;
return pTraits<T>::zero;
}
};
//- The single value
singleValue single_;
//- Allocated plain field (eg, scalarField)
void *fieldPtr_;
//- Alternative storage for non-plain fields (eg, volScalarField)
autoPtr<regIOobject> objectPtr_;
// Private Member Functions
//- Type-checked deletion of the value pointer.
// \return True if the type check was satisfied
template<class Type>
inline bool deleteChecked();
//- Dispatch to type-checked pointer deletion
void uglyDelete();
//- Type-checked creation of uniform field from dictionary
// \return True if the type check was satisfied
template<class Type>
inline bool createUniformChecked
(
const word& key,
const dictionary& dict,
const label len
);
//- Type-checked creation of non-uniform field from dictionary
// \return True if the type check was satisfied
template<class Type>
inline bool createNonUniformChecked
(
const word& key,
const dictionary& dict,
const label len
);
//- Type-checked retrieval of uniform field from current results
// \return True if the type check was satisfied
template<class Type>
bool getUniformChecked
(
exprResult& result,
const label size,
const bool noWarn,
const bool parallel
) const;
//- Type-checked determination of centre value (min/max)
// \return True if the type check was satisfied
template<class Type>
bool setAverageValueChecked();
//- Type-checked copy of field
// \return True if the type check was satisfied
template<class Type>
bool duplicateFieldChecked(const void* ptr);
//- Type-checked writing of "value" entry
// \return True if the type check was satisfied
template<class Type>
bool writeValueChecked(Ostream& os) const;
//- Type-checked forwarding to Field::writeEntry
// \return True if the type check was satisfied
template<class Type>
bool writeEntryChecked(const word& keyword, Ostream& os) const;
//- Type-checked field addition with another expression field
// \return True if the type check was satisfied
template<class Type>
bool plusEqChecked(const exprResult& b);
//- Type-checked field multiplication with a scalar
// \return True if the type check was satisfied
template<class Type>
bool multiplyEqChecked(const scalar& b);
template<class Type>
inline void setResultImpl(Field<Type>*, bool isPointVal=false);
template<class Type>
inline void setResultImpl(const Field<Type>&, bool isPointVal=false);
template<class Type>
inline void setResultImpl(Field<Type>&&, bool isPointVal=false);
template<class Type>
inline void setResultImpl(const Type& val, const label len);
template<class Type>
inline void setSingleValueImpl(const Type& val);
template<class Type>
inline void setObjectResultImpl(Type* ptr);
template<class Type>
inline void setObjectResultImpl(autoPtr<Type>& ap);
template<class Type>
inline void setObjectResultImpl(autoPtr<Type>&& ap);
protected:
// Protected Member Functions
//- Simulate virtual templated methods
inline virtual exprResult& target() { return *this; }
//- Reset at new timestep according to the derived class type
virtual void resetImpl();
//- Reset at new timestep according to type
// \return true if it was actually reset
bool reset(bool force=false);
//- Adjusts the internal needsReset value
void needsReset(bool val) { needsReset_ = val; }
public:
//- An empty result
static const exprResult null;
//- Friendship with globals
friend class exprResultGlobals;
//- Runtime type information
TypeName("exprResult");
declareRunTimeSelectionTable
(
autoPtr,
exprResult,
dictionary,
(
const dictionary& dict
),
(dict)
);
declareRunTimeSelectionTable
(
autoPtr,
exprResult,
empty,
(),
()
);
// Constructors
//- Construct null
exprResult();
//- Copy construct
exprResult(const exprResult& expr);
//- Move construct
exprResult(exprResult&& expr);
//- Construct from a dictionary
explicit exprResult
(
const dictionary& dict,
const bool uniform = false,
const bool needsValue = false
);
//- Construct by copying a field
template<class Type>
exprResult(const Field<Type>& f);
//- Construct by moving a field
template<class Type>
exprResult(Field<Type>&& f);
//- Construct for an IOobject
template<class Type>
exprResult(autoPtr<Type>& ap);
//- Construct for an IOobject
template<class Type>
exprResult(autoPtr<Type>&& ap);
//- Construct from a dimensioned value
template<class Type>
exprResult(const dimensioned<Type>& f);
#undef exprResult_Construct
#define exprResult_Construct(Type) \
/*! Construct from single value of Type */ \
explicit exprResult(const Type& val) : exprResult() \
{ \
setSingleValue(val); \
}
exprResult_Construct(bool);
exprResult_Construct(scalar);
exprResult_Construct(vector);
exprResult_Construct(tensor);
exprResult_Construct(symmTensor);
exprResult_Construct(sphericalTensor);
#undef exprResult_Construct
// Selectors
//- Return a reference to the selected value driver
static autoPtr<exprResult> New(const dictionary& dict);
//- Clone
virtual autoPtr<exprResult> clone() const
{
return autoPtr<exprResult>::New(*this);
}
//- Destructor
virtual ~exprResult();
// Member Functions
// Access
//- Has a value?
inline bool hasValue() const;
//- Basic type for the field or single value
inline const word& valueType() const;
//- True if representing point values, or test if same as isPointVal
inline bool isPointValue(const bool isPointVal = true) const;
//- True if single, uniform value
inline bool isUniform() const;
//- True if valueType corresponds to the given Type
template<class Type>
inline bool isType() const;
//- True if valueType is a bool
inline bool isBool() const;
//- True if the object pointer is being used
inline bool isObject() const;
//- The field or object size
inline label size() const;
//- The address of the field data content.
// Fatal for unknown types.
// Used, for example, for python integration
const void* dataAddress() const;
// Edit
//- Clear (zero) the result
void clear();
//- Change reset behaviour
void noReset() { noReset_ = true; }
//- Change reset behaviour
void allowReset() { noReset_ = false; }
//- Test if field corresponds to a single-value and thus uniform.
// Uses field min/max to establish uniformity.
void testIfSingleValue();
// Set results
//- Set result field, taking ownership of the pointer
template<class Type>
inline void setResult(Field<Type>*, bool isPointVal=false);
//- Set result field, taking copy of the field contents
template<class Type>
inline void setResult(const Field<Type>& fld, bool isPointVal=false);
//- Set result field, moving field contents
template<class Type>
inline void setResult(Field<Type>&&, bool isPointVal=false);
//- Set uniform result field of given size
template<class Type>
inline void setResult(const Type& val, const label size);
//- Set single-value uniform result
template<class Type>
inline void setSingleValue(const Type& val);
template<class Type>
inline void setObjectResult(autoPtr<Type>& o);
template<class Type>
inline void setObjectResult(autoPtr<Type>&& o);
// Access/Get results
//- Return const reference to the field
template<class Type>
inline const Field<Type>& cref() const;
//- Return non-const reference to the field
template<class Type>
inline Field<Type>& ref();
//- Return non-const reference to the field, casting away constness
template<class Type>
inline Field<Type>& getRef() const;
//- Return tmp field of the contents,
//- optionally keeping a copy in cache
template<class Type>
inline tmp<Field<Type>> getResult(bool cacheCopy=false);
//- Get object result (Caution - potentially fragile)
//- optionally keeping a copy in cache
template<class Type>
inline tmp<Type> getObjectResult(bool cacheCopy=false);
//- Construct a uniform field from the current results
// Uses the field average. Optionally warning if the min/max
// deviation is larger than SMALL.
exprResult getUniform
(
const label size,
const bool noWarn,
const bool parRun = Pstream::parRun()
) const;
//- Get a reduced result
template<template<class> class BinaryOp, class Type>
inline Type getReduced
(
const BinaryOp<Type>& bop,
const Type& initial = pTraits<Type>::zero
);
// Write
//- Forwarding to Field::writeEntry
void writeEntry(const word& keyword, Ostream& os) const;
//- Write entry as dictionary contents
void writeDict(Ostream& os, const bool subDict=true) const;
// Member Operators
//- Copy assignment
virtual void operator=(const exprResult& rhs);
//- Move assignment
virtual void operator=(exprResult&& rhs);
//- Scalar multiplication
exprResult& operator*=(const scalar& b);
//- Addition of results
exprResult& operator+=(const exprResult& b);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace expressions
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Operators
expressions::exprResult operator*
(
const scalar& a,
const expressions::exprResult& b
);
expressions::exprResult operator*
(
const expressions::exprResult& a,
const scalar& b
);
expressions::exprResult operator+
(
const expressions::exprResult& a,
const expressions::exprResult& b
);
// IO Operator
Istream& operator>>(Istream& os, expressions::exprResult& data);
Ostream& operator<<(Ostream& os, const expressions::exprResult& data);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "exprResultI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,333 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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 "exprResultDelayed.H"
#include "vector.H"
#include "tensor.H"
#include "symmTensor.H"
#include "sphericalTensor.H"
#include "addToRunTimeSelectionTable.H"
// #include <cassert>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
defineTypeNameAndDebug(exprResultDelayed, 0);
addToRunTimeSelectionTable
(
exprResult,
exprResultDelayed,
dictionary
);
addToRunTimeSelectionTable
(
exprResult,
exprResultDelayed,
empty
);
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::expressions::exprResultDelayed::exprResultDelayed()
:
exprResult(),
name_("none"),
startExpr_(),
settingResult_(),
storeInterval_(1),
delay_(10)
{}
Foam::expressions::exprResultDelayed::exprResultDelayed
(
const exprResultDelayed& rhs
)
:
exprResult(rhs),
name_(rhs.name_),
startExpr_(rhs.startExpr_),
settingResult_(rhs.settingResult_),
storedValues_(rhs.storedValues_),
storeInterval_(rhs.storeInterval_),
delay_(rhs.delay_)
{}
Foam::expressions::exprResultDelayed::exprResultDelayed
(
const dictionary& dict
)
:
exprResult(dict.subOrEmptyDict("value")),
name_(dict.get<word>("name")),
startExpr_(dict.get<string>("startupValue"), dict),
storeInterval_(dict.get<scalar>("storeInterval")),
delay_(dict.get<scalar>("delay"))
{
const entry *eptr = dict.findEntry("storedValues");
if (eptr)
{
storedValues_ = DLList<ValueAtTime>(eptr->stream());
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::expressions::exprResultDelayed::updateReadValue
(
const scalar& timeVal
)
{
if (storedValues_.empty())
{
return false;
}
const ValueAtTime& first = storedValues_.first();
if (first.first() > (timeVal-delay_))
{
// No matching data yet
return false;
}
if (storedValues_.size() <= 1)
{
FatalErrorInFunction
<< "Only one stored value at time " << timeVal
<< " for delayedVariable " << name() << nl
<< "Check the values for the interval " << storeInterval_
<< " and delay " << delay_ << nl
<< "Probably the interval is too large" << nl << endl
<< exit(FatalError);
}
auto current = storedValues_.cbegin();
auto next = current;
++next;
// The time without the delay offset
const scalar newTime = (timeVal - delay_);
while (next != storedValues_.end())
{
if (newTime >= current().first() && newTime <= next().first())
{
break;
}
current = next;
++next;
}
const scalar f =
(
(newTime - current().first())
/ (next().first() - current().first())
);
exprResult val((1-f)*current().second() + f*next().second());
setReadValue(val);
return true;
}
void Foam::expressions::exprResultDelayed::setReadValue
(
const exprResult& val
)
{
exprResult::operator=(val);
}
void Foam::expressions::exprResultDelayed::storeValue
(
const scalar& currTime
)
{
bool append = storedValues_.empty();
if (!append)
{
const scalar lastTime = storedValues_.last().first();
if (lastTime + SMALL >= currTime)
{
// Times are essentially identical - replace value
}
else if ((currTime - lastTime) >= 0.999*storeInterval_)
{
append = true;
}
else
{
// Cannot store in the middle - abandon the attempt
return;
}
}
if (append)
{
// Append value
const scalar oldLastTime =
(
storedValues_.empty()
? 0
: storedValues_.last().first()
);
storedValues_.append(ValueAtTime(currTime, settingResult_));
while
(
storedValues_.size() > 1
&& (oldLastTime - storedValues_.first().first()) >= delay_
)
{
// Remove values that are older than delay_
storedValues_.removeHead();
}
}
else
{
// Replace value
storedValues_.last().second() = settingResult_;
}
}
void Foam::expressions::exprResultDelayed::writeDict(Ostream& os) const
{
os.beginBlock();
os.writeEntry("name", name_);
os.writeEntry("startupValue", startExpr_);
if (!settingResult_.valueType().empty())
{
os.writeEntry("settingResult", settingResult_);
}
os.writeEntry("storedValues", storedValues_);
os.writeEntry("storeInterval", storeInterval_);
os.writeEntry("delay", delay_);
os.writeKeyword("value");
os << static_cast<const exprResult&>(*this);
os.endBlock();
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::expressions::exprResultDelayed::operator=
(
const exprResultDelayed& rhs
)
{
if (this == &rhs)
{
return; // Self-assignment is a no-op
}
exprResult::operator=(rhs);
name_ = rhs.name_;
startExpr_ = rhs.startExpr_;
settingResult_ = rhs.settingResult_;
storedValues_ = rhs.storedValues_;
storeInterval_ = rhs.storeInterval_;
delay_ = rhs.delay_;
}
void Foam::expressions::exprResultDelayed::operator=
(
const exprResult& rhs
)
{
settingResult_ = rhs;
}
void Foam::expressions::exprResultDelayed::operator=
(
exprResult&& rhs
)
{
settingResult_ = std::move(rhs);
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>
(
Istream& is,
expressions::exprResultDelayed& data
)
{
dictionary dict(is);
data = expressions::exprResultDelayed(dict);
return is;
}
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const expressions::exprResultDelayed& data
)
{
data.writeDict(os);
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,210 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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::exprResultDelayed
Description
An exprResult with an additional delay before evaluation
\heading Dictionary parameters
\table
Property | Description | Required | Default
name | The result name | yes |
delay | The delay before starting | yes |
storeInterval | The storage interval (time) | yes |
startupValue | The initial startup value | yes |
value | The expression result (dictionary) | no |
storedValues | The list of stored values | yes |
\endtable
SourceFiles
exprResultDelayed.C
\*---------------------------------------------------------------------------*/
#ifndef expressions_exprResultDelayed_H
#define expressions_exprResultDelayed_H
#include "exprResult.H"
#include "exprString.H"
#include "Tuple2.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
/*---------------------------------------------------------------------------*\
Class exprResultDelayed Declaration
\*---------------------------------------------------------------------------*/
class exprResultDelayed
:
public expressions::exprResult
{
// Typedefs
//- Expression at a given time value.
typedef Tuple2<scalar, expressions::exprResult> ValueAtTime;
// Private Data
//- The name of the expression
word name_;
//- The initial value expression
expressions::exprString startExpr_;
//- The pending result to be set
expressions::exprResult settingResult_;
//- The old results
DLList<ValueAtTime> storedValues_;
//- How often values should be stored
scalar storeInterval_;
//- The size of the delay
scalar delay_;
protected:
// Protected Member Functions
//- Simulate virtual templated methods
inline expressions::exprResult& target() { return settingResult_; }
public:
//- Runtime type information
TypeName("exprResultDelayed");
// Constructors
//- Construct null
exprResultDelayed();
//- Copy construct
exprResultDelayed(const exprResultDelayed&);
//- Construct from a dictionary
exprResultDelayed(const dictionary& dict);
//- Clone
virtual autoPtr<exprResult> clone() const
{
return autoPtr<exprResult>
(
new exprResultDelayed(*this)
);
}
//- Destructor
virtual ~exprResultDelayed() = default;
// Member Functions
//- The expression name
const word& name() const
{
return name_;
}
//- The initial value expression
const expressions::exprString& startupValueExpression() const
{
return startExpr_;
}
//- Update the read-value
// return true if there was a valid value.
// this does not do the work of setReadValue because we have no
// access to the Parser
bool updateReadValue(const scalar& timeVal);
//- Set the readValue with a calculated value
void setReadValue(const exprResult& val);
//- Add a stored value
void storeValue(const scalar& timeVal);
// Write
void writeDict(Ostream& os) const;
// Member Operators
//- Copy assignment
void operator=(const exprResultDelayed& rhs);
//- Copy assignment
void operator=(const exprResult& rhs);
//- Move assignment
void operator=(exprResult&& rhs);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace expressions
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline bool operator!=
(
const expressions::exprResultDelayed&,
const expressions::exprResultDelayed&
)
{
return false;
}
// IO Operators
Istream& operator>>(Istream& is, expressions::exprResultDelayed& data);
Ostream& operator<<(Ostream& os, const expressions::exprResultDelayed& data);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,334 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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 "exprResultGlobals.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
defineTypeNameAndDebug(exprResultGlobals, 0);
} // End namespace expressions
} // End namespace Foam
Foam::autoPtr<Foam::expressions::exprResultGlobals>
Foam::expressions::exprResultGlobals::singleton_;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::expressions::exprResultGlobals::exprResultGlobals
(
const objectRegistry& obr
)
:
regIOobject
(
IOobject
(
"exprResultGlobals",
obr.time().timeName(),
"expressions",
obr.time(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
)
),
timeIndex_(obr.time().timeIndex())
{
if (headerOk())
{
readData
(
readStream("exprResultGlobals", true)
);
}
}
Foam::expressions::exprResultGlobals::Table::Table()
:
HashPtrTable<exprResult>()
{}
Foam::expressions::exprResultGlobals::Table::Table(const Table& tbl)
:
HashPtrTable<exprResult>(tbl.capacity())
{
for (auto iter = tbl.cbegin(); iter != tbl.cend(); ++iter)
{
this->set(iter.key(), (*iter)->clone());
}
}
Foam::expressions::exprResultGlobals::Table::Table(Table&& tbl)
:
HashPtrTable<exprResult>(std::move(tbl))
{}
Foam::expressions::exprResultGlobals::Table::Table(Istream& is)
:
HashPtrTable<exprResult>(is)
{}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::expressions::exprResultGlobals::reset()
{
forAllIters(variables_, tablesIter)
{
forAllIters((*tablesIter), iter)
{
(*iter)->reset();
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::expressions::exprResultGlobals::writeData(Ostream& os) const
{
// Enforce ASCII to avoid any potential binary issues
const auto oldFmt = os.format(IOstream::ASCII);
os << variables_;
os.format(oldFmt);
return os.good();
}
bool Foam::expressions::exprResultGlobals::readData(Istream& is)
{
// Enforce ASCII to avoid any potential binary issues
const auto oldFmt = is.format(IOstream::ASCII);
is >> variables_;
is.format(oldFmt);
return !is.bad();
}
Foam::expressions::exprResultGlobals&
Foam::expressions::exprResultGlobals::New
(
const objectRegistry& obr
)
{
if (!singleton_)
{
singleton_.reset(new exprResultGlobals(obr));
}
if (singleton_->timeIndex_ != obr.time().timeIndex())
{
// Time changes, reset variables
singleton_->timeIndex_ = obr.time().timeIndex();
singleton_->reset();
}
return *singleton_;
}
Foam::expressions::exprResultGlobals::Table&
Foam::expressions::exprResultGlobals::getNamespace(const word& name)
{
return variables_[name];
}
const Foam::expressions::exprResult&
Foam::expressions::exprResultGlobals::get
(
const word& name,
const wordUList& scopes
) const
{
for (const word& scopeName : scopes)
{
const auto tableIter = variables_.find(scopeName);
if (tableIter.found())
{
const auto resultIter = (*tableIter).find(name);
if (resultIter.found())
{
return *(*resultIter);
}
}
#ifdef FULLDEBUG
else
{
WarningInFunction
<< "No scope " << scopeName << " for " << name << nl
<< "Known global scopes: " << variables_.sortToc() << nl;
}
#endif
}
return exprResult::null;
}
Foam::expressions::exprResult&
Foam::expressions::exprResultGlobals::addValue
(
const word& name,
const word& scope,
const exprResult& value,
const bool overwrite
)
{
Table& tbl = getOrCreateScope(scope);
auto iter = tbl.find(name);
if (!iter.found())
{
tbl.set(name, new exprResult(value));
iter = tbl.find(name);
}
else if (overwrite)
{
*(*iter) = value;
}
return *(*iter);
}
Foam::expressions::exprResult&
Foam::expressions::exprResultGlobals::addValue
(
const word& name,
const word& scope,
autoPtr<exprResult>& value,
const bool overwrite
)
{
Table& tbl = getOrCreateScope(scope);
if (overwrite || !tbl.found(name))
{
tbl.set(name, value);
}
return *tbl[name];
}
Foam::expressions::exprResult&
Foam::expressions::exprResultGlobals::addValue
(
const word& name,
const word& scope,
autoPtr<exprResult>&& value,
const bool overwrite
)
{
Table& tbl = getOrCreateScope(scope);
if (overwrite || !tbl.found(name))
{
tbl.set(name, value);
}
return *tbl[name];
}
Foam::expressions::exprResult&
Foam::expressions::exprResultGlobals::addValue
(
const dictionary& dict,
const word& scope,
const bool overwrite
)
{
word scopeName(scope);
const word name(dict.get<word>("globalName"));
if (scopeName.empty())
{
scopeName = dict.get<word>("globalScope");
}
if (dict.found("resultType"))
{
return addValue
(
name,
scopeName,
exprResult::New(dict),
overwrite
);
}
else
{
return addValue
(
name,
scopeName,
exprResult(dict, true),
overwrite
);
}
}
bool Foam::expressions::exprResultGlobals::removeValue
(
const word& name,
const word& scope
)
{
auto iter = variables_.find(scope);
return (iter.found() && (*iter).erase(name));
}
// ************************************************************************* //

View File

@ -0,0 +1,202 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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::exprResultGlobals
Description
A globally available registry of expression results
SourceFiles
exprResultGlobals.C
\*---------------------------------------------------------------------------*/
#ifndef expressions_exprResultGlobals_H
#define expressions_exprResultGlobals_H
#include "exprResult.H"
#include "autoPtr.H"
#include "HashPtrTable.H"
#include "regIOobject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
/*---------------------------------------------------------------------------*\
Class exprResultGlobals Declaration
\*---------------------------------------------------------------------------*/
class exprResultGlobals
:
public regIOobject
{
public:
// Public Classes
//- The table of results
class Table
:
public HashPtrTable<exprResult>
{
public:
Table();
Table(const Table& tbl);
Table(Table&& tbl);
Table(Istream& is);
};
private:
// Private Data
//- The scoped table of results
HashTable<Table> variables_;
//- The currently (or previously) used time-index
label timeIndex_;
//- Only one instance of this repository
static autoPtr<exprResultGlobals> singleton_;
// Private Member Functions
//- Construct
explicit exprResultGlobals(const objectRegistry& obr);
//- Reset all variables
void reset();
//- Get or create a table for the scope
Table& getOrCreateScope(const word& scope)
{
return variables_(scope);
}
public:
//- Runtime type information
TypeName("exprResultGlobals");
// Constructors
//- Get the singleton
static exprResultGlobals& New(const objectRegistry& obr);
//- Destructor
virtual ~exprResultGlobals() = default;
// Member Functions
//- Get an existing table for the namespace
Table& getNamespace(const word& name);
//- Return a global variable, if it exists, or a exprResult::null
const exprResult& get
(
const word& name,
const wordUList& scopes
) const;
//- Add named result to specified scope
exprResult& addValue
(
const word& name,
const word& scope,
const exprResult& value,
const bool overwrite = true
);
//- Add named result to specified scope
exprResult& addValue
(
const word& name,
const word& scope,
autoPtr<exprResult>& value,
const bool overwrite = true
);
//- Add named result to specified scope
exprResult& addValue
(
const word& name,
const word& scope,
autoPtr<exprResult>&& value,
const bool overwrite = true
);
//- Extract result from dictionary and add to the scope
//
// Controlled by dictionary entries:
// - globalName (mandatory)
// - globalScope (optional)
// - resultType (optional)
exprResult& addValue
(
const dictionary& dict,
const word& scope = "",
const bool overwrite = true
);
//- Remove named result from specified scope
// \return true if result was removed
bool removeValue
(
const word& name,
const word& scope
);
//- Write variables
virtual bool writeData(Ostream& os) const;
//- Read variables
virtual bool readData(Istream& os);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,790 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * Template Specializations * * * * * * * * * * * * //
namespace Foam
{
#undef defineExpressionMethod
#define defineExpressionMethod(Type, Var) \
template<> inline const Type& \
expressions::exprResult::singleValue::get<Type>() const \
{ \
return Var; \
} \
\
template<> inline const Type& \
expressions::exprResult::singleValue::set(const Type& val) \
{ \
Var = val; \
return Var; \
}
defineExpressionMethod(bool, bool_);
defineExpressionMethod(scalar, scalar_);
defineExpressionMethod(vector, vector_);
defineExpressionMethod(tensor, tensor_);
defineExpressionMethod(symmTensor, symmTensor_);
defineExpressionMethod(sphericalTensor, sphTensor_);
#undef defineExpressionMethod
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
inline bool Foam::expressions::exprResult::deleteChecked()
{
const bool ok = isType<Type>();
if (ok && fieldPtr_ != nullptr)
{
delete static_cast<Field<Type>*>(fieldPtr_);
fieldPtr_ = nullptr;
size_ = 0;
}
return ok;
}
template<class Type>
inline bool Foam::expressions::exprResult::createUniformChecked
(
const word& key,
const dictionary& dict,
const label len
)
{
const bool ok = isType<Type>();
if (ok)
{
uglyDelete();
const Type val(dict.get<Type>(key));
size_ = len;
fieldPtr_ = new Field<Type>(size_, val);
single_.set(val);
isUniform_ = true;
}
return ok;
}
template<class Type>
inline bool Foam::expressions::exprResult::createNonUniformChecked
(
const word& key,
const dictionary& dict,
const label len
)
{
const bool ok = isType<Type>();
if (ok)
{
uglyDelete();
size_ = len;
fieldPtr_ = new Field<Type>(key, dict, size_);
isUniform_ = false;
}
return ok;
}
template<class Type>
bool Foam::expressions::exprResult::getUniformChecked
(
exprResult& result,
const label size,
const bool noWarn,
const bool parRun
) const
{
if (!isType<Type>())
{
return false;
}
result.clear();
const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
const Type avg = (parRun ? gAverage(fld) : average(fld));
if (!noWarn)
{
const MinMax<Type> limits = (parRun ? gMinMax(fld) : minMax(fld));
if (limits.mag() > SMALL)
{
WarningInFunction
<< "Different min/max values: " << limits
<< " Using the average " << avg << nl;
}
}
result.setResult(avg, size);
return true;
}
template<class Type>
bool Foam::expressions::exprResult::plusEqChecked
(
const exprResult& b
)
{
const bool ok = isType<Type>();
if (ok)
{
*static_cast<Field<Type>*>(fieldPtr_)
+= *static_cast<const Field<Type>*>(b.fieldPtr_);
}
return ok;
}
template<class Type>
bool Foam::expressions::exprResult::multiplyEqChecked
(
const scalar& b
)
{
const bool ok = isType<Type>();
if (ok)
{
*static_cast<Field<Type>*>(fieldPtr_) *= b;
}
return ok;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::expressions::exprResult::exprResult(const Field<Type>& f)
:
exprResult()
{
DebugInFunction << nl;
setResult(f);
}
template<class Type>
Foam::expressions::exprResult::exprResult(Field<Type>&& f)
:
exprResult()
{
DebugInFunction << nl;
setResult(std::move(f));
}
template<class Type>
Foam::expressions::exprResult::exprResult(autoPtr<Type>& o)
:
exprResult()
{
setObjectResult(o);
}
template<class Type>
Foam::expressions::exprResult::exprResult(autoPtr<Type>&& o)
:
exprResult()
{
setObjectResult(o);
}
template<class Type>
Foam::expressions::exprResult::exprResult(const dimensioned<Type>& f)
:
exprResult()
{
DebugInFunction << nl;
setSingleValue(f.value());
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::expressions::exprResult::hasValue() const
{
return (!valType_.empty() && fieldPtr_ != nullptr);
}
inline const Foam::word& Foam::expressions::exprResult::valueType() const
{
return valType_;
}
inline bool Foam::expressions::exprResult::isPointValue
(
const bool isPointVal
) const
{
return isPointVal_ == isPointVal;
}
inline bool Foam::expressions::exprResult::isUniform() const
{
return isUniform_;
}
template<class Type>
inline bool Foam::expressions::exprResult::isType() const
{
return valType_ == pTraits<Type>::typeName;
}
inline bool Foam::expressions::exprResult::isBool() const
{
return valType_ == pTraits<bool>::typeName;
}
inline bool Foam::expressions::exprResult::isObject() const
{
return objectPtr_.valid();
}
inline Foam::label Foam::expressions::exprResult::size() const
{
return size_;
}
template<class Type>
void Foam::expressions::exprResult::setResult
(
const Field<Type>& val,
bool isPointVal
)
{
DebugInFunction << nl;
target().setResultImpl(val, isPointVal);
}
template<class Type>
void Foam::expressions::exprResult::setResult
(
Field<Type>&& val,
bool isPointVal
)
{
DebugInFunction << nl;
target().setResultImpl(val, isPointVal);
}
template<class Type>
void Foam::expressions::exprResult::setResultImpl
(
const Field<Type>& fld,
bool isPointVal
)
{
DebugInFunction << nl;
clear();
isUniform_ = false;
isPointVal_ = isPointVal;
size_ = fld.size();
valType_ = pTraits<Type>::typeName;
fieldPtr_ = new Field<Type>(fld);
DebugInFunction << nl;
}
template<class Type>
void Foam::expressions::exprResult::setResultImpl
(
Field<Type>&& fld,
bool isPointVal
)
{
DebugInFunction << nl;
clear();
isUniform_ = false;
isPointVal_ = isPointVal;
size_ = fld.size();
valType_ = pTraits<Type>::typeName;
fieldPtr_ = new Field<Type>(std::move(fld));
DebugInFunction << nl;
}
template<class Type>
void Foam::expressions::exprResult::setObjectResult(autoPtr<Type>& ap)
{
target().setObjectResultImpl(ap.ptr());
}
template<class Type>
void Foam::expressions::exprResult::setObjectResult(autoPtr<Type>&& ap)
{
target().setObjectResultImpl(ap.ptr());
}
template<class T>
void Foam::expressions::exprResult::setObjectResultImpl(T* ptr)
{
DebugInFunction << nl;
isUniform_ = false;
isPointVal_ = false;
size_ = ptr->size();
valType_ = ptr->typeName;
objectPtr_.reset(ptr);
}
template<class T>
void Foam::expressions::exprResult::setObjectResultImpl(autoPtr<T>& o)
{
setObjectResultImpl(o.ptr());
}
template<class T>
void Foam::expressions::exprResult::setObjectResultImpl(autoPtr<T>&& o)
{
setObjectResultImpl(o.ptr());
}
template<class Type>
void Foam::expressions::exprResult::setResult
(
Field<Type>* fldPtr,
bool isPointVal
)
{
target().setResultImpl(fldPtr, isPointVal);
}
template<class Type>
void Foam::expressions::exprResult::setResultImpl
(
Field<Type>* fldPtr,
bool isPointVal
)
{
DebugInFunction << nl;
clear();
isPointVal_ = isPointVal;
isUniform_ = false;
size_ = fldPtr->size();
valType_ = pTraits<Type>::typeName;
fieldPtr_ = fldPtr;
}
template<class Type>
void Foam::expressions::exprResult::setResult
(
const Type& val,
const label size
)
{
target().setResultImpl(val, size);
}
template<class Type>
void Foam::expressions::exprResult::setResultImpl
(
const Type& val,
const label len
)
{
DebugInFunction << nl;
clear();
isPointVal_ = false;
size_ = len;
valType_ = pTraits<Type>::typeName;
fieldPtr_ = new Field<Type>(size_, val);
isUniform_ = true;
single_.set(val);
}
template<class Type>
void Foam::expressions::exprResult::setSingleValue(const Type& val)
{
target().setSingleValueImpl(val);
}
template<class Type>
bool Foam::expressions::exprResult::writeValueChecked(Ostream& os) const
{
if (!isType<Type>())
{
return false;
}
if (this->size() <= 0)
{
if (isUniform_)
{
const Type& val = single_.get<Type>();
os.writeEntry("value", val);
}
else
{
// Zero-sized
const Field<Type> fld;
fld.writeEntry("value", os);
}
}
else
{
const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
if (isUniform_)
{
os.writeEntry("value", fld.first());
}
else
{
fld.writeEntry("value", os);
}
}
return true;
}
template<class Type>
bool Foam::expressions::exprResult::writeEntryChecked
(
const word& keyword,
Ostream& os
) const
{
if (!isType<Type>())
{
return false;
}
if (this->size() <= 0)
{
if (isUniform_ && is_contiguous<Type>::value)
{
const Type& val = single_.get<Type>();
os << "uniform " << val
<< token::END_STATEMENT << nl;
}
else
{
// Zero-sized
const Field<Type> fld;
fld.writeEntry(keyword, os);
}
}
else
{
const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
if (isUniform_ && is_contiguous<Type>::value)
{
os << "uniform " << fld.first()
<< token::END_STATEMENT << nl;
}
else
{
fld.writeEntry(keyword, os);
}
}
return true;
}
template<class Type>
bool Foam::expressions::exprResult::setAverageValueChecked()
{
if (!isType<Type>())
{
return false;
}
const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
const MinMax<Type> limits = gMinMax(fld);
isUniform_ = (limits.mag() <= SMALL);
const Type avg = limits.centre();
single_.set(avg);
return true;
}
template<class Type>
bool Foam::expressions::exprResult::duplicateFieldChecked(const void* ptr)
{
if (!isType<Type>())
{
return false;
}
if (fieldPtr_)
{
deleteChecked<Type>();
}
const Field<Type>& fld = *static_cast<const Field<Type>*>(ptr);
size_ = fld.size();
fieldPtr_ = new Field<Type>(fld);
return true;
}
template<class Type>
void Foam::expressions::exprResult::setSingleValueImpl(const Type& val)
{
DebugInFunction << nl;
clear();
isPointVal_ = false;
isUniform_ = true;
single_.set(val);
size_ = 1;
valType_ = pTraits<Type>::typeName;
fieldPtr_ = new Field<Type>(size_, val);
}
template<class Type>
inline Foam::tmp<Foam::Field<Type>>
Foam::expressions::exprResult::getResult(bool cacheCopy)
{
DebugInFunction << nl;
if (!isType<Type>())
{
FatalErrorInFunction
<< "The expected return type " << pTraits<Type>::typeName
<< " is different from the stored result type "
<< valType_ << nl << nl
<< exit(FatalError);
}
if (fieldPtr_ == nullptr)
{
FatalErrorInFunction
<< "Cannot create tmp from nullptr." << nl
<< "This error message should never appear!!" << nl
<< exit(FatalError);
}
Field<Type>* ptr = static_cast<Field<Type>*>(fieldPtr_);
if (cacheCopy)
{
// Leave field intact, return a duplicate field
// Or return reference instead??
return tmp<Field<Type>>::New(*ptr);
}
tmp<Field<Type>> result(ptr);
fieldPtr_ = nullptr; // Took ownership of field pointer
clear();
return result;
}
template<class Type>
inline const Foam::Field<Type>&
Foam::expressions::exprResult::cref() const
{
DebugInFunction << nl;
if (!isType<Type>())
{
FatalErrorInFunction
<< "The expected return type " << pTraits<Type>::typeName
<< " is different from the stored result type "
<< valType_ << nl << nl
<< exit(FatalError);
}
if (fieldPtr_ == nullptr)
{
FatalErrorInFunction
<< "Cannot return reference from nullptr." << nl
<< "This error message should never appear!!" << nl
<< exit(FatalError);
}
return *static_cast<const Field<Type>*>(fieldPtr_);
}
template<class Type>
inline Foam::Field<Type>&
Foam::expressions::exprResult::ref()
{
return const_cast<Field<Type>&>(this->cref<Type>());
}
template<class Type>
inline Foam::Field<Type>&
Foam::expressions::exprResult::getRef() const
{
return const_cast<Field<Type>&>(this->cref<Type>());
}
template<class Type>
inline Foam::tmp<Type>
Foam::expressions::exprResult::getObjectResult(bool cacheCopy)
{
DebugInFunction << nl;
if (!isType<Type>())
{
FatalErrorInFunction
<< "The expected return type " << pTraits<Type>::typeName
<< " is different from the stored result type "
<< valType_ << nl << nl
<< exit(FatalError);
}
Type* ptr = dynamic_cast<Type*>(objectPtr_.get());
if (!ptr)
{
WarningInFunction
<< "Cannot cast object pointer to " << pTraits<Type>::typeName
<< nl << nl;
return nullptr;
}
if (cacheCopy)
{
// Return duplicated content
return tmp<Type>::New(*ptr);
}
objectPtr_.release(); // Take ownership in ptr
clear();
return tmp<Type>(ptr);
}
template<template<class> class BinaryOp, class Type>
inline Type Foam::expressions::exprResult::getReduced
(
const BinaryOp<Type>& bop,
const Type& initial
)
{
if (!isType<Type>())
{
FatalErrorInFunction
<< "The expected return type " << pTraits<Type>::typeName
<< " is different from the stored result type "
<< valType_ << nl << nl
<< exit(FatalError);
}
Type result = initial;
const Field<Type>& fld = *static_cast<Field<Type>*>(fieldPtr_);
for (const Type& val : fld)
{
result = bop(result, val);
}
return returnReduce(result, bop);
}
// ************************************************************************* //

View File

@ -0,0 +1,207 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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 "exprResultStack.H"
#include "vector.H"
#include "tensor.H"
#include "symmTensor.H"
#include "sphericalTensor.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
defineTypeNameAndDebug(exprResultStack, 0);
addToRunTimeSelectionTable
(
exprResult,
exprResultStack,
dictionary
);
addToRunTimeSelectionTable
(
exprResult,
exprResultStack,
empty
);
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::expressions::exprResultStack::exprResultStack()
:
expressions::exprResult()
{
needsReset(true); // Requires reset every timestep to work
}
Foam::expressions::exprResultStack::exprResultStack
(
const exprResultStack& rhs
)
:
expressions::exprResult(rhs)
{
needsReset(true); // Requires reset every timestep to work
}
Foam::expressions::exprResultStack::exprResultStack
(
const dictionary &dict
)
:
expressions::exprResult(dict)
{
needsReset(true); // Requires reset every timestep to work
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::expressions::exprResult
Foam::expressions::exprResultStack::pop()
{
exprResult result;
if (this->size() <= 0)
{
FatalErrorInFunction
<< "Trying to pop result from a empty queue" << endl
<< abort(FatalError);
return result;
}
const bool ok =
(
popChecked<scalar>(result)
|| popChecked<vector>(result)
|| popChecked<tensor>(result)
|| popChecked<symmTensor>(result)
|| popChecked<sphericalTensor>(result)
);
if (!ok)
{
FatalErrorInFunction
<< "Unsupported value type " << valueType() << nl
<< abort(FatalError);
}
return result;
}
void Foam::expressions::exprResultStack::push(const exprResult& result)
{
DebugInFunction << nl << "Pushing: " << result << nl;
if (!hasValue())
{
// This is the first push
exprResult::operator=(result);
}
else
{
if (valueType() != result.valueType())
{
FatalErrorInFunction
<< "Type of pushed value " << result.valueType()
<< " is not the expected type " << valueType() << nl
<< abort(FatalError);
}
const bool ok =
(
pushChecked<scalar>(result)
|| pushChecked<vector>(result)
|| pushChecked<tensor>(result)
|| pushChecked<symmTensor>(result)
|| pushChecked<sphericalTensor>(result)
);
if (!ok)
{
FatalErrorInFunction
<< "Unsupported value type " << valueType() << nl
<< abort(FatalError);
}
}
DebugInFunction << "After push: " << *this << nl;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::expressions::exprResultStack::operator=
(
const exprResultStack& rhs
)
{
if (this == &rhs)
{
return; // Self-assignment is a no-op
}
static_cast<exprResult&>(*this) = rhs;
}
void Foam::expressions::exprResultStack::operator=
(
const exprResult& rhs
)
{
if (this == &rhs)
{
return; // Self-assignment is a no-op
}
DebugInFunction << nl;
exprResult exprValue
(
// Issue warning if the other result is not really uniform
rhs.getUniform(1, false)
);
this->push(exprValue);
}
// ************************************************************************* //

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) 2012-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::exprResultStack
Description
A stack of polymorphic fields.
Can be used to build a list of results one at a time.
SourceFiles
exprResultStack.C
exprResultStackTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef expressions_exprResultStack_H
#define expressions_exprResultStack_H
#include "exprResult.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
/*---------------------------------------------------------------------------*\
Class exprResultStack Declaration
\*---------------------------------------------------------------------------*/
class exprResultStack
:
public expressions::exprResult
{
// Private Data
//- Type-checked pop value.
// \return True if the type check was satisfied
template<class T>
bool popChecked(exprResult& result);
//- Type-checked push value.
// \return True if the type check was satisfied
template<class T>
bool pushChecked(const exprResult& result);
public:
//- Runtime type information
TypeName("exprResultStack");
// Constructors
//- Construct null
exprResultStack();
//- Copy construct
exprResultStack(const exprResultStack& rhs);
//- Construct from a dictionary
explicit exprResultStack(const dictionary& dict);
// Selectors
virtual autoPtr<exprResult> clone() const
{
return autoPtr<exprResult>
(
new exprResultStack(*this)
);
}
//- Destructor
virtual ~exprResultStack() = default;
// Member Functions
//- Pop the last value as an expression result
exprResult pop();
//- Push an expression result value
void push(const exprResult& result);
// Member Operators
//- Copy assignment
void operator=(const exprResultStack& rhs);
//- Copy assignment
void operator=(const exprResult& rhs);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "exprResultStackTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,84 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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/>.
\*---------------------------------------------------------------------------*/
template<class T>
bool Foam::expressions::exprResultStack::pushChecked
(
const exprResult& result
)
{
if (!isType<T>())
{
return false;
}
// The value to push
T val(Zero);
const Field<T>& resultField = result.cref<T>();
if (!resultField.empty())
{
val = resultField.first();
}
this->ref<T>().append(val);
return true;
}
template<class T>
bool Foam::expressions::exprResultStack::popChecked
(
exprResult& result
)
{
if (!isType<T>())
{
return false;
}
// The popped value
T val(Zero);
Field<T>& oldField = this->ref<T>();
if (!oldField.empty())
{
val = oldField.last();
oldField.resize(oldField.size()-1);
}
result.setSingleValue(val);
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,165 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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 "exprResultStored.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
defineTypeNameAndDebug(exprResultStored, 0);
addToRunTimeSelectionTable
(
exprResult,
exprResultStored,
dictionary
);
addToRunTimeSelectionTable
(
exprResult,
exprResultStored,
empty
);
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::expressions::exprResultStored::exprResultStored()
:
expressions::exprResult(),
name_("none"),
startExpr_()
{}
Foam::expressions::exprResultStored::exprResultStored
(
const exprResultStored& rhs
)
:
expressions::exprResult(rhs),
name_(rhs.name_),
startExpr_(rhs.startExpr_)
{}
Foam::expressions::exprResultStored::exprResultStored
(
const dictionary& dict
)
:
expressions::exprResult(dict.subOrEmptyDict("value")),
name_(dict.get<word>("name")),
startExpr_(dict.get<string>("initialValue"), dict)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::expressions::exprResultStored::writeDict(Ostream& os) const
{
os.beginBlock();
os.writeEntry("name", name_);
os.writeEntry("initialValue", startExpr_);
os.writeKeyword("value");
os << static_cast<const exprResult&>(*this);
os.endBlock();
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::expressions::exprResultStored::operator=
(
const exprResultStored& rhs
)
{
if (this == &rhs)
{
return; // Self-assignment is a no-op
}
this->exprResult::operator=(rhs);
name_ = rhs.name_;
startExpr_ = rhs.startExpr_;
}
void Foam::expressions::exprResultStored::operator=
(
const exprResult& rhs
)
{
if (this == &rhs)
{
return; // Self-assignment is a no-op
}
this->exprResult::operator=(rhs);
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>
(
Istream& is,
expressions::exprResultStored& data
)
{
dictionary dict(is);
data = expressions::exprResultStored(dict);
return is;
}
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const expressions::exprResultStored& data
)
{
data.writeDict(os);
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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::exprResultStored
Description
An exprResult with persistence.
\heading Dictionary parameters
\table
Property | Description | Required | Default
name | The result name | yes |
initialValue | The initial value | yes |
value | The expression result (dictionary) | no |
\endtable
SourceFiles
StoredExpressionResult.C
\*---------------------------------------------------------------------------*/
#ifndef expressions_exprResultStored_H
#define expressions_exprResultStored_H
#include "exprResult.H"
#include "exprString.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
/*---------------------------------------------------------------------------*\
Class exprResultStored Declaration
\*---------------------------------------------------------------------------*/
class exprResultStored
:
public expressions::exprResult
{
// Private Data
//- The name of the expression
word name_;
//- The initial value expression
expressions::exprString startExpr_;
protected:
// Protected Member Functions
//- Reset at new timestep - disabling locally
virtual void resetImpl() {}
public:
//- Runtime type information
TypeName("exprResultStored");
// Constructors
//- Construct null
exprResultStored();
//- Copy construct
exprResultStored(const exprResultStored& rhs);
//- Construct from a dictionary
explicit exprResultStored(const dictionary& dict);
// Selectors
virtual autoPtr<exprResult> clone() const
{
return autoPtr<exprResult>
(
new exprResultStored(*this)
);
}
//- Destructor
virtual ~exprResultStored() = default;
// Member Functions
//- The name of the expression
const word& name() const
{
return name_;
}
//- The initial value expression
const expressions::exprString& initialValueExpression() const
{
return startExpr_;
}
void writeDict(Ostream& os) const;
// Member Operators
//- Copy assignment
void operator=(const exprResultStored& rhs);
//- Copy assignment
void operator=(const exprResult& rhs);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace expressions
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IO Operators
Istream& operator>>(Istream& is, expressions::exprResultStored& data);
Ostream& operator<<(Ostream& is, const expressions::exprResultStored& data);
// Comparison
inline bool operator!=
(
const expressions::exprResultStored& a,
const expressions::exprResultStored& b
)
{
return (&a != &b);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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 "exprResultStoredStack.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
defineTypeNameAndDebug(exprResultStoredStack,0);
addToRunTimeSelectionTable
(
exprResult,
exprResultStoredStack,
dictionary
);
addToRunTimeSelectionTable
(
exprResult,
exprResultStoredStack,
empty
);
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::expressions::exprResultStoredStack::exprResultStoredStack()
:
expressions::exprResultStack()
{
needsReset(false); // Override parent: does not reset every timestep
}
Foam::expressions::exprResultStoredStack::exprResultStoredStack
(
const exprResultStoredStack& rhs
)
:
expressions::exprResultStack(rhs)
{
needsReset(false); // Override parent: does not reset every timestep
}
Foam::expressions::exprResultStoredStack::exprResultStoredStack
(
const dictionary& dict
)
:
expressions::exprResultStack(dict)
{
needsReset(false); // Override parent: does not reset every timestep
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::expressions::exprResultStoredStack::operator=
(
const exprResultStoredStack& rhs
)
{
if (this == &rhs)
{
return; // Self-assignment is a no-op
}
exprResultStack::operator=(rhs);
}
// ************************************************************************* //

View File

@ -0,0 +1,115 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-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::exprResultStoredStack
Description
An exprResultStack with persistence.
SourceFiles
exprResultStoredStack.C
\*---------------------------------------------------------------------------*/
#ifndef expressions_exprResultStoredStack_H
#define expressions_exprResultStoredStack_H
#include "exprResultStack.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
/*---------------------------------------------------------------------------*\
Class exprResultStoredStack Declaration
\*---------------------------------------------------------------------------*/
class exprResultStoredStack
:
public expressions::exprResultStack
{
protected:
// Protected Member Functions
//- Reset at new timestep - disabling locally
virtual void resetImpl() {}
public:
//- Runtime type information
TypeName("exprResultStoredStack");
// Constructors
//- Construct null
exprResultStoredStack();
//- Copy construct
exprResultStoredStack(const exprResultStoredStack& rhs);
//- Construct from a dictionary
explicit exprResultStoredStack(const dictionary& dict);
// Selectors
virtual autoPtr<exprResult> clone() const
{
return autoPtr<exprResult>
(
new exprResultStoredStack(*this)
);
}
//- Destructor
virtual ~exprResultStoredStack() = default;
// Member Operators
//- Copy assignment
void operator=(const exprResultStoredStack& rhs);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //