Commit de7ac625 authored by Henry Weller's avatar Henry Weller
Browse files

functionObjectList: Rationalized and simplified the handling of disabled functionObjects

Simplified and generalized the handling of functionObjects which fail to
construct by removing them from the list rather than maintaining an
"enabled" switch in each functionObject.
parent 8663237a
......@@ -699,7 +699,7 @@ Foam::Time::~Time()
removeWatch(controlDict_.watchIndex());
}
// destroy function objects first
// Destroy function objects first
functionObjects_.clear();
}
......
......@@ -36,8 +36,6 @@ void Foam::OutputFilterFunctionObject<OutputFilter>::readDict()
{
dict_.readIfPresent("region", regionName_);
dict_.readIfPresent("dictionary", dictName_);
dict_.readIfPresent("enabled", enabled_);
dict_.readIfPresent("storeFilter", storeFilter_);
dict_.readIfPresent("timeStart", timeStart_);
dict_.readIfPresent("timeEnd", timeEnd_);
dict_.readIfPresent("nStepsToStartTimeChange", nStepsToStartTimeChange_);
......@@ -48,8 +46,7 @@ template<class OutputFilter>
bool Foam::OutputFilterFunctionObject<OutputFilter>::active() const
{
return
enabled_
&& time_.value() >= timeStart_
time_.value() >= timeStart_
&& time_.value() <= timeEnd_;
}
......@@ -79,10 +76,6 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::allocateFilter()
)
);
}
else
{
enabled_ = false;
}
}
else
{
......@@ -106,20 +99,9 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::allocateFilter()
)
);
}
else
{
enabled_ = false;
}
}
return enabled_;
}
template<class OutputFilter>
void Foam::OutputFilterFunctionObject<OutputFilter>::destroyFilter()
{
ptr_.reset();
return ptr_.valid();
}
......@@ -138,8 +120,6 @@ Foam::OutputFilterFunctionObject<OutputFilter>::OutputFilterFunctionObject
dict_(dict),
regionName_(polyMesh::defaultRegion),
dictName_(),
enabled_(true),
storeFilter_(true),
timeStart_(-VGREAT),
timeEnd_(VGREAT),
nStepsToStartTimeChange_
......@@ -148,40 +128,23 @@ Foam::OutputFilterFunctionObject<OutputFilter>::OutputFilterFunctionObject
),
outputControl_(t, dict, "output"),
evaluateControl_(t, dict, "evaluate")
{
readDict();
}
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class OutputFilter>
void Foam::OutputFilterFunctionObject<OutputFilter>::on()
{
enabled_ = true;
}
template<class OutputFilter>
void Foam::OutputFilterFunctionObject<OutputFilter>::off()
{
enabled_ = false;
}
template<class OutputFilter>
bool Foam::OutputFilterFunctionObject<OutputFilter>::start()
{
readDict();
if (enabled_ && storeFilter_)
if (!allocateFilter())
{
return allocateFilter();
}
else
{
return true;
FatalErrorInFunction
<< "Cannot construct " << OutputFilter::typeName
<< exit(FatalError);
}
return true;
}
......@@ -193,11 +156,6 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::execute
{
if (active())
{
if (!storeFilter_ && !allocateFilter())
{
return false;
}
if (evaluateControl_.output())
{
ptr_->execute();
......@@ -207,11 +165,6 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::execute
{
ptr_->write();
}
if (!storeFilter_)
{
destroyFilter();
}
}
return true;
......@@ -221,24 +174,11 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::execute
template<class OutputFilter>
bool Foam::OutputFilterFunctionObject<OutputFilter>::end()
{
if (enabled_)
{
if (!storeFilter_ && !allocateFilter())
{
return false;
}
ptr_->end();
ptr_->end();
if (outputControl_.output())
{
ptr_->write();
}
if (!storeFilter_)
{
destroyFilter();
}
if (outputControl_.output())
{
ptr_->write();
}
return true;
......@@ -314,6 +254,7 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::read
dict_ = dict;
outputControl_.read(dict);
// Reset the OutputFilter
return start();
}
else
......
......@@ -77,13 +77,6 @@ class OutputFilterFunctionObject
//- Dictionary name to supply required inputs
word dictName_;
//- Switch for the execution - defaults to 'yes/on'
bool enabled_;
//- Switch to store filter in between writes or use on-the-fly
// construction - defaults to true
bool storeFilter_;
//- Activation time - defaults to -VGREAT
scalar timeStart_;
......@@ -113,9 +106,6 @@ class OutputFilterFunctionObject
//- Creates most of the data associated with this object.
bool allocateFilter();
//- Destroys most of the data associated with this object.
void destroyFilter();
//- Returns true if active (enabled and within time bounds)
bool active() const;
......@@ -148,62 +138,33 @@ public:
// Access
//- Return time database
virtual const Time& time() const
{
return time_;
}
inline const Time& time() const;
//- Return the input dictionary
virtual const dictionary& dict() const
{
return dict_;
}
inline const dictionary& dict() const;
//- Return the region name
virtual const word& regionName() const
{
return regionName_;
}
inline const word& regionName() const;
//- Return the optional dictionary name
virtual const word& dictName() const
{
return dictName_;
}
//- Return the enabled flag
virtual bool enabled() const
{
return enabled_;
}
inline const word& dictName() const;
//- Return the output control object
virtual const outputFilterOutputControl& outputControl() const
{
return outputControl_;
}
inline const outputFilterOutputControl& outputControl() const;
//- Return the output filter
virtual const OutputFilter& outputFilter() const
{
return ptr_();
}
inline const OutputFilter& outputFilter() const;
// Function object control
//- Switch the function object on
virtual void on();
//- Switch the function object off
virtual void off();
//- Called at the start of the time-loop
virtual bool start();
//- Called at each ++ or += of the time-loop
virtual bool execute(const bool forceWrite);
//- Called at each ++ or += of the time-loop. forceWrite overrides
// the usual outputControl behaviour and forces writing always
// (used in post-processing mode)
virtual bool execute(const bool forceWrite = false);
//- Called when Time::run() determines that the time-loop exits
virtual bool end();
......@@ -231,6 +192,10 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "OutputFilterFunctionObjectI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "OutputFilterFunctionObject.C"
#endif
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class OutputFilter>
inline const Foam::Time&
Foam::OutputFilterFunctionObject<OutputFilter>::time() const
{
return time_;
}
template<class OutputFilter>
inline const Foam::dictionary&
Foam::OutputFilterFunctionObject<OutputFilter>::dict() const
{
return dict_;
}
template<class OutputFilter>
inline const Foam::word&
Foam::OutputFilterFunctionObject<OutputFilter>::regionName() const
{
return regionName_;
}
template<class OutputFilter>
inline const Foam::word&
Foam::OutputFilterFunctionObject<OutputFilter>::dictName() const
{
return dictName_;
}
template<class OutputFilter>
inline const Foam::outputFilterOutputControl&
Foam::OutputFilterFunctionObject<OutputFilter>::outputControl() const
{
return outputControl_;
}
template<class OutputFilter>
inline const OutputFilter&
Foam::OutputFilterFunctionObject<OutputFilter>::outputFilter() const
{
return ptr_();
}
// ************************************************************************* //
......@@ -186,8 +186,9 @@ public:
//- Called at the start of the time-loop
virtual bool start() = 0;
//- Called at each ++ or += of the time-loop. forceWrite overrides the
// outputControl behaviour.
//- Called at each ++ or += of the time-loop. forceWrite overrides
// the usual outputControl behaviour and forces writing always
// (used in post-processing mode)
virtual bool execute(const bool forceWrite) = 0;
//- Called when Time::run() determines that the time-loop exits.
......
......@@ -45,7 +45,7 @@ Foam::functionObject* Foam::functionObjectList::remove
{
oldIndex = fnd();
// retrieve the pointer and remove it from the old list
// Retrieve the pointer and remove it from the old list
ptr = this->set(oldIndex, 0).ptr();
indices_.erase(fnd);
}
......@@ -168,7 +168,7 @@ void Foam::functionObjectList::on()
void Foam::functionObjectList::off()
{
// for safety, also force a read() when execution is turned back on
// For safety, also force a read() when execution is turned back on
updated_ = execution_ = false;
}
......@@ -274,10 +274,10 @@ bool Foam::functionObjectList::read()
bool ok = true;
updated_ = execution_;
// avoid reading/initializing if execution is off
// Avoid reading/initializing if execution is off
if (!execution_)
{
return ok;
return true;
}
// Update existing and add new functionObjects
......@@ -296,31 +296,42 @@ bool Foam::functionObjectList::read()
label nFunc = 0;
if (entryPtr->isDict())
if (!entryPtr->isDict())
{
// a dictionary of functionObjects
const dictionary& functionDicts = entryPtr->dict();
FatalIOErrorInFunction(parentDict_)
<< "'functions' entry is not a dictionary"
<< exit(FatalIOError);
}
const dictionary& functionDicts = entryPtr->dict();
newPtrs.setSize(functionDicts.size());
newDigs.setSize(functionDicts.size());
newPtrs.setSize(functionDicts.size());
newDigs.setSize(functionDicts.size());
forAllConstIter(dictionary, functionDicts, iter)
forAllConstIter(dictionary, functionDicts, iter)
{
const word& key = iter().keyword();
if (!iter().isDict())
{
// safety:
if (!iter().isDict())
{
continue;
}
const word& key = iter().keyword();
const dictionary& dict = iter().dict();
IOWarningInFunction(parentDict_)
<< "Entry " << key << " is not a dictionary" << endl;
continue;
}
const dictionary& dict = iter().dict();
bool enabled = dict.lookupOrDefault("enabled", true);
newDigs[nFunc] = dict.digest();
newDigs[nFunc] = dict.digest();
label oldIndex;
functionObject* objPtr = remove(key, oldIndex);
if (objPtr)
label oldIndex;
functionObject* objPtr = remove(key, oldIndex);
if (objPtr)
{
if (enabled)
{
// an existing functionObject, and dictionary changed
// Dictionary changed for an existing functionObject
if (newDigs[nFunc] != digests_[oldIndex])
{
ok = objPtr->read(dict) && ok;
......@@ -328,65 +339,48 @@ bool Foam::functionObjectList::read()
}
else
{
// new functionObject
objPtr = functionObject::New(key, time_, dict).ptr();
ok = objPtr->start() && ok;
// Delete the disabled functionObject
delete objPtr;
objPtr = NULL;
continue;
}
newPtrs.set(nFunc, objPtr);
newIndices.insert(key, nFunc);
nFunc++;
}
}
else
{
// a list of functionObjects
PtrList<entry> functionDicts(entryPtr->stream());
newPtrs.setSize(functionDicts.size());
newDigs.setSize(functionDicts.size());
forAllIter(PtrList<entry>, functionDicts, iter)
else if (enabled)
{
// safety:
if (!iter().isDict())
{
continue;
}
const word& key = iter().keyword();
const dictionary& dict = iter().dict();
newDigs[nFunc] = dict.digest();
autoPtr<functionObject> foPtr;
label oldIndex;
functionObject* objPtr = remove(key, oldIndex);
if (objPtr)
FatalError.throwExceptions();
FatalIOError.throwExceptions();
try
{
// an existing functionObject, and dictionary changed
if (newDigs[nFunc] != digests_[oldIndex])
{
ok = objPtr->read(dict) && ok;
}
foPtr = functionObject::New(key, time_, dict);
}
else
catch (...)
{}
FatalError.dontThrowExceptions();
FatalIOError.dontThrowExceptions();
if (foPtr.valid())
{
// new functionObject
objPtr = functionObject::New(key, time_, dict).ptr();
objPtr = foPtr.ptr();
ok = objPtr->start() && ok;
}
}
// Insert active functionObjects into the list
if (objPtr)
{
newPtrs.set(nFunc, objPtr);
newIndices.insert(key, nFunc);
nFunc++;
}
}
// safety:
newPtrs.setSize(nFunc);
newDigs.setSize(nFunc);
// updating the PtrList of functionObjects also deletes any existing,
// but unused functionObjects
// Updating the PtrList of functionObjects deletes any
// existing unused functionObjects
PtrList<functionObject>::transfer(newPtrs);
digests_.transfer(newDigs);
indices_.transfer(newIndices);
......
......@@ -138,7 +138,7 @@ public:
//- Destructor
virtual ~functionObjectList();
~functionObjectList();
// Member Functions
......@@ -153,46 +153,45 @@ public:
using PtrList<functionObject>::operator[];
//- Clear the list of function objects
virtual void clear();
void clear();
//- Find the ID of a given function object by name
virtual label findObjectID(const word& name) const;
label findObjectID(const word& name) const;
//- Switch the function objects on
virtual void on();
void on();
//- Switch the function objects off
virtual void off();
void off();
//- Return the execution status (on/off) of the function objects
virtual bool status() const;
bool status() const;
//- Called at the start of the time-loop
virtual bool start();
bool start();
//- Called at each ++ or += of the time-loop. forceWrite overrides