ENH: Refactored valueAverage FO and average runTimeCondition

This commit is contained in:
Andrew Heather
2022-02-02 13:35:29 +00:00
committed by Mark Olesen
parent bb04f5759d
commit 3d134167dd
10 changed files with 493 additions and 448 deletions

View File

@ -365,6 +365,7 @@ $(funcObjs)/logFiles/logFiles.C
$(funcObjs)/timeControl/timeControl.C $(funcObjs)/timeControl/timeControl.C
$(funcObjs)/timeControl/timeControlFunctionObject.C $(funcObjs)/timeControl/timeControlFunctionObject.C
$(funcObjs)/regionFunctionObject/regionFunctionObject.C $(funcObjs)/regionFunctionObject/regionFunctionObject.C
$(funcObjs)/valueAverageBase/valueAverageBase.C
Time = db/Time Time = db/Time
$(Time)/TimePaths.C $(Time)/TimePaths.C

View File

@ -0,0 +1,238 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation
Copyright (C) 2015-2022 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 "valueAverageBase.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::Enum
<
Foam::functionObjects::valueAverageBase::windowType
>
Foam::functionObjects::valueAverageBase::windowTypeNames
({
{ windowType::NONE, "none" },
{ windowType::APPROXIMATE, "approximate" },
{ windowType::EXACT, "exact" }
});
// * * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * //
void Foam::functionObjects::valueAverageBase::writeFileHeader(Ostream& os) const
{
writeHeader(os, "Value averages");
writeCommented(os, "Time");
forAll(fieldNames_, fieldi)
{
writeTabbed(os, fieldNames_[fieldi]);
}
os << endl;
}
void Foam::functionObjects::valueAverageBase::readState(dictionary& dict)
{
if (resetOnRestart_)
{
resetState(dict);
return;
}
forAll(fieldNames_, fieldi)
{
const word& fieldName = fieldNames_[fieldi];
if (dict.found(fieldName))
{
const dictionary& valueDict = dict.subDict(fieldName);
valueDict.readEntry("totalTime", totalTime_[fieldi]);
}
else
{
dict.set(fieldName, dictionary());
totalTime_[fieldi] = 0;
}
}
}
void Foam::functionObjects::valueAverageBase::writeState(dictionary& dict)
{
forAll(fieldNames_, fieldi)
{
const word& fieldName = fieldNames_[fieldi];
if (dict.found(fieldName))
{
dictionary& valueDict = dict.subDict(fieldName);
valueDict.add("totalTime", totalTime_[fieldi], true);
}
else
{
dictionary valueDict;
valueDict.add("totalTime", totalTime_[fieldi], true);
dict.add(fieldName, valueDict);
}
}
}
void Foam::functionObjects::valueAverageBase::resetState(dictionary& dict)
{
forAll(fieldNames_, fieldi)
{
dict.set(fieldNames_[fieldi], dictionary());
totalTime_[fieldi] = 0;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::valueAverageBase::valueAverageBase
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
stateFunctionObject& state,
const bool writeToFile
)
:
writeFile(obr, name, state.type(), dict, writeToFile),
log(true),
resetOnRestart_(false),
windowType_(windowType::NONE),
state_(state),
functionObjectName_("unknown-functionObject"),
fieldNames_(),
tolerance_(dict.getOrDefault<scalar>("tolerance", -1)),
window_(-1),
totalTime_()
{
read(dict);
writeFileHeader(file());
}
// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
bool Foam::functionObjects::valueAverageBase::read(const dictionary& dict)
{
if (writeFile::read(dict))
{
// Make certain that the values are consistent with the defaults:
resetOnRestart_ = false;
dict.readEntry("functionObject", functionObjectName_);
dict.readEntry("fields", fieldNames_);
if (dict.readIfPresent("window", window_))
{
window_ = state_.time().userTimeToTime(window_);
if (window_ > 0)
{
windowType_ = windowTypeNames.get("windowType", dict);
}
}
totalTime_.resize(fieldNames_.size(), Zero);
dict.readIfPresent("resetOnRestart", resetOnRestart_);
dict.readIfPresent("log", log);
return true;
}
return false;
}
bool Foam::functionObjects::valueAverageBase::calculate(dictionary& dict)
{
scalar dt = state_.time().deltaTValue();
Log << indent << state_.type() << ": " << prefix_.c_str()
<< " averages:" << nl;
file() << state_.time().timeName();
DynamicList<word> unprocessedFields(fieldNames_.size());
bool converged = true;
forAll(fieldNames_, fieldi)
{
totalTime_[fieldi] += dt;
const bool processed =
(
calc<scalar>(fieldi, converged, dict)
|| calc<vector>(fieldi, converged, dict)
|| calc<sphericalTensor>(fieldi, converged, dict)
|| calc<symmTensor>(fieldi, converged, dict)
|| calc<tensor>(fieldi, converged, dict)
);
if (!processed)
{
unprocessedFields.append(fieldNames_[fieldi]);
file() << tab << "n/a";
}
}
file() << endl;
if (unprocessedFields.size())
{
WarningInFunction
<< "From function object: " << functionObjectName_ << nl
<< "Unprocessed fields:" << nl;
for (const word& fieldName : unprocessedFields)
{
Log << indent << " " << fieldName << nl;
}
if (unprocessedFields.size() == fieldNames_.size())
{
converged = false;
}
}
Log << endl;
return converged;
}
// ************************************************************************* //

View File

@ -0,0 +1,189 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation
Copyright (C) 2016-2022 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::functionObjects::valueAverageBase
Description
Base class that computes the ensemble- or time-based singular-value average
values, with optional windowing, from the output of function objects
that generate non-field type values, e.g. \c Cd of \c forceCoeffs or
\c momentum_x in \c momentum function objects.
See also
- Foam::functionObjects::writeFile
SourceFiles
valueAverageBase.C
valueAverageBaseTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_valueAverageBase_H
#define functionObjects_valueAverageBase_H
#include "writeFile.H"
#include "Enum.H"
#include "stateFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class valueAverageBase Declaration
\*---------------------------------------------------------------------------*/
class valueAverageBase
:
public functionObjects::writeFile
{
public:
// Public Enumerations
//- Averaging window types
enum class windowType : uint8_t
{
NONE, //!< "none"
APPROXIMATE, //!< "approximate"
EXACT //!< "exact"
};
//- Names for windowType enumeration
static const Enum<windowType> windowTypeNames;
private:
// Private Data
//- Log flag
bool log;
protected:
// Protected Data
//- Reset the averaging process on restart
bool resetOnRestart_;
//- Window type
windowType windowType_;
//- Reference to the state functionObject
stateFunctionObject& state_;
//- Name of function object to retrieve data from
word functionObjectName_;
//- List of fields on which to operate
wordList fieldNames_;
//- Optional tolerance to check for converged results
scalar tolerance_;
//- Averaging window
scalar window_;
//- Average time per field
List<scalar> totalTime_;
// Protected Member Functions
//- Templated function to calculate the average
// Return true if processed
template<class Type>
bool calc(const label fieldi, bool& converged, dictionary& dict);
//- Output file header information
virtual void writeFileHeader(Ostream& os) const;
//- Read state from dictionary
virtual void readState(dictionary& dict);
//- Write state to dictionary for restarts
virtual void writeState(dictionary& dict);
//- Reset state
virtual void resetState(dictionary& dict);
public:
// Constructors
//- Construct from Time and dictionary
valueAverageBase
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
stateFunctionObject& state,
const bool writeToFile = true
);
//- No copy construct
valueAverageBase(const valueAverageBase&) = delete;
//- No copy assignment
void operator=(const valueAverageBase&) = delete;
//- Destructor
virtual ~valueAverageBase() = default;
// Public Member Functions
//- Read the field value average data
virtual bool read(const dictionary& dict);
//- Calculate the averages
virtual bool calculate(dictionary& dict);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "valueAverageBaseTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2015 OpenFOAM Foundation
Copyright (C) 2015-2016 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -26,17 +26,14 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "Time.H"
#include "FIFOStack.H"
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
template<class Type> template<class Type>
void Foam::functionObjects::runTimeControls::averageCondition::calc bool Foam::functionObjects::valueAverageBase::calc
( (
const label fieldi, const label fieldi,
bool& satisfied, bool& converged,
bool& processed dictionary& dict
) )
{ {
const word& fieldName = fieldNames_[fieldi]; const word& fieldName = fieldNames_[fieldi];
@ -46,16 +43,16 @@ void Foam::functionObjects::runTimeControls::averageCondition::calc
if (pTraits<Type>::typeName != valueType) if (pTraits<Type>::typeName != valueType)
{ {
return; return false;
} }
const scalar dt = obr_.time().deltaTValue(); const scalar dt = state_.time().deltaTValue();
const Type currentValue = const Type currentValue =
state_.getObjectResult<Type>(functionObjectName_, fieldName); state_.getObjectResult<Type>(functionObjectName_, fieldName);
const word meanName(fieldName + "Mean");
// Current mean value // Current mean value
const word meanName(fieldName + "Mean");
Type meanValue = state_.getResult<Type>(meanName); Type meanValue = state_.getResult<Type>(meanName);
switch (windowType_) switch (windowType_)
@ -63,40 +60,35 @@ void Foam::functionObjects::runTimeControls::averageCondition::calc
case windowType::NONE: case windowType::NONE:
{ {
const scalar Dt = totalTime_[fieldi]; const scalar Dt = totalTime_[fieldi];
const scalar alpha = (Dt - dt)/Dt;
const scalar beta = dt/Dt; const scalar beta = dt/Dt;
meanValue = alpha*meanValue + beta*currentValue; meanValue = (1 - beta)*meanValue + beta*currentValue;
break; break;
} }
case windowType::APPROXIMATE: case windowType::APPROXIMATE:
{ {
const scalar Dt = totalTime_[fieldi]; const scalar Dt = totalTime_[fieldi];
scalar alpha = (Dt - dt)/Dt;
scalar beta = dt/Dt; scalar beta = dt/Dt;
if (Dt - dt >= window_) if (Dt - dt >= window_)
{ {
alpha = (window_ - dt)/window_;
beta = dt/window_; beta = dt/window_;
} }
else else
{ {
// Ensure that averaging is performed over window time converged = false;
// before condition can be satisfied
satisfied = false;
} }
meanValue = alpha*meanValue + beta*currentValue; meanValue = (1 - beta)*meanValue + beta*currentValue;
totalTime_[fieldi] += dt;
break; break;
} }
case windowType::EXACT: case windowType::EXACT:
{ {
FIFOStack<scalar> windowTimes; FIFOStack<scalar> windowTimes;
FIFOStack<Type> windowValues; FIFOStack<Type> windowValues;
dictionary& dict = this->conditionDict().subDict(fieldName); dictionary& fieldDict = dict.subDict(fieldName);
dict.readIfPresent("windowTimes", windowTimes); fieldDict.readIfPresent("windowTimes", windowTimes);
dict.readIfPresent("windowValues", windowValues); fieldDict.readIfPresent("windowValues", windowValues);
// Increment time for all existing values // Increment time for all existing values
for (scalar& dti : windowTimes) for (scalar& dti : windowTimes)
@ -151,8 +143,8 @@ void Foam::functionObjects::runTimeControls::averageCondition::calc
meanValue /= windowTimes.first(); meanValue /= windowTimes.first();
// Store the state information for the next step // Store the state information for the next step
dict.set("windowTimes", windowTimes); fieldDict.set("windowTimes", windowTimes);
dict.set("windowValues", windowValues); fieldDict.set("windowValues", windowValues);
break; break;
} }
@ -160,19 +152,19 @@ void Foam::functionObjects::runTimeControls::averageCondition::calc
scalar delta = mag(meanValue - currentValue); scalar delta = mag(meanValue - currentValue);
Log << " " << meanName << ": " << meanValue Log << indent << " " << meanName << ": " << meanValue
<< ", delta: " << delta << nl; << ", delta: " << delta << nl;
// Note: Writing result to owner function object and not the local run-time file() << tab << meanValue;
// condition
state_.setResult(meanName, meanValue); state_.setResult(meanName, meanValue);
if (delta > tolerance_) if ((tolerance_ > 0) && (delta > tolerance_))
{ {
satisfied = false; converged = false;
} }
processed = true; return true;
} }

View File

@ -5,8 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2015-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,7 +27,6 @@ License
#include "valueAverage.H" #include "valueAverage.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -41,21 +39,6 @@ namespace functionObjects
} }
} }
// * * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * //
void Foam::functionObjects::valueAverage::writeFileHeader(Ostream& os) const
{
writeHeader(os, "Value averages");
writeCommented(os, "Time");
forAll(fieldNames_, fieldi)
{
writeTabbed(os, fieldNames_[fieldi]);
}
os << endl;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::valueAverage::valueAverage Foam::functionObjects::valueAverage::valueAverage
@ -66,30 +49,9 @@ Foam::functionObjects::valueAverage::valueAverage
) )
: :
regionFunctionObject(name, runTime, dict), regionFunctionObject(name, runTime, dict),
writeFile(obr_, name, typeName, dict), valueAverageBase(name, obr_, dict, *this)
functionObjectName_("unknown-functionObject"),
fieldNames_(),
window_(-1),
totalTime_(),
resetOnRestart_(false)
{ {
read(dict); readState(this->propertyDict());
if (resetOnRestart_)
{
forAll(fieldNames_, fieldi)
{
const word& fieldName = fieldNames_[fieldi];
if (dict.found(fieldName))
{
const dictionary& valueDict = dict.subDict(fieldName);
valueDict.readEntry("totalTime", totalTime_[fieldi]);
}
}
}
writeFileHeader(file());
} }
@ -97,103 +59,25 @@ Foam::functionObjects::valueAverage::valueAverage
bool Foam::functionObjects::valueAverage::read(const dictionary& dict) bool Foam::functionObjects::valueAverage::read(const dictionary& dict)
{ {
regionFunctionObject::read(dict); if (regionFunctionObject::read(dict) && valueAverageBase::read(dict))
writeFile::read(dict);
// Make certain that the values are consistent with the defaults:
resetOnRestart_ = false;
dict.readEntry("functionObject", functionObjectName_);
dict.readEntry("fields", fieldNames_);
if (dict.readIfPresent("window", window_))
{ {
window_ = obr().time().userTimeToTime(window_); return true;
} }
totalTime_.setSize(fieldNames_.size()); return false;
forAll(totalTime_, i)
{
totalTime_[i] = time_.deltaTValue();
}
dict.readIfPresent("resetOnRestart", resetOnRestart_);
return true;
} }
bool Foam::functionObjects::valueAverage::execute() bool Foam::functionObjects::valueAverage::execute()
{ {
scalar dt = obr_.time().deltaTValue(); (void)valueAverageBase::calculate(this->propertyDict());
Log << type() << ": " << name() << " averages:" << nl;
file() << time_.timeName();
DynamicList<label> unprocessedFields(fieldNames_.size());
forAll(fieldNames_, fieldi)
{
const word& fieldName(fieldNames_[fieldi]);
const word meanName(fieldName + "Mean");
scalar Dt = totalTime_[fieldi];
scalar alpha = (Dt - dt)/Dt;
scalar beta = dt/Dt;
if (window_ > 0)
{
if (Dt - dt >= window_)
{
alpha = (window_ - dt)/window_;
beta = dt/window_;
}
}
bool processed = false;
calc<scalar>(fieldName, meanName, alpha, beta, processed);
calc<vector>(fieldName, meanName, alpha, beta, processed);
calc<sphericalTensor>(fieldName, meanName, alpha, beta, processed);
calc<symmTensor>(fieldName, meanName, alpha, beta, processed);
calc<tensor>(fieldName, meanName, alpha, beta, processed);
if (!processed)
{
unprocessedFields.append(fieldi);
if (writeToFile())
{
file() << tab << "n/a";
}
}
totalTime_[fieldi] += dt;
}
file()<< endl;
if (unprocessedFields.size())
{
WarningInFunction
<< "From function object: " << functionObjectName_ << nl
<< "Unprocessed fields:" << nl;
forAll(unprocessedFields, i)
{
label fieldi = unprocessedFields[i];
Log << " " << fieldNames_[fieldi] << nl;
}
Log << endl;
}
Log << endl;
return true; return true;
} }
bool Foam::functionObjects::valueAverage::write() bool Foam::functionObjects::valueAverage::write()
{ {
valueAverageBase::writeState(this->propertyDict());
return true; return true;
} }

