Commit 5579e7a6 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: improve some efficiency in expressions

- use refPtr to simplify some logic.
- avoid copying field if an average will be used
- initialize geometric fields with a uniform value instead of Zero
- minor tweak of method names

- apply bugfix #1889 (longer description elsewhere)
parent 51b24902
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2010-2018 Bernhard Gschaider
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -284,7 +284,7 @@ public:
//- Return the expression result as a tmp field
template<class Type>
tmp<Field<Type>> getResult(bool isPointVal=false);
tmp<Field<Type>> getResult(bool wantPointData=false);
//- The result type as word - same as result().valueType()
virtual word getResultType() const
......@@ -388,7 +388,7 @@ public:
bool isLocalVariable
(
const word& name,
bool isPointVal,
bool wantPointData = false,
label expectedSize = -1
) const;
......@@ -424,7 +424,7 @@ public:
evaluate
(
const expressions::exprString& expr,
bool isPointVal = false
bool wantPointData = false
);
//- Evaluate the expression and return a single value
......@@ -432,7 +432,7 @@ public:
inline Type evaluateUniform
(
const expressions::exprString& expr,
bool isPointVal = false
bool wantPointData = false
);
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -75,12 +75,12 @@ template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::expressions::exprDriver::evaluate
(
const expressions::exprString& expr,
bool isPointVal
bool wantPointData
)
{
parse(expr);
return getResult<Type>(isPointVal);
return getResult<Type>(wantPointData);
}
......@@ -89,7 +89,7 @@ template<class Type>
inline Type Foam::expressions::exprDriver::evaluateUniform
(
const expressions::exprString& expr,
bool isPointVal
bool wantPointData
)
{
parse(expr);
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -145,13 +145,13 @@ Type Foam::expressions::exprDriver::exprDriver::weightedSum
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::expressions::exprDriver::getResult(bool isPointVal)
Foam::expressions::exprDriver::getResult(bool wantPointData)
{
if (!result_.isPointValue(isPointVal))
if (!result_.isPointData(wantPointData))
{
FatalErrorInFunction
<< "Expected a" << (isPointVal ? " point" : "")
<< " field, but found a" << (!isPointVal ? " point" : "")
<< "Expected a" << (wantPointData ? " point" : "")
<< " field, but found a" << (!wantPointData ? " point" : "")
<< " field" << nl
<< exit(FatalError);
}
......@@ -166,15 +166,16 @@ template<class Type>
bool Foam::expressions::exprDriver::isLocalVariable
(
const word& name,
bool isPointVal,
bool wantPointData,
label expectedSize
) const
{
DebugInfo
<< "Looking for local" << (isPointVal ? " point" : "")
<< "Looking for local" << (wantPointData ? " point" : "")
<< " field name:" << name << " type:"
<< pTraits<Type>::typeName << " size:" << expectedSize;
bool good = hasVariable(name);
if (good)
......@@ -182,10 +183,11 @@ bool Foam::expressions::exprDriver::isLocalVariable
const exprResult& var = variable(name);
DebugInfo
<< " - found (" << var.valueType() << ' ' << var.isPointValue() << ')';
<< " - found (" << var.valueType() << ' '
<< var.isPointData() << ')';
good = (var.isType<Type>() && var.isPointValue(isPointVal));
good = (var.isType<Type>() && var.isPointData(wantPointData));
// Do size checking if requested
if (good && expectedSize >= 0)
......
......@@ -166,7 +166,7 @@ bool Foam::expressions::exprResult::getUniformCheckedBool
// TODO?
}
result.setResult(avg, size);
result.setResult<Type>(avg, size);
return true;
}
......@@ -207,7 +207,7 @@ Foam::expressions::exprResult::exprResult()
refCount(),
valType_(),
isUniform_(false),
isPointVal_(false),
isPointData_(false),
noReset_(false),
needsReset_(false),
size_(0),
......@@ -245,7 +245,7 @@ Foam::expressions::exprResult::exprResult
refCount(),
valType_(dict.getOrDefault<word>("valueType", "")),
isUniform_(dict.getOrDefault("isSingleValue", uniform)),
isPointVal_(dict.getOrDefault("isPointValue", false)),
isPointData_(dict.getOrDefault("isPointValue", false)),
noReset_(dict.getOrDefault("noReset", false)),
needsReset_(false),
size_(0),
......@@ -268,20 +268,21 @@ Foam::expressions::exprResult::exprResult
const bool ok =
(
readChecked<bool>("value", dict, len, uniform)
|| readChecked<scalar>("value", dict, len, uniform)
// Just use <scalar> for <label>?
readChecked<scalar>("value", dict, len, uniform)
|| readChecked<vector>("value", dict, len, uniform)
|| readChecked<tensor>("value", dict, len, uniform)
|| readChecked<symmTensor>("value", dict, len, uniform)
|| readChecked<sphericalTensor>("value", dict, len, uniform)
|| readChecked<bool>("value", dict, len, uniform)
);
if (!ok)
{
if (valType_.empty())
{
// For the error message only
valType_ = "None";
// For error message only
valType_ = "none";
}
FatalErrorInFunction
......@@ -316,12 +317,13 @@ Foam::expressions::exprResult::New
if (!cstrIter.found())
{
FatalErrorInLookup
FatalIOErrorInLookup
(
dict,
"resultType",
resultType,
*emptyConstructorTablePtr_
) << exit(FatalError);
) << exit(FatalIOError);
}
DebugInfo
......@@ -335,12 +337,13 @@ Foam::expressions::exprResult::New
if (!cstrIter.found())
{
FatalErrorInLookup
FatalIOErrorInLookup
(
dict,
"resultType",
resultType,
*dictionaryConstructorTablePtr_
) << exit(FatalError);
) << exit(FatalIOError);
}
DebugInfo
......@@ -384,7 +387,7 @@ void Foam::expressions::exprResult::clear()
{
uglyDelete();
valType_.clear();
objectPtr_.reset();
objectPtr_.reset(nullptr);
size_ = 0;
}
......@@ -496,7 +499,7 @@ void Foam::expressions::exprResult::operator=(const exprResult& rhs)
valType_ = rhs.valType_;
isUniform_ = rhs.isUniform_;
isPointVal_ = rhs.isPointVal_;
isPointData_ = rhs.isPointData_;
single_ = rhs.single_;
if (rhs.fieldPtr_)
......@@ -538,7 +541,7 @@ void Foam::expressions::exprResult::operator=(exprResult&& rhs)
valType_ = rhs.valType_;
isUniform_ = rhs.isUniform_;
isPointVal_ = rhs.isPointVal_;
isPointData_ = rhs.isPointData_;
noReset_ = rhs.noReset_;
needsReset_ = rhs.needsReset_;
size_ = rhs.size_;
......@@ -596,7 +599,7 @@ void Foam::expressions::exprResult::writeDict
}
os.writeEntry("resultType", valueType());
os.writeEntryIfDifferent<Switch>("noReset_", false, noReset_);
os.writeEntryIfDifferent<Switch>("noReset", false, noReset_);
if (fieldPtr_ == nullptr)
{
......@@ -606,7 +609,7 @@ void Foam::expressions::exprResult::writeDict
{
os.writeEntry("valueType", valType_);
os.writeEntryIfDifferent<Switch>("isPointValue", false, isPointVal_);
os.writeEntryIfDifferent<Switch>("isPointValue", false, isPointData_);
os.writeEntry<Switch>("isSingleValue", isUniform_);
const bool ok =
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -89,8 +89,8 @@ class exprResult
//- Is single, uniform value (can be a non-field)
bool isUniform_;
//- Is a point value
bool isPointVal_;
//- Represents point data
bool isPointData_;
//- Whether or not the variable will be reset
bool noReset_;
......@@ -98,7 +98,7 @@ class exprResult
//- Allow override of noReset_, but only accessible for subclasses
bool needsReset_;
//- Size of field or object
//- Size (length) of field or object
label size_;
//- A %union of single values, including standard VectorSpace types
......@@ -112,7 +112,7 @@ class exprResult
symmTensor symmTensor_;
sphericalTensor sphTensor_;
//- Construct null, zero-initialized
//- Default construct, zero-initialized
singleValue();
//- Copy construct
......@@ -126,21 +126,24 @@ class exprResult
inline const T& get() const
{
WarningInFunction
<< "Not implemented for type " << pTraits<T>::typeName << nl;
<< "Not implemented for type "
<< pTraits<T>::typeName << nl;
return pTraits<T>::zero;
}
//- Set new value for specified type. Returns updated value.
//- Set new value for specified type.
// \return updated value
template<class T>
inline const T& set(const T& val)
{
WarningInFunction
<< "Not implemented for type " << pTraits<T>::typeName << nl;
<< "Not implemented for type "
<< pTraits<T>::typeName << nl;
return val;
}
};
//- The single value
//- The single value representation
singleValue single_;
//- Allocated plain field (eg, scalarField)
......@@ -182,7 +185,7 @@ class exprResult
const bool parRun
) const;
//- Type-checked retrieval of uniform field from current results
//- Type-checked retrieval of \c bool uniform field from current result
// \return True if the type check was satisfied
bool getUniformCheckedBool
(
......@@ -233,13 +236,13 @@ class exprResult
template<class Type>
inline void setResultImpl(Field<Type>*, bool isPointVal=false);
inline void setResultImpl(Field<Type>*, bool wantPointData=false);
template<class Type>
inline void setResultImpl(const Field<Type>&, bool isPointVal=false);
inline void setResultImpl(const Field<Type>&, bool wantPointData=false);
template<class Type>
inline void setResultImpl(Field<Type>&&, bool isPointVal=false);
inline void setResultImpl(Field<Type>&&, bool wantPointData=false);
template<class Type>
inline void setResultImpl(const Type& val, const label len);
......@@ -250,19 +253,13 @@ class exprResult
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; }
inline virtual expressions::exprResult& target() { return *this; }
//- Reset at new timestep according to the derived class type
virtual void resetImpl();
......@@ -309,7 +306,7 @@ public:
// Constructors
//- Construct null
//- Default construct
exprResult();
//- Copy construct
......@@ -328,23 +325,19 @@ public:
//- Construct by copying a field
template<class Type>
exprResult(const Field<Type>& f);
explicit exprResult(const Field<Type>& fld);
//- Construct by moving a field
template<class Type>
exprResult(Field<Type>&& f);
//- Construct for an IOobject
template<class Type>
exprResult(autoPtr<Type>& ap);
explicit exprResult(Field<Type>&& fld);
//- Construct for an IOobject
template<class Type>
exprResult(autoPtr<Type>&& ap);
explicit exprResult(autoPtr<Type>&& obj);
//- Construct from a dimensioned value
template<class Type>
exprResult(const dimensioned<Type>& f);
explicit exprResult(const dimensioned<Type>& dt);
#undef exprResult_Construct
#define exprResult_Construct(Type) \
......@@ -390,8 +383,9 @@ public:
//- 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 representing point data,
//- or test for same value as wantPointData argument
inline bool isPointData(const bool wantPointData=true) const;
//- True if single, uniform value
inline bool isUniform() const;
......@@ -400,6 +394,12 @@ public:
template<class Type>
inline bool isType() const;
//- Return a single value when isUniform() is true,
//- or Zero when it is non-uniform or if the type mismatches,
//- which means that it can generally be considered as failsafe.
template<class Type>
inline Type getValue() const;
//- True if valueType is a bool
inline bool isBool() const;
......@@ -436,15 +436,15 @@ public:
//- Set result field, taking ownership of the pointer
template<class Type>
inline void setResult(Field<Type>*, bool isPointVal=false);
inline void setResult(Field<Type>*, bool wantPointData=false);
//- Set result field, taking copy of the field contents
template<class Type>
inline void setResult(const Field<Type>& fld, bool isPointVal=false);
inline void setResult(const Field<Type>&, bool wantPointData=false);
//- Set result field, moving field contents
template<class Type>
inline void setResult(Field<Type>&&, bool isPointVal=false);
inline void setResult(Field<Type>&&, bool wantPointData=false);
//- Set uniform result field of given size
template<class Type>
......@@ -454,11 +454,9 @@ public:
template<class Type>
inline void setSingleValue(const Type& val);
//- Set result object
template<class Type>
inline void setObjectResult(autoPtr<Type>& o);
template<class Type>
inline void setObjectResult(autoPtr<Type>&& o);
inline void setObjectResult(autoPtr<Type>&& obj);
// Access/Get results
......
......@@ -33,18 +33,18 @@ namespace Foam
namespace expressions
{
#undef defineExpressionMethod
#define defineExpressionMethod(Type, Var) \
#define defineExpressionMethod(Type, Member) \
template<> \
inline const Type& exprResult::singleValue::get<Type>() const \
{ \
return Var; \
return Member; \
} \
\
template<> \
inline const Type& exprResult::singleValue::set(const Type& val) \
{ \
Var = val; \
return Var; \
Member = val; \
return Member; \
}
defineExpressionMethod(bool, bool_);
......@@ -67,6 +67,7 @@ template<class Type>
inline bool Foam::expressions::exprResult::deleteChecked()
{
const bool ok = isType<Type>();
if (ok && fieldPtr_ != nullptr)
{
delete static_cast<Field<Type>*>(fieldPtr_);
......@@ -88,6 +89,7 @@ inline bool Foam::expressions::exprResult::readChecked
)
{
const bool ok = isType<Type>();
if (ok)
{
uglyDelete();
......@@ -190,52 +192,43 @@ bool Foam::expressions::exprResult::multiplyEqChecked
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::expressions::exprResult::exprResult(const Field<Type>& f)
Foam::expressions::exprResult::exprResult(const Field<Type>& fld)
:
exprResult()
{
DebugInFunction << nl;
setResult(f);
setResult(fld);
}
template<class Type>
Foam::expressions::exprResult::exprResult(Field<Type>&& f)
Foam::expressions::exprResult::exprResult(Field<Type>&& fld)
:
exprResult()
{
DebugInFunction << nl;
setResult(std::move(f));
setResult(std::move(fld));
}
template<class Type>
Foam::expressions::exprResult::exprResult(autoPtr<Type>& o)
Foam::expressions::exprResult::exprResult(autoPtr<Type>&& obj)
:
exprResult()
{
setObjectResult(o);
setObjectResult(std::move(obj));
}
template<class Type>
Foam::expressions::exprResult::exprResult(autoPtr<Type>&& o)
:
exprResult()
{
setObjectResult(o);
}
template<class Type>
Foam::expressions::exprResult::exprResult(const dimensioned<Type>& f)
Foam::expressions::exprResult::exprResult(const dimensioned<Type>& dt)
:
exprResult()
{
DebugInFunction << nl;
setSingleValue(f.value());
setSingleValue(dt.value());
}
......@@ -253,12 +246,12 @@ inline const Foam::word& Foam::expressions::exprResult::valueType() const
}
inline bool Foam::expressions::exprResult::isPointValue
inline bool Foam::expressions::exprResult::isPointData
(
const bool isPointVal
const bool wantPointData
) const
{
return isPointVal_ == isPointVal;
return isPointData_ == wantPointData;
}
......@@ -275,6 +268,18 @@ inline bool Foam::expressions::exprResult::isType() const
}
template<class Type>
inline Type Foam::expressions::exprResult::getValue() const
{
if (!isUniform_ || !isType<Type>())
{
return Zero;
}
return single_.get<Type>();
}
inline bool Foam::expressions::exprResult::isBool() const
{
return valType_ == pTraits<bool>::typeName;
......@@ -297,12 +302,12 @@ template<class Type>
void Foam::expressions::exprResult::setResult
(
const Field<Type>& val,
bool isPointVal
bool wantPointData
)
{
DebugInFunction << nl;
target().setResultImpl(val, isPointVal);
target().setResultImpl(val, wantPointData);
}