Commit b6b4ab07 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: additional patch expressions (#2114)

- snGrad, internalField, neighbourField.
  Functional use as per swak: "... + internalField(T) ..."

ENH: additional volume/patch expressions

- deltaT()

STYLE: rename exprDriverWriter -> fvExprDriverWriter

- the original class name was a misnomer since it holds a reference
  to fvExprDriver

BUG: expression faceToPoint/pointToFace definitions were flipped

ENH: refactor expression hierarchy and code style

- handle TimeState reference at the top-level for simpler derivations

- unified internal search parameters (cruft)
parent 239a7884
......@@ -33,8 +33,8 @@ Description
Set boundary values using an expression
Note
Based on funkySetBoundaryFields
Copyright 2006-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
Based on funkySetBoundaryFields from
Bernhard Gschaider <bgschaid@hfd-research.com>
\*---------------------------------------------------------------------------*/
......@@ -248,8 +248,12 @@ int main(int argc, char *argv[])
expressions::patchExprDriver driver(currDict, mesh);
// Search on disc
driver.setSearchBehaviour(cacheFields, false, true);
// Search files only
driver.setSearchBehaviour
(
expressions::exprDriver::SEARCH_FILES,
cacheFields
);
driver.clearVariables();
driver.parse(expr);
......
......@@ -33,8 +33,8 @@ Description
Set values on a selected set of cells/patch-faces via a dictionary.
Note
Based on funkySetFields
Copyright 2006-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
Based on funkySetFields from
Bernhard Gschaider <bgschaid@hfd-research.com>
\*---------------------------------------------------------------------------*/
......@@ -310,11 +310,9 @@ void evaluate
Info<< endl;
expressions::volumeExprDriver driver
(
mesh,
ctrl.cacheVariables
);
expressions::volumeExprDriver driver(mesh);
driver.setCaching(ctrl.cacheVariables);
driver.readDict(dict);
......
......@@ -5,8 +5,8 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2010-2018 Bernhard Gschaider
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -29,6 +29,7 @@ License
#include "exprDriver.H"
#include "expressionEntry.H"
#include "stringOps.H"
#include "TimeState.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -43,9 +44,31 @@ namespace expressions
} // End namespace Foam
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
int Foam::expressions::exprDriver::getSearchControls(const dictionary& dict)
{
int val = 0;
if (dict.getOrDefault("searchInMemory", true))
{
val |= int(searchControls::SEARCH_REGISTRY);
}
if (dict.getOrDefault("searchFiles", false))
{
val |= int(searchControls::SEARCH_FILES);
}
if (dict.getOrDefault("cacheReadFields", false))
{
val |= int(searchControls::CACHE_READ_FIELDS);
}
return val;
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
#if 0
......@@ -78,14 +101,27 @@ static string getEntryString
} // End namespace Foam
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::expressions::exprDriver::resetTimeReference(const TimeState* ts)
{
timeStatePtr_ = ts;
}
void Foam::expressions::exprDriver::resetTimeReference(const TimeState& ts)
{
timeStatePtr_ = &ts;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::expressions::exprDriver::exprDriver
(
bool cacheReadFields,
bool searchInMemory,
bool searchFiles,
const dictionary& dict
enum searchControls search,
const dictionary& dict,
const TimeState* ts
)
:
dict_(dict),
......@@ -93,6 +129,7 @@ Foam::expressions::exprDriver::exprDriver
variableStrings_(),
variables_(),
arg1Value_(0),
timeStatePtr_(ts),
stashedTokenId_(0),
// Controls
......@@ -106,9 +143,7 @@ Foam::expressions::exprDriver::exprDriver
(
dict.getOrDefault("prevIterIsOldTime", false)
),
cacheReadFields_(cacheReadFields),
searchInMemory_(searchInMemory || cacheReadFields),
searchFiles_(searchFiles)
searchCtrl_(search)
{}
......@@ -122,6 +157,7 @@ Foam::expressions::exprDriver::exprDriver
variableStrings_(rhs.variableStrings_),
variables_(rhs.variables_),
arg1Value_(rhs.arg1Value_),
timeStatePtr_(rhs.timeStatePtr_),
stashedTokenId_(0),
debugScanner_(rhs.debugScanner_),
......@@ -129,23 +165,21 @@ Foam::expressions::exprDriver::exprDriver
allowShadowing_(rhs.allowShadowing_),
prevIterIsOldTime_(rhs.prevIterIsOldTime_),
cacheReadFields_(rhs.cacheReadFields_),
searchInMemory_(rhs.searchInMemory_),
searchFiles_(rhs.searchFiles_)
searchCtrl_(rhs.searchCtrl_)
{}
Foam::expressions::exprDriver::exprDriver
(
const dictionary& dict
const dictionary& dict,
const TimeState* ts
)
:
exprDriver
(
dict.getOrDefault("cacheReadFields", false),
dict.getOrDefault("searchInMemory", true),
dict.getOrDefault("searchFiles", false),
dict
searchControls(exprDriver::getSearchControls(dict)),
dict,
ts
)
{
readDict(dict);
......@@ -154,6 +188,32 @@ Foam::expressions::exprDriver::exprDriver
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::TimeState* Foam::expressions::exprDriver::timeState() const
{
return timeStatePtr_;
}
Foam::scalar Foam::expressions::exprDriver::timeValue() const
{
if (timeStatePtr_)
{
return timeStatePtr_->value();
}
return 0;
}
Foam::scalar Foam::expressions::exprDriver::deltaT() const
{
if (timeStatePtr_)
{
return timeStatePtr_->deltaT().value();
}
return 0;
}
bool Foam::expressions::exprDriver::readDict
(
const dictionary& dict
......@@ -196,18 +256,6 @@ void Foam::expressions::exprDriver::clearVariables()
}
void Foam::expressions::exprDriver::setArgument(scalar val)
{
arg1Value_ = val;
}
Foam::scalar Foam::expressions::exprDriver::argValue() const
{
return arg1Value_;
}
void Foam::expressions::exprDriver::evaluateVariable
(
const word& varName,
......@@ -383,20 +431,58 @@ void Foam::expressions::exprDriver::setDebugging
}
bool Foam::expressions::exprDriver::setCaching(bool on) noexcept
{
int val(searchCtrl_);
bool old = (val & searchControls::CACHE_READ_FIELDS);
if (!on)
{
// Off
val &= ~(searchControls::CACHE_READ_FIELDS);
}
else if (!old)
{
// Toggled on.
// Caching read fields implies both registry and disk use
val |=
(
searchControls::SEARCH_REGISTRY
| searchControls::SEARCH_FILES
| searchControls::CACHE_READ_FIELDS
);
}
searchCtrl_ = searchControls(val);
return old;
}
void Foam::expressions::exprDriver::setSearchBehaviour
(
bool cacheReadFields,
bool searchInMemory,
bool searchFiles
enum searchControls search,
const bool caching
)
{
searchInMemory_ = searchInMemory_ || cacheReadFields_;
int val(search);
if (caching || (val & searchControls::CACHE_READ_FIELDS))
{
// Caching read fields implies both registry and disk use
val |=
(
searchControls::SEARCH_REGISTRY
| searchControls::SEARCH_FILES
| searchControls::CACHE_READ_FIELDS
);
}
searchCtrl_ = searchControls(val);
#ifdef FULLDEBUG
Info<< "Searching "
<< " registry:" << searchInMemory_
<< " disk:" << searchFiles_
<< " cache-read:" << cacheReadFields_ << nl;
<< " registry:" << searchRegistry()
<< " disk:" << searchFiles()
<< " cache-read:" << cacheReadFields() << nl;
#endif
}
......@@ -406,12 +492,7 @@ void Foam::expressions::exprDriver::setSearchBehaviour
const exprDriver& rhs
)
{
setSearchBehaviour
(
rhs.cacheReadFields_,
rhs.searchInMemory_,
rhs.searchFiles_
);
searchCtrl_ = rhs.searchCtrl_;
}
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2010-2018 Bernhard Gschaider
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -68,6 +68,10 @@ SourceFiles
namespace Foam
{
// Forward Declarations
class TimeState;
namespace expressions
{
......@@ -77,6 +81,29 @@ namespace expressions
class exprDriver
{
public:
// Data Types
//- Search/caching controls
enum searchControls
{
NO_SEARCH = 0,
SEARCH_REGISTRY = 1, //!< Search registry before disk
SEARCH_FILES = 2, //!< Search disk (eg, standalone app)
CACHE_READ_FIELDS = 4, //!< Cache fields read from disk
DEFAULT_SEARCH = (SEARCH_REGISTRY)
};
private:
// Private Member Functions
//- Get search/caching controls from dictionary entries
static int getSearchControls(const dictionary& dict);
protected:
// Protected Data
......@@ -98,6 +125,9 @@ protected:
//- Special-purpose scalar reference argument
scalar arg1Value_;
//- Reference to the time-state
mutable const TimeState* timeStatePtr_;
// Controls, tracing etc.
......@@ -116,17 +146,27 @@ protected:
//- Use value of previous iteration when oldTime is requested
bool prevIterIsOldTime_;
//- Keep fields read from disc in memory
bool cacheReadFields_;
//- Registry/disk/caching control
searchControls searchCtrl_;
//- Search in registry before looking on disk
bool searchInMemory_;
// Protected Member Functions
//- Search on disk (eg, for a standalone application)
bool searchFiles_;
inline bool searchRegistry() const noexcept;
inline bool searchFiles() const noexcept;
inline bool cacheReadFields() const noexcept;
//- Reset the time-state reference
void resetTimeReference(const TimeState* ts);
// Protected Member Functions
//- Reset the time-state reference
void resetTimeReference(const TimeState& ts);
//- Lookup field object.
// \return const-ref tmp or invalid if not found
template<class GeoField>
static tmp<GeoField>
cfindFieldObject(const objectRegistry& obr, const word& fldName);
//- Read an interpolation table
template<typename TableType>
......@@ -159,7 +199,8 @@ protected:
//- Fill a random field
//
// \param field the field to populate
// \param seed the seed value.
// \param seed the seed value. If zero or negative, use as an offset
// to the current timeIndex (if a time-state is available)
// \param gaussian generate a Gaussian distribution
void fill_random
(
......@@ -227,20 +268,23 @@ public:
// Constructors
//- Null constructor, and null construct with search preferences
//- Default construct, and default construct with search preferences
explicit exprDriver
(
bool cacheReadFields = false,
bool searchInMemory = true,
bool searchFiles = false,
const dictionary& dict = dictionary::null
enum searchControls search = searchControls::DEFAULT_SEARCH,
const dictionary& dict = dictionary::null,
const TimeState* ts = nullptr
);
//- Copy construct
exprDriver(const exprDriver&);
exprDriver(const exprDriver& rhs);
//- Construct from a dictionary
explicit exprDriver(const dictionary& dict);
explicit exprDriver
(
const dictionary& dict,
const TimeState* ts = nullptr
);
//- Destructor
......@@ -261,20 +305,30 @@ public:
return 1;
}
//- Reference to the current time-state (can be nullptr)
const TimeState* timeState() const;
//- The current time value
virtual scalar timeValue() const;
//- The current deltaT value
virtual scalar deltaT() const;
//- The dictionary with all input data/specification
const dictionary& dict() const
const dictionary& dict() const noexcept
{
return dict_;
}
//- Const access to expression result
virtual const exprResult& result() const
const exprResult& result() const noexcept
{
return result_;
}
//- Non-const access to expression result
virtual exprResult& result()
exprResult& result() noexcept
{
return result_;
}
......@@ -287,28 +341,28 @@ public:
tmp<Field<Type>> getResult(bool wantPointData=false);
//- The result type as word - same as result().valueType()
virtual word getResultType() const
const word& getResultType() const noexcept
{
return result_.valueType();
}
// Globals, Mesh Related
// Specials
//- Set special-purpose scalar reference argument.
//- Get special-purpose scalar reference argument.
// Typically available as \c arg() in an expression and
// may corrspond to table index, time value etc.
scalar argValue() const;
// may correspond to table index, time value etc.
inline scalar argValue() const noexcept;
// General Controls
//- Get "look-behind" parsing context (internal bookkeeping)
inline int stashedTokenId() const;
inline int stashedTokenId() const noexcept;
//- Reset "look-behind" parsing context (mutable operation)
// \return the previous value
inline int resetStashedTokenId(int tokenId=0) const;
inline int resetStashedTokenId(int tokenId=0) const noexcept;
//- Set the scanner/parser debug
......@@ -317,26 +371,26 @@ public:
//- Set the scanner/parser debug to match the input
void setDebugging(const exprDriver& rhs);
//- Set search behaviour
//- Toggle CACHE_READ_FIELDS control
bool setCaching(bool on) noexcept;
//- Set search behaviour,
//- with additional CACHE_READ_FIELDS toggle on
void setSearchBehaviour
(
bool cacheReadFields,
bool searchInMemory,
bool searchFiles
enum searchControls search,
const bool caching = false
);
//- Set search behaviour to be identical to rhs
void setSearchBehaviour(const exprDriver& rhs);
//- Read access to scanner debug
bool debugScanner() const { return debugScanner_; }
inline bool debugScanner() const noexcept;
//- Read access to parser debug
bool debugParser() const { return debugParser_; }
inline bool debugParser() const noexcept;
bool cacheReadFields() const { return cacheReadFields_; }
bool searchInMemory() const { return searchInMemory_; }
bool searchFiles() const { return searchFiles_; }
bool prevIterIsOldTime() const { return prevIterIsOldTime_; }
......@@ -348,7 +402,7 @@ public:
//- Set special-purpose scalar reference argument.
// Typically available as \c arg() in an expression and
// may corrspond to table index, time value etc.
virtual void setArgument(const scalar val);
inline void setArgument(const scalar val) noexcept;
//- True if named variable exists
inline virtual bool hasVariable(const word& name) const;
......
......@@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -28,6 +28,7 @@ License
#include "exprDriver.H"
#include "FieldOps.H"
#include "Random.H"
#include "TimeState.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
......@@ -38,6 +39,18 @@ void Foam::expressions::exprDriver::fill_random
const bool gaussian
) const
{
if (seed <= 0)
{
if (timeStatePtr_)
{
seed = (timeStatePtr_->timeIndex() - seed);
}
else
{
seed = -seed;
}
}
if (gaussian)
{
Random::gaussianGeneratorOp<scalar> gen(seed);
......
......@@ -5,8 +5,8 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2010-2018 Bernhard Gschaider
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -28,6 +28,18 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline void Foam::expressions::exprDriver::setArgument(scalar val) noexcept
{