View File

@ -5,8 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -79,14 +78,13 @@ Usage
The inherited entries are elaborated in: The inherited entries are elaborated in:
- \link regionFunctionObject.H \endlink - \link regionFunctionObject.H \endlink
- \link writeFile.H \endlink - \link valueAverageBase.H \endlink
Usage by the \c postProcess utility is not available. Usage by the \c postProcess utility is not available.
See also See also
- Foam::functionObject - Foam::functionObject
- Foam::functionObjects::stateFunctionObject - Foam::functionObjects::valueAverageBase
- Foam::functionObjects::writeFile
- ExtendedCodeGuide::functionObjects::field::valueAverage - ExtendedCodeGuide::functionObjects::field::valueAverage
SourceFiles SourceFiles
@ -99,6 +97,7 @@ SourceFiles
#define functionObjects_valueAverage_H #define functionObjects_valueAverage_H
#include "regionFunctionObject.H" #include "regionFunctionObject.H"
#include "valueAverageBase.H"
#include "writeFile.H" #include "writeFile.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -115,45 +114,8 @@ namespace functionObjects
class valueAverage class valueAverage
: :
public regionFunctionObject, public regionFunctionObject,
public writeFile public valueAverageBase
{ {
protected:
// Protected Data
//- Name of function object to retrieve data from
word functionObjectName_;
//- List of fields on which to operate
wordList fieldNames_;
//- Averaging window
scalar window_;
//- Average time per field
List<scalar> totalTime_;
//- Reset the averaging process on restart
Switch resetOnRestart_;
// Protected Member Functions
//- Templated function to calculate the average
template<class Type>
void calc
(
const word& fieldName,
const word& meanName,
const scalar alpha,
const scalar beta,
bool& processed
);
//- Output file header information
virtual void writeFileHeader(Ostream& os) const;
public: public:
//- Runtime type information //- Runtime type information
@ -201,12 +163,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "valueAverageTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -1,63 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation
Copyright (C) 2015-2016 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
template<class Type>
void Foam::functionObjects::valueAverage::calc
(
const word& fieldName,
const word& meanName,
const scalar alpha,
const scalar beta,
bool& processed
)
{
const word valueType = objectResultType(functionObjectName_, fieldName);
if (pTraits<Type>::typeName != valueType)
{
return;
}
Type currentValue = getObjectResult<Type>(functionObjectName_, fieldName);
Type meanValue = getResult<Type>(meanName);
meanValue = alpha*meanValue + beta*currentValue;
setResult(meanName, meanValue);
file() << tab << meanValue;
Log<< " " << meanName << ": " << meanValue << nl;
processed = true;
}
// ************************************************************************* //

View File

@ -5,8 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,7 +27,6 @@ License
#include "averageCondition.H" #include "averageCondition.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -44,18 +42,6 @@ namespace runTimeControls
} }
} }
const Foam::Enum
<
Foam::functionObjects::runTimeControls::averageCondition::windowType
>
Foam::functionObjects::runTimeControls::averageCondition::windowTypeNames
({
{ windowType::NONE, "none" },
{ windowType::APPROXIMATE, "approximate" },
{ windowType::EXACT, "exact" }
});
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::runTimeControls::averageCondition::averageCondition Foam::functionObjects::runTimeControls::averageCondition::averageCondition
@ -67,45 +53,15 @@ Foam::functionObjects::runTimeControls::averageCondition::averageCondition
) )
: :
runTimeCondition(name, obr, dict, state), runTimeCondition(name, obr, dict, state),
functionObjectName_(dict.get<word>("functionObject")), valueAverageBase(name, obr_, dict, state, false),
fieldNames_(dict.get<wordList>("fields")),
tolerance_(dict.get<scalar>("tolerance")),
window_(dict.getOrDefault<scalar>("window", -1)),
windowType_
(
window_ > 0
? windowTypeNames.get("windowType", dict)
: windowType::NONE
),
totalTime_(fieldNames_.size(), scalar(0)),
resetOnRestart_(dict.getOrDefault("resetOnRestart", false)),
nIterStartUp_(dict.getOrDefault<label>("nIterStartUp", 10)), nIterStartUp_(dict.getOrDefault<label>("nIterStartUp", 10)),
iter_(-1) iter_(-1)
{ {
dictionary& conditionDict = this->conditionDict(); dictionary& conditionDict = this->conditionDict();
readState(conditionDict);
conditionDict.readIfPresent("iter", iter_); conditionDict.readIfPresent("iter", iter_);
if (resetOnRestart_)
{
reset();
}
else
{
forAll(fieldNames_, fieldi)
{
const word& fieldName = fieldNames_[fieldi];
if (conditionDict.found(fieldName))
{
const dictionary& valueDict = conditionDict.subDict(fieldName);
valueDict.readIfPresent("totalTime", totalTime_[fieldi]);
}
else
{
conditionDict.set(fieldName, dictionary());
}
}
}
} }
@ -118,53 +74,18 @@ bool Foam::functionObjects::runTimeControls::averageCondition::apply()
return true; return true;
} }
bool satisfied = iter_ > nIterStartUp_; bool running = iter_ > nIterStartUp_;
++iter_; ++iter_;
const scalar dt = obr_.time().deltaTValue(); dictionary& conditionDict = this->conditionDict();
Log << " " << type() << ": " << name_ << " averages:" << nl;
DynamicList<label> unprocessedFields(fieldNames_.size()); Info<< incrIndent;
running = valueAverageBase::calculate(conditionDict) && running;
Info<< decrIndent;
forAll(fieldNames_, fieldi) return running;
{
totalTime_[fieldi] += dt;
bool processed = false;
calc<scalar>(fieldi, satisfied, processed);
calc<vector>(fieldi, satisfied, processed);
calc<sphericalTensor>(fieldi, satisfied, processed);
calc<symmTensor>(fieldi, satisfied, processed);
calc<tensor>(fieldi, satisfied, processed);
if (!processed)
{
unprocessedFields.append(fieldi);
}
}
if (unprocessedFields.size())
{
WarningInFunction
<< "From function object: " << functionObjectName_ << nl
<< "Unprocessed fields:" << nl;
for (const label fieldi : unprocessedFields)
{
Info<< " " << fieldNames_[fieldi] << nl;
}
if (unprocessedFields.size() == fieldNames_.size())
{
satisfied = false;
}
}
Log << endl;
return satisfied;
} }
@ -172,22 +93,7 @@ void Foam::functionObjects::runTimeControls::averageCondition::write()
{ {
dictionary& conditionDict = this->conditionDict(); dictionary& conditionDict = this->conditionDict();
forAll(fieldNames_, fieldi) valueAverageBase::writeState(conditionDict);
{
const word& fieldName = fieldNames_[fieldi];
if (conditionDict.found(fieldName))
{
dictionary& valueDict = conditionDict.subDict(fieldName);
valueDict.add("totalTime", totalTime_[fieldi], true);
}
else
{
dictionary valueDict;
valueDict.add("totalTime", totalTime_[fieldi], true);
conditionDict.add(fieldName, valueDict);
}
}
conditionDict.set("iter", iter_); conditionDict.set("iter", iter_);
} }
@ -195,18 +101,9 @@ void Foam::functionObjects::runTimeControls::averageCondition::write()
void Foam::functionObjects::runTimeControls::averageCondition::reset() void Foam::functionObjects::runTimeControls::averageCondition::reset()
{ {
dictionary& conditionDict = this->conditionDict(); valueAverageBase::resetState(this->conditionDict());
forAll(fieldNames_, fieldi) iter_ = 0;
{
const word& fieldName = fieldNames_[fieldi];
conditionDict.set(fieldName, dictionary());
totalTime_[fieldi] = 0;
}
iter_ = -1;
conditionDict.set("iter", iter_);
} }

