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)
This commit is contained in:
Mark Olesen
2020-10-23 16:38:00 +02:00
parent 51b2490258
commit 5579e7a62b
16 changed files with 282 additions and 286 deletions

View File

@ -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
);

View File

@ -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);

View File

@ -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)

View File

@ -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 =

View File

@ -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);
explicit exprResult(Field<Type>&& fld);
//- Construct for an IOobject
template<class Type>
exprResult(autoPtr<Type>& ap);
//- 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

View File

@ -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);
}
@ -310,12 +315,12 @@ template<class Type>
void Foam::expressions::exprResult::setResult
(
Field<Type>&& val,
bool isPointVal
bool wantPointData
)
{
DebugInFunction << nl;
target().setResultImpl(val, isPointVal);
target().setResultImpl(val, wantPointData);
}
@ -323,7 +328,7 @@ template<class Type>
void Foam::expressions::exprResult::setResultImpl
(
const Field<Type>& fld,
bool isPointVal
bool wantPointData
)
{
DebugInFunction << nl;
@ -331,7 +336,7 @@ void Foam::expressions::exprResult::setResultImpl
clear();
isUniform_ = false;
isPointVal_ = isPointVal;
isPointData_ = wantPointData;
size_ = fld.size();
valType_ = pTraits<Type>::typeName;
@ -345,7 +350,7 @@ template<class Type>
void Foam::expressions::exprResult::setResultImpl
(
Field<Type>&& fld,
bool isPointVal
bool wantPointData
)
{
DebugInFunction << nl;
@ -353,7 +358,7 @@ void Foam::expressions::exprResult::setResultImpl
clear();
isUniform_ = false;
isPointVal_ = isPointVal;
isPointData_ = wantPointData;
size_ = fld.size();
valType_ = pTraits<Type>::typeName;
@ -364,44 +369,26 @@ void Foam::expressions::exprResult::setResultImpl
template<class Type>
void Foam::expressions::exprResult::setObjectResult(autoPtr<Type>& ap)
void Foam::expressions::exprResult::setObjectResult(autoPtr<Type>&& obj)
{
target().setObjectResultImpl(ap.ptr());
}
template<class Type>
void Foam::expressions::exprResult::setObjectResult(autoPtr<Type>&& ap)
{
target().setObjectResultImpl(ap.ptr());
target().setObjectResultImpl(obj.ptr()); // release()
}
template<class T>
void Foam::expressions::exprResult::setObjectResultImpl(T* ptr)
{
DebugInFunction << nl;
clear();
isUniform_ = false;
isPointVal_ = false;
isPointData_ = false;
if (ptr != nullptr)
{
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());
}
@ -409,10 +396,10 @@ template<class Type>
void Foam::expressions::exprResult::setResult
(
Field<Type>* fldPtr,
bool isPointVal
bool wantPointData
)
{
target().setResultImpl(fldPtr, isPointVal);
target().setResultImpl(fldPtr, wantPointData);
}
@ -420,20 +407,21 @@ template<class Type>
void Foam::expressions::exprResult::setResultImpl
(
Field<Type>* fldPtr,
bool isPointVal
bool wantPointData
)
{
DebugInFunction << nl;
clear();
isPointVal_ = isPointVal;
isUniform_ = false;
isPointData_ = wantPointData;
if (fldPtr != nullptr)
{
size_ = fldPtr->size();
valType_ = pTraits<Type>::typeName;
fieldPtr_ = fldPtr;
}
}
template<class Type>
@ -458,7 +446,7 @@ void Foam::expressions::exprResult::setResultImpl
clear();
isPointVal_ = false;
isPointData_ = false;
size_ = len;
valType_ = pTraits<Type>::typeName;
@ -653,8 +641,8 @@ void Foam::expressions::exprResult::setSingleValueImpl(const Type& val)
clear();
isPointVal_ = false;
isUniform_ = true;
isPointData_ = false;
single_.set(val);
size_ = 1;

View File

@ -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.
@ -78,7 +78,7 @@ public:
// Constructors
//- Construct null
//- Default construct
exprResultStack();
//- Copy construct

View File

@ -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,7 +89,7 @@ public:
// Constructors
//- Construct null
//- Default construct
exprResultStored();
//- Copy construct

View File

@ -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.
@ -71,7 +71,7 @@ public:
// Constructors
//- Construct null
//- Default construct
exprResultStoredStack();
//- Copy construct

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,43 +34,42 @@ Foam::expressions::fieldExpr::parseDriver::getField
const word& name
) const
{
bool isPointVal = false;
bool isUniformVal = false;
bool hasPointData = false;
tmp<Field<Type>> tfield;
refPtr<expressions::exprResult> tvar;
if (hasVariable(name) && variable(name).isType<Type>())
{
const expressions::exprResult& var = variable(name);
isPointVal = var.isPointValue();
isUniformVal = var.isUniform();
tfield = var.cref<Type>().clone();
tvar.cref(variable(name));
hasPointData = tvar().isPointData();
}
if (tfield.valid())
{
const label fldLen = tfield().size();
const label len = (isPointVal ? this->pointSize() : this->size());
if (returnReduce((fldLen == len), andOp<bool>()))
if (tvar.valid())
{
return tfield;
const auto& var = tvar.cref();
const Field<Type>& vals = var.cref<Type>();
const label len = (hasPointData ? this->pointSize() : this->size());
if (returnReduce((vals.size() == len), andOp<bool>()))
{
// Return a copy of the field
return tmp<Field<Type>>::New(vals);
}
if (!isUniformVal)
if (!var.isUniform())
{
WarningInFunction
<< "Variable " << name
<< " does not fit the size and is not a uniform value." << nl
<< "Using average value" << endl;
<< " is nonuniform and does not fit the size"
<< ". Using average" << endl;
}
return tmp<Field<Type>>::New(this->size(), gAverage(tfield));
return tmp<Field<Type>>::New(this->size(), gAverage(vals));
}
return tfield;
return nullptr;
}

View File

@ -163,6 +163,7 @@ protected:
}
//- Default boundary type for volume fields is zeroGradient
//- since they are essentially just internal fields.
template<class Type>
static inline word defaultBoundaryType
(
@ -211,8 +212,8 @@ protected:
bool isGlobalVariable
(
const word& name,
bool isPointVal,
label expectedSize = -1
const bool wantPointData = false,
const label expectedSize = -1
) const;
//- Return the global variable if available or a null result
@ -226,8 +227,8 @@ protected:
bool isField
(
const word& name,
bool isPointVal = false,
label expectSize = -1 //!< ignored
const bool wantPointData = false,
const label expectSize = -1 //!< ignored
) const;
@ -236,8 +237,8 @@ protected:
inline tmp<GeomField> getOrReadField
(
const word& name,
bool mandatory = true,
bool getOldTime = false
const bool mandatory = true,
const bool getOldTime = false
);
//- Retrieve point field from memory or disk
@ -245,8 +246,8 @@ protected:
inline tmp<GeomField> getOrReadPointField
(
const word& name,
bool mandatory = true,
bool getOldTime = false
const bool mandatory = true,
const bool getOldTime = false
);
//- Retrieve field from memory or disk (implementation)
@ -255,8 +256,8 @@ protected:
(
const word& name,
const MeshRef& meshRef,
bool mandatory = true,
bool getOldTime = false
const bool mandatory = true,
const bool getOldTime = false
);
//- Helper function for getOrReadField
@ -461,8 +462,8 @@ public:
inline bool isVariableOrField
(
const word& name,
bool isPointVal = false,
label expectSize = -1
const bool wantPointData = false,
const label expectSize = -1
) const;
//- Retrieve local/global variable as a tmp field
@ -475,7 +476,7 @@ public:
tmp<Field<Type>> getVariable
(
const word& name,
label expectSize,
const label expectSize,
const bool mandatory = true
) const;
@ -568,7 +569,7 @@ public:
inline bool isVariable
(
const word& name,
bool isPointVal = false,
bool wantPointData = false,
label expectSize = -1
) const;

View File

@ -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.
@ -73,14 +73,14 @@ template<class Type>
inline bool Foam::expressions::fvExprDriver::isVariable
(
const word& name,
bool isPointVal,
label expectedSize
const bool wantPointData,
const label expectedSize
) const
{
return
(
this->isLocalVariable<Type>(name, isPointVal, expectedSize)
|| this->isGlobalVariable<Type>(name, isPointVal, expectedSize)
this->isLocalVariable<Type>(name, wantPointData, expectedSize)
|| this->isGlobalVariable<Type>(name, wantPointData, expectedSize)
);
}
@ -89,15 +89,15 @@ template<class Type>
inline bool Foam::expressions::fvExprDriver::isVariableOrField
(
const word& name,
bool isPointVal,
label expectedSize
const bool wantPointData,
const label expectedSize
)
const
{
return
(
this->isVariable<Type>(name, isPointVal, expectedSize)
|| this->isField<Type>(name, isPointVal)
this->isVariable<Type>(name, wantPointData, expectedSize)
|| this->isField<Type>(name, wantPointData)
);
}
@ -107,8 +107,8 @@ inline Foam::tmp<GeomField>
Foam::expressions::fvExprDriver::getOrReadField
(
const word& name,
bool mandatory,
bool getOldTime
const bool mandatory,
const bool getOldTime
)
{
return this->getOrReadFieldImpl<GeomField>
@ -126,8 +126,8 @@ inline Foam::tmp<GeomField>
Foam::expressions::fvExprDriver::getOrReadPointField
(
const word& name,
bool mandatory,
bool getOldTime
const bool mandatory,
const bool getOldTime
)
{
return this->getOrReadFieldImpl<GeomField>

View File

@ -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.
@ -36,21 +36,23 @@ template<class Type>
bool Foam::expressions::fvExprDriver::isGlobalVariable
(
const word& name,
bool isPointVal,
label expectedSize
const bool wantPointData,
const label expectedSize
) const
{
DebugInfo
<< "Looking for global" << (isPointVal ? " point" : "")
<< "Looking for global" << (wantPointData ? " point" : "")
<< " field name:" << name;
const exprResult& result = lookupGlobal(name);
const expressions::exprResult& result = lookupGlobal(name);
DebugInfo
<< " - found (" << result.valueType() << ' ' << result.isPointValue() << ')';
<< " - found (" << result.valueType() << ' '
<< result.isPointData() << ')';
bool good = (result.isType<Type>() && result.isPointValue(isPointVal));
bool good =
(result.isType<Type>() && result.isPointData(wantPointData));
// Do size checking if requested
if (good && expectedSize >= 0)
@ -75,48 +77,47 @@ Foam::tmp<Foam::Field<Type>>
Foam::expressions::fvExprDriver::getVariable
(
const word& name,
label expectedSize,
const label expectedSize,
const bool mandatory
) const
{
tmp<Field<Type>> tresult;
bool isSingleValue = false;
refPtr<expressions::exprResult> tvar;
if (hasVariable(name) && variable(name).isType<Type>())
{
isSingleValue = variable(name).isUniform();
tresult = variable(name).cref<Type>().clone();
tvar.cref(variable(name));
}
else if (isGlobalVariable<Type>(name, false))
else if (isGlobalVariable<Type>(name))
{
const exprResult& var = lookupGlobal(name);
isSingleValue = var.isUniform();
tresult = var.cref<Type>().clone();
tvar.cref(lookupGlobal(name));
}
if (tresult.valid())
if (tvar.valid())
{
const auto& var = tvar.cref();
const Field<Type>& vals = var.cref<Type>();
if
(
expectedSize < 0
|| returnReduce((tresult->size() == expectedSize), andOp<bool>())
|| returnReduce((vals.size() == expectedSize), andOp<bool>())
)
{
return tresult;
// Return a copy of the field
return tmp<Field<Type>>::New(vals);
}
if (!isSingleValue)
if (!var.isUniform())
{
WarningInFunction
<< "Variable " << name
<< " is not a single value and does not fit the size "
<< " is nonuniform and does not fit the size "
<< expectedSize << ". Using average" << endl;
}
return tmp<Field<Type>>::New(expectedSize, gAverage(tresult()));
return tmp<Field<Type>>::New(expectedSize, gAverage(vals));
}
if (mandatory)
@ -197,7 +198,7 @@ template<class Type>
bool Foam::expressions::fvExprDriver::isField
(
const word& name,
bool isPointVal,
bool wantPointData,
label
) const
{
@ -212,7 +213,7 @@ bool Foam::expressions::fvExprDriver::isField
return
(
isPointVal
wantPointData
? this->foundField<pfieldType>(name)
:
(
@ -240,17 +241,29 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
<< "> Type: " << GeomField::typeName << endl;
}
refPtr<expressions::exprResult> tvar;
if (hasVariable(name) && variable(name).isType<Type>())
{
tvar.cref(variable(name));
}
else if (isGlobalVariable<Type>(name))
{
tvar.cref(lookupGlobal(name));
}
tmp<GeomField> tfield;
if
(
(hasVariable(name) && variable(name).isType<Type>())
|| isGlobalVariable<Type>(name, false)
)
if (tvar.valid())
{
const auto& var = tvar.cref();
const Type deflt(var.getValue<Type>());
if (debug)
{
Info<< "Getting " << name << " from variables" << endl;
Info<< "Getting " << name << " from variables. Default: "
<< deflt << endl;
}
if (debug)
@ -259,12 +272,15 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
<< GeomField::typeName << nl;
}
tfield.reset
tfield = GeomField::New
(
GeomField::New(name, meshRef, dimensioned<Type>(Zero))
name,
meshRef,
dimensioned<Type>(deflt),
// Patch is zeroGradient (volFields) or calculated (other)
defaultBoundaryType(GeomField::null())
);
GeomField& fld = tfield.ref();
auto& fld = tfield.ref();
if (debug)
{
@ -272,16 +288,7 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
<< fld.ownedByRegistry() << endl;
}
Field<Type> vals;
if (hasVariable(name) && variable(name).isType<Type>())
{
vals = variable(name).cref<Type>();
}
else
{
vals = lookupGlobal(name).cref<Type>();
}
const Field<Type>& vals = var.cref<Type>();
if (debug)
{
@ -294,7 +301,7 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
}
else
{
Type avg = gAverage(vals);
const Type avg = gAverage(vals);
bool noWarn = false;
@ -321,21 +328,23 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
const objectRegistry& obr = meshRef.thisDb();
if (searchInMemory() && obr.foundObject<GeomField>(name))
const GeomField* origFldPtr;
if
(
searchInMemory()
&& (origFldPtr = obr.cfindObject<GeomField>(name)) != nullptr
)
{
if (debug)
{
Info<< "Retrieve registered: " << name << nl;
}
const GeomField& origFld = obr.lookupObject<GeomField>(name);
const GeomField& origFld = *origFldPtr;
// Avoid shadowing the original object
tfield.reset
(
GeomField::New(name + "_exprDriverCopy", origFld)
);
tfield = GeomField::New(name + "_exprDriverCopy", origFld);
if (getOldTime)
{
@ -369,9 +378,10 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
// oldTime automatically read
}
if (debug)
{
Info<< "field: valid()=" << tfield.valid() << endl;
Info<< "field: valid()=" << Switch::name(tfield.valid()) << endl;
}
if (tfield.valid())

View File

@ -39,7 +39,7 @@ void Foam::expressions::patchExprFieldBase::readExpressions
(
const dictionary& dict,
enum expectedTypes expectedType,
bool isPointVal
bool wantPointData
)
{
if (debug_)
@ -108,7 +108,7 @@ void Foam::expressions::patchExprFieldBase::readExpressions
else if (!exprFrac.empty())
{
evalFrac = true;
if (isPointVal)
if (wantPointData)
{
exprFrac = "toPoint(" + exprFrac + ")";
}
@ -149,7 +149,7 @@ Foam::expressions::patchExprFieldBase::patchExprFieldBase
(
const dictionary& dict,
enum expectedTypes expectedType,
bool isPointVal
bool wantPointData
)
:
debug_(dict.getOrDefault("debug", false)),
@ -158,7 +158,7 @@ Foam::expressions::patchExprFieldBase::patchExprFieldBase
gradExpr_(),
fracExpr_()
{
readExpressions(dict, expectedType, isPointVal);
readExpressions(dict, expectedType, wantPointData);
}

View File

@ -99,7 +99,7 @@ private:
(
const dictionary& dict,
enum expectedTypes expectedType,
bool isPointVal = false
bool wantPointData = false
);
@ -118,7 +118,7 @@ public:
(
const dictionary& dict,
enum expectedTypes expectedType = expectedTypes::VALUE_TYPE,
bool isPointVal = false
bool wantPointData = false
);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -36,51 +36,46 @@ Foam::expressions::patchExpr::parseDriver::getVariableIfAvailable
const word& name
) const
{
bool isPointVal = false;
bool isUniformVal = false;
bool hasPointData = false;
tmp<Field<Type>> tfield;
refPtr<expressions::exprResult> tvar;
if (hasVariable(name) && variable(name).isType<Type>())
{
const expressions::exprResult& var = variable(name);
isPointVal = var.isPointValue();
isUniformVal = var.isUniform();
tfield = var.cref<Type>().clone();
tvar.cref(variable(name));
hasPointData = tvar().isPointData();
}
else if (isGlobalVariable<Type>(name, false))
else if (isGlobalVariable<Type>(name))
{
const expressions::exprResult& var = lookupGlobal(name);
isUniformVal = var.isUniform();
tfield = var.cref<Type>().clone();
tvar.cref(lookupGlobal(name));
}
if (tfield.valid())
{
const label fldLen = tfield().size();
const label len = (isPointVal ? this->pointSize() : this->size());
if (returnReduce((fldLen == len), andOp<bool>()))
if (tvar.valid())
{
return tfield;
const auto& var = tvar.cref();
const Field<Type>& vals = var.cref<Type>();
const label len = (hasPointData ? this->pointSize() : this->size());
if (returnReduce((vals.size() == len), andOp<bool>()))
{
// Return a copy of the field
return tmp<Field<Type>>::New(vals);
}
if (!isUniformVal)
if (!var.isUniform())
{
WarningInFunction
<< "Variable " << name
<< " does not fit the size and is not a uniform value." << nl
<< "Using average value" << endl;
<< " is nonuniform and does not fit the size"
<< ". Using average" << endl;
}
return tmp<Field<Type>>::New(this->size(), gAverage(tfield));
return tmp<Field<Type>>::New(this->size(), gAverage(vals));
}
return tfield;
return nullptr;
}