mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: Refactored valueAverage FO and average runTimeCondition
This commit is contained in:
committed by
Mark Olesen
parent
bb04f5759d
commit
3d134167dd
@ -5,8 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2015 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -28,7 +27,6 @@ License
|
||||
|
||||
#include "averageCondition.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * 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 * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::functionObjects::runTimeControls::averageCondition::averageCondition
|
||||
@ -67,45 +53,15 @@ Foam::functionObjects::runTimeControls::averageCondition::averageCondition
|
||||
)
|
||||
:
|
||||
runTimeCondition(name, obr, dict, state),
|
||||
functionObjectName_(dict.get<word>("functionObject")),
|
||||
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)),
|
||||
valueAverageBase(name, obr_, dict, state, false),
|
||||
nIterStartUp_(dict.getOrDefault<label>("nIterStartUp", 10)),
|
||||
iter_(-1)
|
||||
{
|
||||
dictionary& conditionDict = this->conditionDict();
|
||||
|
||||
readState(conditionDict);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool satisfied = iter_ > nIterStartUp_;
|
||||
bool running = iter_ > nIterStartUp_;
|
||||
|
||||
++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)
|
||||
{
|
||||
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;
|
||||
return running;
|
||||
}
|
||||
|
||||
|
||||
@ -172,22 +93,7 @@ void Foam::functionObjects::runTimeControls::averageCondition::write()
|
||||
{
|
||||
dictionary& conditionDict = this->conditionDict();
|
||||
|
||||
forAll(fieldNames_, fieldi)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
valueAverageBase::writeState(conditionDict);
|
||||
|
||||
conditionDict.set("iter", iter_);
|
||||
}
|
||||
@ -195,18 +101,9 @@ void Foam::functionObjects::runTimeControls::averageCondition::write()
|
||||
|
||||
void Foam::functionObjects::runTimeControls::averageCondition::reset()
|
||||
{
|
||||
dictionary& conditionDict = this->conditionDict();
|
||||
valueAverageBase::resetState(this->conditionDict());
|
||||
|
||||
forAll(fieldNames_, fieldi)
|
||||
{
|
||||
const word& fieldName = fieldNames_[fieldi];
|
||||
|
||||
conditionDict.set(fieldName, dictionary());
|
||||
totalTime_[fieldi] = 0;
|
||||
}
|
||||
|
||||
iter_ = -1;
|
||||
conditionDict.set("iter", iter_);
|
||||
iter_ = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -5,8 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2015 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -31,18 +30,20 @@ Description
|
||||
Average run time condition - satisfied when average does not change by
|
||||
more than a given value.
|
||||
|
||||
See also
|
||||
- Foam::functionObjects::valueAverageBase
|
||||
|
||||
SourceFiles
|
||||
averageCondition.H
|
||||
averageCondition.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef averageCondition_H
|
||||
#define averageCondition_H
|
||||
#ifndef functionObjects_runTimeControls_averageCondition_H
|
||||
#define functionObjects_runTimeControls_averageCondition_H
|
||||
|
||||
#include "runTimeCondition.H"
|
||||
#include "Switch.H"
|
||||
#include "Enum.H"
|
||||
#include "valueAverageBase.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -59,64 +60,19 @@ namespace runTimeControls
|
||||
|
||||
class averageCondition
|
||||
:
|
||||
public runTimeCondition
|
||||
public runTimeCondition,
|
||||
public valueAverageBase
|
||||
{
|
||||
public:
|
||||
|
||||
// Public enumerations
|
||||
|
||||
enum class windowType
|
||||
{
|
||||
NONE,
|
||||
APPROXIMATE,
|
||||
EXACT
|
||||
};
|
||||
|
||||
static const Enum<windowType> windowTypeNames;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// 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
|
||||
label nIterStartUp_;
|
||||
|
||||
//- Current iteration count
|
||||
label iter_;
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Templated function to calculate the average
|
||||
template<class Type>
|
||||
void calc
|
||||
(
|
||||
const label fieldi,
|
||||
bool& satisfied,
|
||||
bool& processed
|
||||
);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@ -157,12 +113,6 @@ public:
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "averageConditionTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -1,179 +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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "Time.H"
|
||||
#include "FIFOStack.H"
|
||||
|
||||
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::functionObjects::runTimeControls::averageCondition::calc
|
||||
(
|
||||
const label fieldi,
|
||||
bool& satisfied,
|
||||
bool& processed
|
||||
)
|
||||
{
|
||||
const word& fieldName = fieldNames_[fieldi];
|
||||
|
||||
const word valueType =
|
||||
state_.objectResultType(functionObjectName_, fieldName);
|
||||
|
||||
if (pTraits<Type>::typeName != valueType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const scalar dt = obr_.time().deltaTValue();
|
||||
|
||||
const Type currentValue =
|
||||
state_.getObjectResult<Type>(functionObjectName_, fieldName);
|
||||
const word meanName(fieldName + "Mean");
|
||||
|
||||
// Current mean value
|
||||
Type meanValue = state_.getResult<Type>(meanName);
|
||||
|
||||
switch (windowType_)
|
||||
{
|
||||
case windowType::NONE:
|
||||
{
|
||||
const scalar Dt = totalTime_[fieldi];
|
||||
const scalar alpha = (Dt - dt)/Dt;
|
||||
const scalar beta = dt/Dt;
|
||||
meanValue = alpha*meanValue + beta*currentValue;
|
||||
|
||||
break;
|
||||
}
|
||||
case windowType::APPROXIMATE:
|
||||
{
|
||||
const scalar Dt = totalTime_[fieldi];
|
||||
scalar alpha = (Dt - dt)/Dt;
|
||||
scalar beta = dt/Dt;
|
||||
if (Dt - dt >= window_)
|
||||
{
|
||||
alpha = (window_ - dt)/window_;
|
||||
beta = dt/window_;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ensure that averaging is performed over window time
|
||||
// before condition can be satisfied
|
||||
satisfied = false;
|
||||
}
|
||||
|
||||
meanValue = alpha*meanValue + beta*currentValue;
|
||||
totalTime_[fieldi] += dt;
|
||||
break;
|
||||
}
|
||||
case windowType::EXACT:
|
||||
{
|
||||
FIFOStack<scalar> windowTimes;
|
||||
FIFOStack<Type> windowValues;
|
||||
dictionary& dict = this->conditionDict().subDict(fieldName);
|
||||
dict.readIfPresent("windowTimes", windowTimes);
|
||||
dict.readIfPresent("windowValues", windowValues);
|
||||
|
||||
// Increment time for all existing values
|
||||
for (scalar& dti : windowTimes)
|
||||
{
|
||||
dti += dt;
|
||||
}
|
||||
|
||||
// Remove any values outside the window
|
||||
bool removeValue = true;
|
||||
while (removeValue && windowTimes.size())
|
||||
{
|
||||
removeValue = windowTimes.first() > window_;
|
||||
|
||||
if (removeValue)
|
||||
{
|
||||
windowTimes.pop();
|
||||
windowValues.pop();
|
||||
}
|
||||
}
|
||||
|
||||
// Add the current value
|
||||
windowTimes.push(dt);
|
||||
windowValues.push(currentValue);
|
||||
|
||||
// Calculate the window average
|
||||
auto timeIter = windowTimes.cbegin();
|
||||
auto valueIter = windowValues.cbegin();
|
||||
|
||||
meanValue = pTraits<Type>::zero;
|
||||
Type valueOld(pTraits<Type>::zero);
|
||||
|
||||
for
|
||||
(
|
||||
label i = 0;
|
||||
timeIter.good();
|
||||
++i, ++timeIter, ++valueIter
|
||||
)
|
||||
{
|
||||
const Type& value = valueIter();
|
||||
const scalar dt = timeIter();
|
||||
|
||||
meanValue += dt*value;
|
||||
|
||||
if (i)
|
||||
{
|
||||
meanValue -= dt*valueOld;
|
||||
}
|
||||
|
||||
valueOld = value;
|
||||
}
|
||||
|
||||
meanValue /= windowTimes.first();
|
||||
|
||||
// Store the state information for the next step
|
||||
dict.set("windowTimes", windowTimes);
|
||||
dict.set("windowValues", windowValues);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scalar delta = mag(meanValue - currentValue);
|
||||
|
||||
Log << " " << meanName << ": " << meanValue
|
||||
<< ", delta: " << delta << nl;
|
||||
|
||||
// Note: Writing result to owner function object and not the local run-time
|
||||
// condition
|
||||
state_.setResult(meanName, meanValue);
|
||||
|
||||
if (delta > tolerance_)
|
||||
{
|
||||
satisfied = false;
|
||||
}
|
||||
|
||||
processed = true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -58,6 +58,7 @@ Foam::functionObjects::runTimeControls::runTimeControl::satisfiedActionNames
|
||||
{ satisfiedAction::SET_TRIGGER, "setTrigger"},
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::functionObjects::runTimeControls::runTimeControl::runTimeControl
|
||||
@ -100,6 +101,8 @@ bool Foam::functionObjects::runTimeControls::runTimeControl::read
|
||||
|
||||
if (fvMeshFunctionObject::read(dict))
|
||||
{
|
||||
Info<< type() << " " << name() << ":" << nl;
|
||||
|
||||
const dictionary& conditionsDict = dict.subDict("conditions");
|
||||
const wordList conditionNames(conditionsDict.toc());
|
||||
conditions_.setSize(conditionNames.size());
|
||||
@ -129,9 +132,7 @@ bool Foam::functionObjects::runTimeControls::runTimeControl::read
|
||||
// Check that some conditions are set
|
||||
if (conditions_.empty())
|
||||
{
|
||||
Info<< type() << " " << name() << " output:" << nl
|
||||
<< " No conditions present" << nl
|
||||
<< endl;
|
||||
Info<< " No conditions present" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -148,12 +149,12 @@ bool Foam::functionObjects::runTimeControls::runTimeControl::read
|
||||
|
||||
if (!check)
|
||||
{
|
||||
Info<< type() << " " << name() << " output:" << nl
|
||||
<< " All conditions are inactive" << nl
|
||||
<< endl;
|
||||
Info<< " All conditions are inactive" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< endl;
|
||||
|
||||
// Set the action to perform when all conditions are satisfied
|
||||
// - set to end for backwards compatibility with v1806
|
||||
satisfiedAction_ =
|
||||
|
||||
Reference in New Issue
Block a user