View File

@ -5,8 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,18 +30,20 @@ Description
Average run time condition - satisfied when average does not change by Average run time condition - satisfied when average does not change by
more than a given value. more than a given value.
See also
- Foam::functionObjects::valueAverageBase
SourceFiles SourceFiles
averageCondition.H averageCondition.H
averageCondition.C averageCondition.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef averageCondition_H #ifndef functionObjects_runTimeControls_averageCondition_H
#define averageCondition_H #define functionObjects_runTimeControls_averageCondition_H
#include "runTimeCondition.H" #include "runTimeCondition.H"
#include "Switch.H" #include "valueAverageBase.H"
#include "Enum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -59,64 +60,19 @@ namespace runTimeControls
class averageCondition class averageCondition
: :
public runTimeCondition public runTimeCondition,
public valueAverageBase
{ {
public:
// Public enumerations
enum class windowType
{
NONE,
APPROXIMATE,
EXACT
};
static const Enum<windowType> windowTypeNames;
protected: protected:
// Protected Data // Protected Data
//- Name of function object to retrieve data from
word functionObjectName_;
//- List of fields on which to operate
wordList fieldNames_;
//- Satisfied when difference in mean values is less than this value
const scalar tolerance_;
//- Averaging window
const scalar window_;
//- Averaging window type
windowType windowType_;
//- Average time per field
List<scalar> totalTime_;
//- Reset the averaging process on restart flag
Switch resetOnRestart_;
//- Number of start-up iterations before allowing satisfied checks //- Number of start-up iterations before allowing satisfied checks
label nIterStartUp_; label nIterStartUp_;
//- Current iteration count //- Current iteration count
label iter_; label iter_;
// Protected Member Functions
//- Templated function to calculate the average
template<class Type>
void calc
(
const label fieldi,
bool& satisfied,
bool& processed
);
public: public:
@ -157,12 +113,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "averageConditionTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -58,6 +58,7 @@ Foam::functionObjects::runTimeControls::runTimeControl::satisfiedActionNames
{ satisfiedAction::SET_TRIGGER, "setTrigger"}, { satisfiedAction::SET_TRIGGER, "setTrigger"},
}; };
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::runTimeControls::runTimeControl::runTimeControl Foam::functionObjects::runTimeControls::runTimeControl::runTimeControl
@ -100,6 +101,8 @@ bool Foam::functionObjects::runTimeControls::runTimeControl::read
if (fvMeshFunctionObject::read(dict)) if (fvMeshFunctionObject::read(dict))
{ {
Info<< type() << " " << name() << ":" << nl;
const dictionary& conditionsDict = dict.subDict("conditions"); const dictionary& conditionsDict = dict.subDict("conditions");
const wordList conditionNames(conditionsDict.toc()); const wordList conditionNames(conditionsDict.toc());
conditions_.setSize(conditionNames.size()); conditions_.setSize(conditionNames.size());
@ -129,9 +132,7 @@ bool Foam::functionObjects::runTimeControls::runTimeControl::read
// Check that some conditions are set // Check that some conditions are set
if (conditions_.empty()) if (conditions_.empty())
{ {
Info<< type() << " " << name() << " output:" << nl Info<< " No conditions present" << endl;
<< " No conditions present" << nl
<< endl;
} }
else else
{ {
@ -148,12 +149,12 @@ bool Foam::functionObjects::runTimeControls::runTimeControl::read
if (!check) if (!check)
{ {
Info<< type() << " " << name() << " output:" << nl Info<< " All conditions are inactive" << endl;
<< " All conditions are inactive" << nl
<< endl;
} }
} }
Info<< endl;
// Set the action to perform when all conditions are satisfied // Set the action to perform when all conditions are satisfied
// - set to end for backwards compatibility with v1806 // - set to end for backwards compatibility with v1806
satisfiedAction_ = satisfiedAction_ =