mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: Updated fieldAverage FO windowing. See #525
When specifying the averaging data, a new `windowType` option is available, taking the values: - none: no windowing - approximate: past functionality (v1706 and earlier) - exact: exact moving average - will store and write (for restart) all fields in the window
This commit is contained in:
@ -579,9 +579,8 @@ bool Foam::functionObjectList::execute()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force writing of state dictionary after function object execution
|
// Force writing of state dictionary after function object execution
|
||||||
if (time_.outputTime())
|
if (time_.writeTime())
|
||||||
{
|
{
|
||||||
label oldPrecision = IOstream::precision_;
|
label oldPrecision = IOstream::precision_;
|
||||||
IOstream::precision_ = 16;
|
IOstream::precision_ = 16;
|
||||||
|
|||||||
@ -44,21 +44,21 @@ namespace functionObjects
|
|||||||
|
|
||||||
void Foam::functionObjects::fieldAverage::resetFields()
|
void Foam::functionObjects::fieldAverage::resetFields()
|
||||||
{
|
{
|
||||||
forAll(faItems_, i)
|
for (const fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
if (faItems_[i].mean())
|
if (item.mean())
|
||||||
{
|
{
|
||||||
if (obr().found(faItems_[i].meanFieldName()))
|
if (obr().found(item.meanFieldName()))
|
||||||
{
|
{
|
||||||
obr().checkOut(*obr()[faItems_[i].meanFieldName()]);
|
obr().checkOut(*obr()[item.meanFieldName()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (faItems_[i].prime2Mean())
|
if (item.prime2Mean())
|
||||||
{
|
{
|
||||||
if (obr().found(faItems_[i].prime2MeanFieldName()))
|
if (obr().found(item.prime2MeanFieldName()))
|
||||||
{
|
{
|
||||||
obr().checkOut(*obr()[faItems_[i].prime2MeanFieldName()]);
|
obr().checkOut(*obr()[item.prime2MeanFieldName()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,25 +67,9 @@ void Foam::functionObjects::fieldAverage::resetFields()
|
|||||||
|
|
||||||
void Foam::functionObjects::fieldAverage::initialize()
|
void Foam::functionObjects::fieldAverage::initialize()
|
||||||
{
|
{
|
||||||
if (!totalIter_.size())
|
for (fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
totalIter_.setSize(faItems_.size(), 1);
|
item.restart(0, false);
|
||||||
}
|
|
||||||
|
|
||||||
if (!totalTime_.size())
|
|
||||||
{
|
|
||||||
totalTime_.setSize(faItems_.size(), obr_.time().deltaTValue());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Check if totalTime_ has been set otherwise initialize
|
|
||||||
forAll(totalTime_, fieldi)
|
|
||||||
{
|
|
||||||
if (totalTime_[fieldi] < 0)
|
|
||||||
{
|
|
||||||
totalTime_[fieldi] = obr_.time().deltaTValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resetFields();
|
resetFields();
|
||||||
@ -93,28 +77,39 @@ void Foam::functionObjects::fieldAverage::initialize()
|
|||||||
Log << type() << " " << name() << ":" << nl;
|
Log << type() << " " << name() << ":" << nl;
|
||||||
|
|
||||||
// Add mean fields to the field lists
|
// Add mean fields to the field lists
|
||||||
forAll(faItems_, fieldi)
|
for (fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
addMeanField<scalar>(fieldi);
|
addMeanField<scalar>(item);
|
||||||
addMeanField<vector>(fieldi);
|
addMeanField<vector>(item);
|
||||||
addMeanField<sphericalTensor>(fieldi);
|
addMeanField<sphericalTensor>(item);
|
||||||
addMeanField<symmTensor>(fieldi);
|
addMeanField<symmTensor>(item);
|
||||||
addMeanField<tensor>(fieldi);
|
addMeanField<tensor>(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add prime-squared mean fields to the field lists
|
// Add prime-squared mean fields to the field lists
|
||||||
forAll(faItems_, fieldi)
|
for (fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
addPrime2MeanField<scalar, scalar>(fieldi);
|
addPrime2MeanField<scalar, scalar>(item);
|
||||||
addPrime2MeanField<vector, symmTensor>(fieldi);
|
addPrime2MeanField<vector, symmTensor>(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
forAll(faItems_, fieldi)
|
// Add window fields to the field lists
|
||||||
|
for (const fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
if (!faItems_[fieldi].active())
|
restoreWindowFields<scalar>(item);
|
||||||
|
restoreWindowFields<vector>(item);
|
||||||
|
restoreWindowFields<sphericalTensor>(item);
|
||||||
|
restoreWindowFields<symmTensor>(item);
|
||||||
|
restoreWindowFields<tensor>(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (const fieldAverageItem& item : faItems_)
|
||||||
|
{
|
||||||
|
if (!item.active())
|
||||||
{
|
{
|
||||||
WarningInFunction
|
WarningInFunction
|
||||||
<< "Field " << faItems_[fieldi].fieldName()
|
<< "Field " << item.fieldName()
|
||||||
<< " not found in database for averaging";
|
<< " not found in database for averaging";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,8 +128,10 @@ void Foam::functionObjects::fieldAverage::restart()
|
|||||||
<< obr().time().timeOutputValue()
|
<< obr().time().timeOutputValue()
|
||||||
<< nl << endl;
|
<< nl << endl;
|
||||||
|
|
||||||
totalIter_.clear();
|
for (fieldAverageItem& item : faItems_)
|
||||||
totalTime_.clear();
|
{
|
||||||
|
item.restart(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
@ -180,6 +177,17 @@ void Foam::functionObjects::fieldAverage::calcAverages()
|
|||||||
Log << type() << " " << name() << " write:" << nl
|
Log << type() << " " << name() << " write:" << nl
|
||||||
<< " Calculating averages" << nl;
|
<< " Calculating averages" << nl;
|
||||||
|
|
||||||
|
forAll(faItems_, fieldi)
|
||||||
|
{
|
||||||
|
faItems_[fieldi].evolve(obr());
|
||||||
|
}
|
||||||
|
|
||||||
|
storeWindowFields<scalar>();
|
||||||
|
storeWindowFields<vector>();
|
||||||
|
storeWindowFields<sphericalTensor>();
|
||||||
|
storeWindowFields<symmTensor>();
|
||||||
|
storeWindowFields<tensor>();
|
||||||
|
|
||||||
addMeanSqrToPrime2Mean<scalar, scalar>();
|
addMeanSqrToPrime2Mean<scalar, scalar>();
|
||||||
addMeanSqrToPrime2Mean<vector, symmTensor>();
|
addMeanSqrToPrime2Mean<vector, symmTensor>();
|
||||||
|
|
||||||
@ -192,12 +200,6 @@ void Foam::functionObjects::fieldAverage::calcAverages()
|
|||||||
calculatePrime2MeanFields<scalar, scalar>();
|
calculatePrime2MeanFields<scalar, scalar>();
|
||||||
calculatePrime2MeanFields<vector, symmTensor>();
|
calculatePrime2MeanFields<vector, symmTensor>();
|
||||||
|
|
||||||
forAll(faItems_, fieldi)
|
|
||||||
{
|
|
||||||
totalIter_[fieldi]++;
|
|
||||||
totalTime_[fieldi] += obr().time().deltaTValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
Log << endl;
|
Log << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,28 +220,17 @@ void Foam::functionObjects::fieldAverage::writeAverages() const
|
|||||||
|
|
||||||
void Foam::functionObjects::fieldAverage::writeAveragingProperties()
|
void Foam::functionObjects::fieldAverage::writeAveragingProperties()
|
||||||
{
|
{
|
||||||
forAll(faItems_, fieldi)
|
for (const fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
const word& fieldName = faItems_[fieldi].fieldName();
|
|
||||||
|
|
||||||
dictionary propsDict;
|
dictionary propsDict;
|
||||||
propsDict.add("totalIter", totalIter_[fieldi]);
|
item.writeState(propsDict);
|
||||||
propsDict.add("totalTime", totalTime_[fieldi]);
|
setProperty(item.fieldName(), propsDict);
|
||||||
setProperty(fieldName, propsDict);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::functionObjects::fieldAverage::readAveragingProperties()
|
void Foam::functionObjects::fieldAverage::readAveragingProperties()
|
||||||
{
|
{
|
||||||
totalIter_.clear();
|
|
||||||
totalIter_.setSize(faItems_.size(), 1);
|
|
||||||
|
|
||||||
// Initialize totalTime with negative values
|
|
||||||
// to indicate that it has not been set
|
|
||||||
totalTime_.clear();
|
|
||||||
totalTime_.setSize(faItems_.size(), -1);
|
|
||||||
|
|
||||||
if (restartOnRestart_ || restartOnOutput_)
|
if (restartOnRestart_ || restartOnOutput_)
|
||||||
{
|
{
|
||||||
Info<< " Starting averaging at time "
|
Info<< " Starting averaging at time "
|
||||||
@ -251,22 +242,20 @@ void Foam::functionObjects::fieldAverage::readAveragingProperties()
|
|||||||
Info<< " Restarting averaging for fields:" << nl;
|
Info<< " Restarting averaging for fields:" << nl;
|
||||||
|
|
||||||
|
|
||||||
forAll(faItems_, fieldi)
|
for (fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
const word& fieldName = faItems_[fieldi].fieldName();
|
const word& fieldName = item.fieldName();
|
||||||
if (foundProperty(fieldName))
|
if (foundProperty(fieldName))
|
||||||
{
|
{
|
||||||
dictionary fieldDict;
|
dictionary fieldDict;
|
||||||
getDict(fieldName, fieldDict);
|
getDict(fieldName, fieldDict);
|
||||||
|
item.readState(fieldDict);
|
||||||
totalIter_[fieldi] = readLabel(fieldDict.lookup("totalIter"));
|
|
||||||
totalTime_[fieldi] = readScalar(fieldDict.lookup("totalTime"));
|
|
||||||
|
|
||||||
scalar userTotalTime =
|
scalar userTotalTime =
|
||||||
obr().time().timeToUserTime(totalTime_[fieldi]);
|
obr().time().timeToUserTime(item.totalTime());
|
||||||
|
|
||||||
Info<< " " << fieldName
|
Info<< " " << fieldName
|
||||||
<< " iters = " << totalIter_[fieldi]
|
<< " iters = " << item.totalIter()
|
||||||
<< " time = " << userTotalTime << nl;
|
<< " time = " << userTotalTime << nl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -298,8 +287,6 @@ Foam::functionObjects::fieldAverage::fieldAverage
|
|||||||
restartTime_(GREAT),
|
restartTime_(GREAT),
|
||||||
initialised_(false),
|
initialised_(false),
|
||||||
faItems_(),
|
faItems_(),
|
||||||
totalIter_(),
|
|
||||||
totalTime_(),
|
|
||||||
periodIndex_(1)
|
periodIndex_(1)
|
||||||
{
|
{
|
||||||
read(dict);
|
read(dict);
|
||||||
@ -321,10 +308,10 @@ bool Foam::functionObjects::fieldAverage::read(const dictionary& dict)
|
|||||||
// Make certain that the values are consistent with the defaults:
|
// Make certain that the values are consistent with the defaults:
|
||||||
initialised_ = false;
|
initialised_ = false;
|
||||||
restartOnRestart_ = false;
|
restartOnRestart_ = false;
|
||||||
restartOnOutput_ = false;
|
restartOnOutput_ = false;
|
||||||
periodicRestart_ = false;
|
periodicRestart_ = false;
|
||||||
restartPeriod_ = GREAT;
|
restartPeriod_ = GREAT;
|
||||||
restartTime_ = GREAT;
|
restartTime_ = GREAT;
|
||||||
|
|
||||||
Info<< type() << " " << name() << ":" << nl;
|
Info<< type() << " " << name() << ":" << nl;
|
||||||
|
|
||||||
|
|||||||
@ -86,6 +86,7 @@ Usage
|
|||||||
mean on;
|
mean on;
|
||||||
prime2Mean on;
|
prime2Mean on;
|
||||||
base time;
|
base time;
|
||||||
|
windowType exact;
|
||||||
window 10.0;
|
window 10.0;
|
||||||
windowName w1;
|
windowName w1;
|
||||||
}
|
}
|
||||||
@ -131,6 +132,7 @@ SourceFiles
|
|||||||
#define functionObjects_fieldAverage_H
|
#define functionObjects_fieldAverage_H
|
||||||
|
|
||||||
#include "fvMeshFunctionObject.H"
|
#include "fvMeshFunctionObject.H"
|
||||||
|
#include "FIFOStack.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -208,19 +210,19 @@ protected:
|
|||||||
|
|
||||||
//- Add mean average field to database
|
//- Add mean average field to database
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void addMeanFieldType(const label fieldi);
|
void addMeanFieldType(fieldAverageItem& item);
|
||||||
|
|
||||||
//- Add mean average field to database
|
//- Add mean average field to database
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void addMeanField(const label fieldi);
|
void addMeanField(fieldAverageItem& item);
|
||||||
|
|
||||||
//- Add prime-squared average field to database
|
//- Add prime-squared average field to database
|
||||||
template<class Type1, class Type2>
|
template<class Type1, class Type2>
|
||||||
void addPrime2MeanFieldType(const label fieldi);
|
void addPrime2MeanFieldType(fieldAverageItem& item);
|
||||||
|
|
||||||
//- Add prime-squared average field to database
|
//- Add prime-squared average field to database
|
||||||
template<class Type1, class Type2>
|
template<class Type1, class Type2>
|
||||||
void addPrime2MeanField(const label fieldi);
|
void addPrime2MeanField(fieldAverageItem& item);
|
||||||
|
|
||||||
|
|
||||||
// Calculation functions
|
// Calculation functions
|
||||||
@ -228,30 +230,33 @@ protected:
|
|||||||
//- Main calculation routine
|
//- Main calculation routine
|
||||||
virtual void calcAverages();
|
virtual void calcAverages();
|
||||||
|
|
||||||
//- Calculate mean average fields
|
|
||||||
template<class Type>
|
|
||||||
void calculateMeanFieldType(const label fieldi) const;
|
|
||||||
|
|
||||||
//- Calculate mean average fields
|
//- Calculate mean average fields
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void calculateMeanFields() const;
|
void calculateMeanFields() const;
|
||||||
|
|
||||||
//- Calculate prime-squared average fields
|
|
||||||
template<class Type1, class Type2>
|
|
||||||
void calculatePrime2MeanFieldType(const label fieldi) const;
|
|
||||||
|
|
||||||
//- Calculate prime-squared average fields
|
//- Calculate prime-squared average fields
|
||||||
template<class Type1, class Type2>
|
template<class Type1, class Type2>
|
||||||
void calculatePrime2MeanFields() const;
|
void calculatePrime2MeanFields() const;
|
||||||
|
|
||||||
//- Add mean-squared field value to prime-squared mean field
|
//- Add mean-squared field value to prime-squared mean field
|
||||||
template<class Type1, class Type2>
|
template<class Type1, class Type2>
|
||||||
void addMeanSqrToPrime2MeanType(const label fieldi) const;
|
void addMeanSqrToPrime2MeanType(const fieldAverageItem& item) const;
|
||||||
|
|
||||||
//- Add mean-squared field value to prime-squared mean field
|
//- Add mean-squared field value to prime-squared mean field
|
||||||
template<class Type1, class Type2>
|
template<class Type1, class Type2>
|
||||||
void addMeanSqrToPrime2Mean() const;
|
void addMeanSqrToPrime2Mean() const;
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void storeWindowFieldType(fieldAverageItem& item);
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void storeWindowFields();
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void restoreWindowFieldsType(const fieldAverageItem& item);
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void restoreWindowFields(const fieldAverageItem& item);
|
||||||
|
|
||||||
// I-O
|
// I-O
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -32,6 +32,7 @@ const Foam::word Foam::functionObjects::fieldAverageItem::EXT_MEAN
|
|||||||
"Mean"
|
"Mean"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const Foam::word Foam::functionObjects::fieldAverageItem::EXT_PRIME2MEAN
|
const Foam::word Foam::functionObjects::fieldAverageItem::EXT_PRIME2MEAN
|
||||||
(
|
(
|
||||||
"Prime2Mean"
|
"Prime2Mean"
|
||||||
@ -49,6 +50,18 @@ Foam::functionObjects::fieldAverageItem::baseTypeNames_
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::Enum
|
||||||
|
<
|
||||||
|
Foam::functionObjects::fieldAverageItem::windowType
|
||||||
|
>
|
||||||
|
Foam::functionObjects::fieldAverageItem::windowTypeNames_
|
||||||
|
{
|
||||||
|
{ windowType::NONE, "none" },
|
||||||
|
{ windowType::APPROXIMATE, "approximate" },
|
||||||
|
{ windowType::EXACT, "exact" },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::functionObjects::fieldAverageItem::fieldAverageItem()
|
Foam::functionObjects::fieldAverageItem::fieldAverageItem()
|
||||||
@ -59,9 +72,15 @@ Foam::functionObjects::fieldAverageItem::fieldAverageItem()
|
|||||||
meanFieldName_("unknown"),
|
meanFieldName_("unknown"),
|
||||||
prime2Mean_(0),
|
prime2Mean_(0),
|
||||||
prime2MeanFieldName_("unknown"),
|
prime2MeanFieldName_("unknown"),
|
||||||
base_(ITER),
|
base_(baseType::ITER),
|
||||||
window_(-1.0),
|
totalIter_(0),
|
||||||
windowName_("")
|
totalTime_(-1),
|
||||||
|
window_(-1),
|
||||||
|
windowName_(""),
|
||||||
|
windowType_(windowType::NONE),
|
||||||
|
|
||||||
|
windowTimes_(),
|
||||||
|
windowFieldNames_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -77,8 +96,14 @@ Foam::functionObjects::fieldAverageItem::fieldAverageItem
|
|||||||
prime2Mean_(faItem.prime2Mean_),
|
prime2Mean_(faItem.prime2Mean_),
|
||||||
prime2MeanFieldName_(faItem.prime2MeanFieldName_),
|
prime2MeanFieldName_(faItem.prime2MeanFieldName_),
|
||||||
base_(faItem.base_),
|
base_(faItem.base_),
|
||||||
|
totalIter_(faItem.totalIter_),
|
||||||
|
totalTime_(faItem.totalTime_),
|
||||||
window_(faItem.window_),
|
window_(faItem.window_),
|
||||||
windowName_(faItem.windowName_)
|
windowName_(faItem.windowName_),
|
||||||
|
windowType_(faItem.windowType_),
|
||||||
|
|
||||||
|
windowTimes_(faItem.windowTimes_),
|
||||||
|
windowFieldNames_(faItem.windowFieldNames_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -88,6 +113,94 @@ Foam::functionObjects::fieldAverageItem::~fieldAverageItem()
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::functionObjects::fieldAverageItem::addToWindow
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const scalar deltaT
|
||||||
|
)
|
||||||
|
{
|
||||||
|
windowTimes_.push(deltaT);
|
||||||
|
windowFieldNames_.push(fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::functionObjects::fieldAverageItem::evolve(const objectRegistry& obr)
|
||||||
|
{
|
||||||
|
totalIter_++;
|
||||||
|
totalTime_ += obr.time().deltaTValue();
|
||||||
|
forAllIters(windowTimes_, timeIter)
|
||||||
|
{
|
||||||
|
timeIter() += obr.time().deltaTValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any fields that have passed out of the window
|
||||||
|
bool removeItem = true;
|
||||||
|
|
||||||
|
while (removeItem && windowTimes_.size())
|
||||||
|
{
|
||||||
|
removeItem = !(inWindow(windowTimes_.first()));
|
||||||
|
|
||||||
|
if (removeItem)
|
||||||
|
{
|
||||||
|
windowTimes_.pop();
|
||||||
|
const word fieldName = windowFieldNames_.pop();
|
||||||
|
|
||||||
|
//Info<< "evolve: removing field: " << fieldName << endl;
|
||||||
|
obr.checkOut(*obr[fieldName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::functionObjects::fieldAverageItem::restart
|
||||||
|
(
|
||||||
|
const scalar time0,
|
||||||
|
const bool override
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (totalTime_ < 0 || override)
|
||||||
|
{
|
||||||
|
totalIter_ = 0;
|
||||||
|
totalTime_ = time0;
|
||||||
|
windowTimes_.clear();
|
||||||
|
windowFieldNames_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::functionObjects::fieldAverageItem::readState(const dictionary& dict)
|
||||||
|
{
|
||||||
|
dict.lookup("totalIter") >> totalIter_;
|
||||||
|
dict.lookup("totalTime") >> totalTime_;
|
||||||
|
|
||||||
|
if (window_ > 0)
|
||||||
|
{
|
||||||
|
dict.lookup("windowTimes") >> windowTimes_;
|
||||||
|
dict.lookup("windowFieldNames") >> windowFieldNames_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::functionObjects::fieldAverageItem::writeState
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
dict.add("totalIter", totalIter_);
|
||||||
|
dict.add("totalTime", totalTime_);
|
||||||
|
|
||||||
|
if (window_ > 0)
|
||||||
|
{
|
||||||
|
dict.add("windowTimes", windowTimes_);
|
||||||
|
dict.add("windowFieldNames", windowFieldNames_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::functionObjects::fieldAverageItem::operator=
|
void Foam::functionObjects::fieldAverageItem::operator=
|
||||||
@ -111,8 +224,13 @@ void Foam::functionObjects::fieldAverageItem::operator=
|
|||||||
prime2Mean_ = rhs.prime2Mean_;
|
prime2Mean_ = rhs.prime2Mean_;
|
||||||
prime2MeanFieldName_ = rhs.prime2MeanFieldName_;
|
prime2MeanFieldName_ = rhs.prime2MeanFieldName_;
|
||||||
base_ = rhs.base_;
|
base_ = rhs.base_;
|
||||||
|
totalIter_ = rhs.totalIter_;
|
||||||
|
totalTime_ = rhs.totalTime_;
|
||||||
window_ = rhs.window_;
|
window_ = rhs.window_;
|
||||||
windowName_ = rhs.windowName_;
|
windowName_ = rhs.windowName_;
|
||||||
|
windowType_ = rhs.windowType_;
|
||||||
|
windowTimes_ = rhs.windowTimes_;
|
||||||
|
windowFieldNames_ = rhs.windowFieldNames_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -35,12 +35,19 @@ Description
|
|||||||
base time; // iteration
|
base time; // iteration
|
||||||
window 200; // optional averaging window
|
window 200; // optional averaging window
|
||||||
windowName w1; // optional window name (default = "")
|
windowName w1; // optional window name (default = "")
|
||||||
|
windowType approximate; // window type
|
||||||
}
|
}
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
|
||||||
The averaging window corresponds to the averaging interval (iters or time)
|
The averaging window corresponds to the averaging interval (iters or time)
|
||||||
If not specified, the averaging is over 'all iters/time'
|
If not specified, the averaging is over 'all iters/time'
|
||||||
|
|
||||||
|
Available window types:
|
||||||
|
- \c none : no windowing
|
||||||
|
- \c exact : exact windowing - additional files will be stored and written
|
||||||
|
- \c approximate : approximate variant that does not store/write additional
|
||||||
|
fields
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
fieldAverageItem.C
|
fieldAverageItem.C
|
||||||
fieldAverageItemIO.C
|
fieldAverageItemIO.C
|
||||||
@ -52,6 +59,7 @@ SourceFiles
|
|||||||
|
|
||||||
#include "Enum.H"
|
#include "Enum.H"
|
||||||
#include "Switch.H"
|
#include "Switch.H"
|
||||||
|
#include "FIFOStack.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -61,6 +69,7 @@ namespace Foam
|
|||||||
// Forward declaration of classes
|
// Forward declaration of classes
|
||||||
class Istream;
|
class Istream;
|
||||||
class Ostream;
|
class Ostream;
|
||||||
|
class objectRegistry;
|
||||||
|
|
||||||
namespace functionObjects
|
namespace functionObjects
|
||||||
{
|
{
|
||||||
@ -88,13 +97,22 @@ public:
|
|||||||
//- Prime-squared average
|
//- Prime-squared average
|
||||||
static const word EXT_PRIME2MEAN;
|
static const word EXT_PRIME2MEAN;
|
||||||
|
|
||||||
|
|
||||||
//- Enumeration defining the averaging base type
|
//- Enumeration defining the averaging base type
|
||||||
enum baseType
|
enum class baseType
|
||||||
{
|
{
|
||||||
ITER,
|
ITER,
|
||||||
TIME
|
TIME
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//- Enumeration defining the averaging window type
|
||||||
|
enum class windowType
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
APPROXIMATE,
|
||||||
|
EXACT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -124,12 +142,30 @@ private:
|
|||||||
//- Averaging base type
|
//- Averaging base type
|
||||||
baseType base_;
|
baseType base_;
|
||||||
|
|
||||||
|
//- Total number of iterations item has been evolved
|
||||||
|
label totalIter_;
|
||||||
|
|
||||||
|
//- Total time item has been evolved
|
||||||
|
scalar totalTime_;
|
||||||
|
|
||||||
//- Averaging window - defaults to -1 for 'all iters/time'
|
//- Averaging window - defaults to -1 for 'all iters/time'
|
||||||
scalar window_;
|
scalar window_;
|
||||||
|
|
||||||
//- Averaging window name - defaults to 'window'
|
//- Averaging window name - defaults to 'window'
|
||||||
word windowName_;
|
word windowName_;
|
||||||
|
|
||||||
|
//- Averaging window type
|
||||||
|
windowType windowType_;
|
||||||
|
|
||||||
|
//- Averaging window type names
|
||||||
|
static const Enum<windowType> windowTypeNames_;
|
||||||
|
|
||||||
|
//- List of window times (windowType = EXACT)
|
||||||
|
FIFOStack<scalar> windowTimes_;
|
||||||
|
|
||||||
|
//- List of window field names (windowType = EXACT)
|
||||||
|
FIFOStack<word> windowFieldNames_;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -154,86 +190,87 @@ public:
|
|||||||
// Access
|
// Access
|
||||||
|
|
||||||
//- Return const access to the active flag
|
//- Return const access to the active flag
|
||||||
bool active() const
|
inline bool active() const;
|
||||||
{
|
|
||||||
return active_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return non-const access to the active flag
|
//- Return non-const access to the active flag
|
||||||
bool& active()
|
inline bool& active();
|
||||||
{
|
|
||||||
return active_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return const access to the field name
|
//- Return const access to the field name
|
||||||
const word& fieldName() const
|
inline const word& fieldName() const;
|
||||||
{
|
|
||||||
return fieldName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return const access to the mean flag
|
//- Return const access to the mean flag
|
||||||
bool mean() const
|
inline bool mean() const;
|
||||||
{
|
|
||||||
return mean_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return non-const access to the mean flag
|
//- Return non-const access to the mean flag
|
||||||
bool& mean()
|
inline bool& mean();
|
||||||
{
|
|
||||||
return mean_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return const access to the mean field name
|
//- Return const access to the mean field name
|
||||||
const word& meanFieldName() const
|
inline const word& meanFieldName() const;
|
||||||
{
|
|
||||||
return meanFieldName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return const access to the prime-squared mean flag
|
//- Return const access to the prime-squared mean flag
|
||||||
bool prime2Mean() const
|
inline bool prime2Mean() const;
|
||||||
{
|
|
||||||
return prime2Mean_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return non-const access to the prime-squared mean flag
|
//- Return non-const access to the prime-squared mean flag
|
||||||
bool& prime2Mean()
|
inline bool& prime2Mean();
|
||||||
{
|
|
||||||
return prime2Mean_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return const access to the prime-squared mean field name
|
//- Return const access to the prime-squared mean field name
|
||||||
const word& prime2MeanFieldName() const
|
inline const word& prime2MeanFieldName() const;
|
||||||
{
|
|
||||||
return prime2MeanFieldName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return averaging base type name
|
//- Return averaging base type name
|
||||||
const word base() const
|
inline const word& base() const;
|
||||||
{
|
|
||||||
return baseTypeNames_[base_];
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return true if base is ITER
|
//- Return the total number of iterations item has been evolved
|
||||||
bool iterBase() const
|
inline label totalIter() const;
|
||||||
{
|
|
||||||
return base_ == ITER;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return true if base is time
|
//- Return the total time item has been evolved
|
||||||
bool timeBase() const
|
inline scalar totalTime() const;
|
||||||
{
|
|
||||||
return base_ == TIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar window() const
|
//- Return the window length (iterations or seconds)
|
||||||
{
|
inline scalar window() const;
|
||||||
return window_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const word& windowName() const
|
//- Return the (optional) window name
|
||||||
{
|
inline const word& windowName() const;
|
||||||
return windowName_;
|
|
||||||
}
|
//- Return the list of window times (windowType = EXACT)
|
||||||
|
inline const FIFOStack<scalar>& windowTimes() const;
|
||||||
|
|
||||||
|
//- Return the list of window field names (windowType = EXACT)
|
||||||
|
inline const FIFOStack<word>& windowFieldNames() const;
|
||||||
|
|
||||||
|
//- Return the current time interval
|
||||||
|
inline scalar dt(const scalar deltaT) const;
|
||||||
|
|
||||||
|
//- Return the total time interval
|
||||||
|
inline scalar Dt() const;
|
||||||
|
|
||||||
|
//- Helper function to construct a window field name
|
||||||
|
inline word windowFieldName(const word& prefix) const;
|
||||||
|
|
||||||
|
//- Return true if time is inside window (including boundaries)
|
||||||
|
inline bool inWindow(const scalar t) const;
|
||||||
|
|
||||||
|
//- Add field to window
|
||||||
|
void addToWindow(const word& fieldName, const scalar deltaT);
|
||||||
|
|
||||||
|
//- Evolve and update
|
||||||
|
void evolve(const objectRegistry& obr);
|
||||||
|
|
||||||
|
//- Restart
|
||||||
|
void restart(const scalar time0, const bool override);
|
||||||
|
|
||||||
|
//- Read state and re-initialise values
|
||||||
|
bool readState(const dictionary& dict);
|
||||||
|
|
||||||
|
//- Write state for restart
|
||||||
|
void writeState(dictionary& dict) const;
|
||||||
|
|
||||||
|
//- Calculate the mean field value
|
||||||
|
template<class Type>
|
||||||
|
bool calculateMeanField(const objectRegistry& obr) const;
|
||||||
|
|
||||||
|
//- Calculate prime-squared average fields
|
||||||
|
template<class Type1, class Type2>
|
||||||
|
bool calculatePrime2MeanField(const objectRegistry& obr) const;
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
@ -257,8 +294,11 @@ public:
|
|||||||
&& a.prime2Mean_ == b.prime2Mean_
|
&& a.prime2Mean_ == b.prime2Mean_
|
||||||
&& a.prime2MeanFieldName_ == b.prime2MeanFieldName_
|
&& a.prime2MeanFieldName_ == b.prime2MeanFieldName_
|
||||||
&& a.base_ == b.base_
|
&& a.base_ == b.base_
|
||||||
|
&& a.totalIter_ == b.totalIter_
|
||||||
|
&& a.totalTime_ == b.totalTime_
|
||||||
&& a.window_ == b.window_
|
&& a.window_ == b.window_
|
||||||
&& a.windowName_ == b.windowName_;
|
&& a.windowName_ == b.windowName_
|
||||||
|
&& a.windowType_ == b.windowType_;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=
|
friend bool operator!=
|
||||||
@ -285,6 +325,16 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "fieldAverageItemI.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "fieldAverageItemTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -0,0 +1,212 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
|
\\/ 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/>.
|
||||||
|
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::functionObjects::fieldAverageItem::active() const
|
||||||
|
{
|
||||||
|
return active_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool& Foam::functionObjects::fieldAverageItem::active()
|
||||||
|
{
|
||||||
|
return active_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::word& Foam::functionObjects::fieldAverageItem::fieldName() const
|
||||||
|
{
|
||||||
|
return fieldName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::functionObjects::fieldAverageItem::mean() const
|
||||||
|
{
|
||||||
|
return mean_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool& Foam::functionObjects::fieldAverageItem::mean()
|
||||||
|
{
|
||||||
|
return mean_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::word&
|
||||||
|
Foam::functionObjects::fieldAverageItem::meanFieldName() const
|
||||||
|
{
|
||||||
|
return meanFieldName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::functionObjects::fieldAverageItem::prime2Mean() const
|
||||||
|
{
|
||||||
|
return prime2Mean_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool& Foam::functionObjects::fieldAverageItem::prime2Mean()
|
||||||
|
{
|
||||||
|
return prime2Mean_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::word& Foam::functionObjects::fieldAverageItem::prime2MeanFieldName() const
|
||||||
|
{
|
||||||
|
return prime2MeanFieldName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::word& Foam::functionObjects::fieldAverageItem::base() const
|
||||||
|
{
|
||||||
|
return baseTypeNames_[base_];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::functionObjects::fieldAverageItem::totalIter() const
|
||||||
|
{
|
||||||
|
return totalIter_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::functionObjects::fieldAverageItem::totalTime() const
|
||||||
|
{
|
||||||
|
return totalTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::functionObjects::fieldAverageItem::window() const
|
||||||
|
{
|
||||||
|
return window_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::word& Foam::functionObjects::fieldAverageItem::windowName() const
|
||||||
|
{
|
||||||
|
return windowName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::FIFOStack<Foam::scalar>&
|
||||||
|
Foam::functionObjects::fieldAverageItem::windowTimes() const
|
||||||
|
{
|
||||||
|
return windowTimes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::FIFOStack<Foam::word>&
|
||||||
|
Foam::functionObjects::fieldAverageItem::windowFieldNames() const
|
||||||
|
{
|
||||||
|
return windowFieldNames_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::functionObjects::fieldAverageItem::dt
|
||||||
|
(
|
||||||
|
const scalar deltaT
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
switch (base_)
|
||||||
|
{
|
||||||
|
case baseType::TIME:
|
||||||
|
{
|
||||||
|
return deltaT;
|
||||||
|
}
|
||||||
|
case baseType::ITER:
|
||||||
|
{
|
||||||
|
return scalar(1);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unhandled enumeration " << baseTypeNames_[base_]
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::functionObjects::fieldAverageItem::Dt() const
|
||||||
|
{
|
||||||
|
switch (base_)
|
||||||
|
{
|
||||||
|
case baseType::TIME:
|
||||||
|
{
|
||||||
|
return totalTime_;
|
||||||
|
}
|
||||||
|
case baseType::ITER:
|
||||||
|
{
|
||||||
|
return scalar(totalIter_);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unhandled enumeration " << baseTypeNames_[base_]
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::word Foam::functionObjects::fieldAverageItem::windowFieldName
|
||||||
|
(
|
||||||
|
const word& prefix
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return prefix + ':' + fieldName_ + ':' + Foam::name(totalIter_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::functionObjects::fieldAverageItem::inWindow(const scalar t) const
|
||||||
|
{
|
||||||
|
switch (base_)
|
||||||
|
{
|
||||||
|
case baseType::ITER:
|
||||||
|
{
|
||||||
|
return round(t) <= round(window_) + 1;
|
||||||
|
}
|
||||||
|
case baseType::TIME:
|
||||||
|
{
|
||||||
|
return t <= window_;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unhandled baseType enumeration "
|
||||||
|
<< baseTypeNames_[base_]
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -37,8 +37,15 @@ Foam::functionObjects::fieldAverageItem::fieldAverageItem(Istream& is)
|
|||||||
meanFieldName_("unknown"),
|
meanFieldName_("unknown"),
|
||||||
prime2Mean_(0),
|
prime2Mean_(0),
|
||||||
prime2MeanFieldName_("unknown"),
|
prime2MeanFieldName_("unknown"),
|
||||||
base_(ITER),
|
base_(baseType::ITER),
|
||||||
window_(-1.0)
|
totalIter_(0),
|
||||||
|
totalTime_(-1),
|
||||||
|
window_(-1.0),
|
||||||
|
windowName_(""),
|
||||||
|
windowType_(windowType::NONE),
|
||||||
|
|
||||||
|
windowTimes_(),
|
||||||
|
windowFieldNames_()
|
||||||
{
|
{
|
||||||
is.check(FUNCTION_NAME);
|
is.check(FUNCTION_NAME);
|
||||||
|
|
||||||
@ -49,11 +56,21 @@ Foam::functionObjects::fieldAverageItem::fieldAverageItem(Istream& is)
|
|||||||
prime2Mean_ = readBool(entry.lookup("prime2Mean"));
|
prime2Mean_ = readBool(entry.lookup("prime2Mean"));
|
||||||
base_ = baseTypeNames_.lookup("base", entry);
|
base_ = baseTypeNames_.lookup("base", entry);
|
||||||
window_ = entry.lookupOrDefault<scalar>("window", -1.0);
|
window_ = entry.lookupOrDefault<scalar>("window", -1.0);
|
||||||
windowName_ = entry.lookupOrDefault<word>("windowName", "");
|
|
||||||
|
if (window_ > 0)
|
||||||
|
{
|
||||||
|
windowName_ = entry.lookupOrDefault<word>("windowName", "");
|
||||||
|
windowType_ = windowTypeNames_.lookup("windowType", entry);
|
||||||
|
|
||||||
|
if (windowType_ == windowType::NONE)
|
||||||
|
{
|
||||||
|
window_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
meanFieldName_ = fieldName_ + EXT_MEAN;
|
meanFieldName_ = fieldName_ + EXT_MEAN;
|
||||||
prime2MeanFieldName_ = fieldName_ + EXT_PRIME2MEAN;
|
prime2MeanFieldName_ = fieldName_ + EXT_PRIME2MEAN;
|
||||||
if ((window_ > 0) && (windowName_ != ""))
|
if ((window_ > 0) && (!windowName_.empty()))
|
||||||
{
|
{
|
||||||
meanFieldName_ = meanFieldName_ + "_" + windowName_;
|
meanFieldName_ = meanFieldName_ + "_" + windowName_;
|
||||||
prime2MeanFieldName_ = prime2MeanFieldName_ + "_" + windowName_;
|
prime2MeanFieldName_ = prime2MeanFieldName_ + "_" + windowName_;
|
||||||
@ -79,13 +96,24 @@ Foam::Istream& Foam::functionObjects::operator>>
|
|||||||
faItem.prime2Mean_ = readBool(entry.lookup("prime2Mean"));
|
faItem.prime2Mean_ = readBool(entry.lookup("prime2Mean"));
|
||||||
faItem.base_ = faItem.baseTypeNames_.lookup("base", entry);
|
faItem.base_ = faItem.baseTypeNames_.lookup("base", entry);
|
||||||
faItem.window_ = entry.lookupOrDefault<scalar>("window", -1.0);
|
faItem.window_ = entry.lookupOrDefault<scalar>("window", -1.0);
|
||||||
faItem.windowName_ = entry.lookupOrDefault<word>("windowName", "");
|
|
||||||
|
if (faItem.window_ > 0)
|
||||||
|
{
|
||||||
|
faItem.windowName_ = entry.lookupOrDefault<word>("windowName", "");
|
||||||
|
faItem.windowType_ =
|
||||||
|
faItem.windowTypeNames_.lookup("windowType", entry);
|
||||||
|
|
||||||
|
if (faItem.windowType_ == fieldAverageItem::windowType::NONE)
|
||||||
|
{
|
||||||
|
faItem.window_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
faItem.meanFieldName_ = faItem.fieldName_ + fieldAverageItem::EXT_MEAN;
|
faItem.meanFieldName_ = faItem.fieldName_ + fieldAverageItem::EXT_MEAN;
|
||||||
faItem.prime2MeanFieldName_ =
|
faItem.prime2MeanFieldName_ =
|
||||||
faItem.fieldName_ + fieldAverageItem::EXT_PRIME2MEAN;
|
faItem.fieldName_ + fieldAverageItem::EXT_PRIME2MEAN;
|
||||||
|
|
||||||
if ((faItem.window_ > 0) && (faItem.windowName_ != ""))
|
if ((faItem.window_ > 0) && (!faItem.windowName_.empty()))
|
||||||
{
|
{
|
||||||
faItem.meanFieldName_ =
|
faItem.meanFieldName_ =
|
||||||
faItem.meanFieldName_ + "_" + faItem.windowName_;
|
faItem.meanFieldName_ + "_" + faItem.windowName_;
|
||||||
@ -105,7 +133,8 @@ Foam::Ostream& Foam::functionObjects::operator<<
|
|||||||
{
|
{
|
||||||
os.check(FUNCTION_NAME);
|
os.check(FUNCTION_NAME);
|
||||||
|
|
||||||
os << faItem.fieldName_ << nl << token::BEGIN_BLOCK << nl;
|
os.beginBlock(faItem.fieldName_);
|
||||||
|
|
||||||
os.writeKeyword("mean") << faItem.mean_ << token::END_STATEMENT << nl;
|
os.writeKeyword("mean") << faItem.mean_ << token::END_STATEMENT << nl;
|
||||||
os.writeKeyword("prime2Mean") << faItem.prime2Mean_
|
os.writeKeyword("prime2Mean") << faItem.prime2Mean_
|
||||||
<< token::END_STATEMENT << nl;
|
<< token::END_STATEMENT << nl;
|
||||||
@ -114,19 +143,24 @@ Foam::Ostream& Foam::functionObjects::operator<<
|
|||||||
|
|
||||||
if (faItem.window_ > 0)
|
if (faItem.window_ > 0)
|
||||||
{
|
{
|
||||||
os.writeKeyword("window") << faItem.window_
|
os.writeEntry("window", faItem.window_);
|
||||||
<< token::END_STATEMENT << nl;
|
|
||||||
|
|
||||||
if (faItem.windowName_ != "")
|
if (!faItem.windowName_.empty())
|
||||||
{
|
{
|
||||||
os.writeKeyword("windowName") << faItem.windowName_
|
os.writeEntry("windowName", faItem.windowName_);
|
||||||
<< token::END_STATEMENT << nl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
os.writeEntry
|
||||||
|
(
|
||||||
|
"windowType",
|
||||||
|
faItem.windowTypeNames_[faItem.windowType_]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
os << token::END_BLOCK << nl;
|
os.endBlock() << flush;
|
||||||
|
|
||||||
os.check(FUNCTION_NAME);
|
os.check(FUNCTION_NAME);
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,291 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
|
\\/ 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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "objectRegistry.H"
|
||||||
|
#include "Time.H"
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
bool Foam::functionObjects::fieldAverageItem::calculateMeanField
|
||||||
|
(
|
||||||
|
const objectRegistry& obr
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (!mean_)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type* baseFieldPtr = obr.lookupObjectPtr<Type>(fieldName_);
|
||||||
|
|
||||||
|
if (!baseFieldPtr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type& baseField = *baseFieldPtr;
|
||||||
|
Type& meanField = obr.lookupObjectRef<Type>(meanFieldName_);
|
||||||
|
|
||||||
|
switch (windowType_)
|
||||||
|
{
|
||||||
|
case windowType::NONE:
|
||||||
|
{
|
||||||
|
scalar dt = this->dt(obr.time().deltaTValue());
|
||||||
|
scalar Dt = this->Dt();
|
||||||
|
scalar beta = dt/Dt;
|
||||||
|
|
||||||
|
meanField = (1 - beta)*meanField + beta*baseField;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case windowType::APPROXIMATE:
|
||||||
|
{
|
||||||
|
scalar dt = this->dt(obr.time().deltaTValue());
|
||||||
|
scalar Dt = this->Dt();
|
||||||
|
scalar beta = dt/Dt;
|
||||||
|
|
||||||
|
if (Dt - dt >= window_)
|
||||||
|
{
|
||||||
|
beta = dt/window_;
|
||||||
|
}
|
||||||
|
|
||||||
|
meanField = (1 - beta)*meanField + beta*baseField;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case windowType::EXACT:
|
||||||
|
{
|
||||||
|
switch (base_)
|
||||||
|
{
|
||||||
|
case baseType::ITER:
|
||||||
|
{
|
||||||
|
// Uniform time step - can use simplified algorithm
|
||||||
|
// Note: stores an additional old time field, but only
|
||||||
|
// needs to do 1 field lookup
|
||||||
|
|
||||||
|
label n = windowTimes_.size();
|
||||||
|
const Type& lastField =
|
||||||
|
obr.lookupObject<Type>(windowFieldNames_.first());
|
||||||
|
|
||||||
|
if (n <= round(window_))
|
||||||
|
{
|
||||||
|
scalar beta = 1.0/scalar(n);
|
||||||
|
meanField = (1 - beta)*meanField + beta*baseField;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meanField += (baseField - lastField)/scalar(n - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case baseType::TIME:
|
||||||
|
{
|
||||||
|
// Assuming non-uniform time step
|
||||||
|
// Note: looks up all window fields from the registry
|
||||||
|
|
||||||
|
meanField = 0*baseField;
|
||||||
|
FIFOStack<scalar>::const_iterator timeIter =
|
||||||
|
windowTimes_.begin();
|
||||||
|
FIFOStack<word>::const_iterator nameIter =
|
||||||
|
windowFieldNames_.begin();
|
||||||
|
|
||||||
|
const Type* wOld = nullptr;
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
;
|
||||||
|
timeIter != windowTimes_.end();
|
||||||
|
++timeIter, ++nameIter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const word& fieldName = nameIter();
|
||||||
|
const scalar dt = timeIter();
|
||||||
|
const Type* w = obr.lookupObjectPtr<Type>(fieldName);
|
||||||
|
|
||||||
|
meanField += dt*(*w);
|
||||||
|
|
||||||
|
if (wOld)
|
||||||
|
{
|
||||||
|
meanField -= dt*(*wOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
wOld = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
meanField /= windowTimes_.first();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unhandled baseType enumeration "
|
||||||
|
<< baseTypeNames_[base_]
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unhandled windowType enumeration "
|
||||||
|
<< windowTypeNames_[windowType_]
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type1, class Type2>
|
||||||
|
bool Foam::functionObjects::fieldAverageItem::calculatePrime2MeanField
|
||||||
|
(
|
||||||
|
const objectRegistry& obr
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (!prime2Mean_)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type1* baseFieldPtr = obr.lookupObjectPtr<Type1>(fieldName_);
|
||||||
|
|
||||||
|
if (!baseFieldPtr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type1& baseField = *baseFieldPtr;
|
||||||
|
const Type1& meanField = obr.lookupObject<Type1>(meanFieldName_);
|
||||||
|
|
||||||
|
Type2& prime2MeanField =
|
||||||
|
obr.lookupObjectRef<Type2>(prime2MeanFieldName_);
|
||||||
|
|
||||||
|
switch (windowType_)
|
||||||
|
{
|
||||||
|
case windowType::NONE:
|
||||||
|
{
|
||||||
|
scalar dt = this->dt(obr.time().deltaTValue());
|
||||||
|
scalar Dt = this->Dt();
|
||||||
|
scalar beta = dt/Dt;
|
||||||
|
|
||||||
|
prime2MeanField =
|
||||||
|
(1 - beta)*prime2MeanField
|
||||||
|
+ beta*sqr(baseField)
|
||||||
|
- sqr(meanField);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case windowType::APPROXIMATE:
|
||||||
|
{
|
||||||
|
scalar dt = this->dt(obr.time().deltaTValue());
|
||||||
|
scalar Dt = this->Dt();
|
||||||
|
scalar beta = dt/Dt;
|
||||||
|
|
||||||
|
if (Dt - dt >= window_)
|
||||||
|
{
|
||||||
|
beta = dt/window_;
|
||||||
|
}
|
||||||
|
|
||||||
|
prime2MeanField =
|
||||||
|
(1 - beta)*prime2MeanField
|
||||||
|
+ beta*sqr(baseField)
|
||||||
|
- sqr(meanField);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case windowType::EXACT:
|
||||||
|
{
|
||||||
|
// Not storing old time mean fields - treat all as TIME (integrated)
|
||||||
|
prime2MeanField = 0*prime2MeanField;
|
||||||
|
FIFOStack<scalar>::const_iterator timeIter =
|
||||||
|
windowTimes_.begin();
|
||||||
|
FIFOStack<word>::const_iterator nameIter =
|
||||||
|
windowFieldNames_.begin();
|
||||||
|
|
||||||
|
switch (base_)
|
||||||
|
{
|
||||||
|
case baseType::ITER:
|
||||||
|
{
|
||||||
|
// ITER method stores an additional entry compared to TIME
|
||||||
|
++timeIter;
|
||||||
|
++nameIter;
|
||||||
|
|
||||||
|
if (timeIter == windowTimes_.end()) return false;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
scalar windowLength = timeIter();
|
||||||
|
|
||||||
|
const Type1* wOld = nullptr;
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
;
|
||||||
|
timeIter != windowTimes_.end();
|
||||||
|
++timeIter, ++nameIter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const word& fieldName = nameIter();
|
||||||
|
const scalar dt = timeIter();
|
||||||
|
const Type1* w = obr.lookupObjectPtr<Type1>(fieldName);
|
||||||
|
|
||||||
|
prime2MeanField += dt*(sqr((*w) - meanField));
|
||||||
|
|
||||||
|
if (wOld)
|
||||||
|
{
|
||||||
|
prime2MeanField -= dt*(sqr((*wOld) - meanField));
|
||||||
|
}
|
||||||
|
|
||||||
|
wOld = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
prime2MeanField /= windowLength;
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unhandled windowType enumeration "
|
||||||
|
<< windowTypeNames_[windowType_]
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -32,13 +32,22 @@ License
|
|||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::functionObjects::fieldAverage::addMeanFieldType(const label fieldi)
|
void Foam::functionObjects::fieldAverage::addMeanFieldType
|
||||||
|
(
|
||||||
|
fieldAverageItem& item
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// Field has been found, so set active flag to true
|
const word& fieldName = item.fieldName();
|
||||||
faItems_[fieldi].active() = true;
|
|
||||||
|
|
||||||
const word& fieldName = faItems_[fieldi].fieldName();
|
if (!foundObject<Type>(fieldName))
|
||||||
const word& meanFieldName = faItems_[fieldi].meanFieldName();
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field has been found, so set active flag to true
|
||||||
|
item.active() = true;
|
||||||
|
|
||||||
|
const word& meanFieldName = item.meanFieldName();
|
||||||
|
|
||||||
Log << " Reading/initialising field " << meanFieldName << endl;
|
Log << " Reading/initialising field " << meanFieldName << endl;
|
||||||
|
|
||||||
@ -50,7 +59,7 @@ void Foam::functionObjects::fieldAverage::addMeanFieldType(const label fieldi)
|
|||||||
<< " since an object with that name already exists."
|
<< " since an object with that name already exists."
|
||||||
<< " Disabling averaging for field." << endl;
|
<< " Disabling averaging for field." << endl;
|
||||||
|
|
||||||
faItems_[fieldi].mean() = false;
|
item.mean() = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -66,9 +75,9 @@ void Foam::functionObjects::fieldAverage::addMeanFieldType(const label fieldi)
|
|||||||
meanFieldName,
|
meanFieldName,
|
||||||
obr().time().timeName(obr().time().startTime().value()),
|
obr().time().timeName(obr().time().startTime().value()),
|
||||||
obr(),
|
obr(),
|
||||||
restartOnOutput_
|
restartOnOutput_ ?
|
||||||
? IOobject::NO_READ
|
IOobject::NO_READ
|
||||||
: IOobject::READ_IF_PRESENT,
|
: IOobject::READ_IF_PRESENT,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
1*baseField
|
1*baseField
|
||||||
@ -79,41 +88,102 @@ void Foam::functionObjects::fieldAverage::addMeanFieldType(const label fieldi)
|
|||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::functionObjects::fieldAverage::addMeanField(const label fieldi)
|
void Foam::functionObjects::fieldAverage::addMeanField
|
||||||
|
(
|
||||||
|
fieldAverageItem& item
|
||||||
|
)
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
||||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
||||||
typedef DimensionedField<Type, surfGeoMesh> SurfFieldType;
|
typedef DimensionedField<Type, surfGeoMesh> SurfFieldType;
|
||||||
|
|
||||||
if (faItems_[fieldi].mean())
|
if (item.mean())
|
||||||
{
|
{
|
||||||
const word& fieldName = faItems_[fieldi].fieldName();
|
addMeanFieldType<VolFieldType>(item);
|
||||||
|
addMeanFieldType<SurfaceFieldType>(item);
|
||||||
|
addMeanFieldType<SurfFieldType>(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (foundObject<VolFieldType>(fieldName))
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::functionObjects::fieldAverage::restoreWindowFieldsType
|
||||||
|
(
|
||||||
|
const fieldAverageItem& item
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (restartOnOutput_)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const word& fieldName = item.fieldName();
|
||||||
|
|
||||||
|
const Type* fieldPtr = lookupObjectPtr<Type>(fieldName);
|
||||||
|
|
||||||
|
if (!fieldPtr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FIFOStack<word>& fieldNames = item.windowFieldNames();
|
||||||
|
|
||||||
|
forAllConstIters(fieldNames, fieldIter)
|
||||||
|
{
|
||||||
|
const word& name = fieldIter();
|
||||||
|
|
||||||
|
IOobject io
|
||||||
|
(
|
||||||
|
name,
|
||||||
|
obr().time().timeName(obr().time().startTime().value()),
|
||||||
|
obr(),
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (io.typeHeaderOk<dictionary>(false))
|
||||||
{
|
{
|
||||||
addMeanFieldType<VolFieldType>(fieldi);
|
DebugInfo << "Read and store: " << name << endl;
|
||||||
}
|
obr().store(new Type(io, fieldPtr->mesh()));
|
||||||
else if (foundObject<SurfaceFieldType>(fieldName))
|
|
||||||
{
|
|
||||||
addMeanFieldType<SurfaceFieldType>(fieldi);
|
|
||||||
}
|
|
||||||
else if (foundObject<SurfFieldType>(fieldName))
|
|
||||||
{
|
|
||||||
addMeanFieldType<SurfFieldType>(fieldi);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::functionObjects::fieldAverage::restoreWindowFields
|
||||||
|
(
|
||||||
|
const fieldAverageItem& item
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
||||||
|
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
||||||
|
typedef DimensionedField<Type, surfGeoMesh> SurfFieldType;
|
||||||
|
|
||||||
|
if (item.window() > 0)
|
||||||
|
{
|
||||||
|
restoreWindowFieldsType<VolFieldType>(item);
|
||||||
|
restoreWindowFieldsType<SurfaceFieldType>(item);
|
||||||
|
restoreWindowFieldsType<SurfFieldType>(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type1, class Type2>
|
template<class Type1, class Type2>
|
||||||
void Foam::functionObjects::fieldAverage::addPrime2MeanFieldType
|
void Foam::functionObjects::fieldAverage::addPrime2MeanFieldType
|
||||||
(
|
(
|
||||||
const label fieldi
|
fieldAverageItem& item
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const word& fieldName = faItems_[fieldi].fieldName();
|
const word& fieldName = item.fieldName();
|
||||||
const word& meanFieldName = faItems_[fieldi].meanFieldName();
|
|
||||||
const word& prime2MeanFieldName = faItems_[fieldi].prime2MeanFieldName();
|
if (!foundObject<Type1>(fieldName))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const word& meanFieldName = item.meanFieldName();
|
||||||
|
const word& prime2MeanFieldName = item.prime2MeanFieldName();
|
||||||
|
|
||||||
Log << " Reading/initialising field " << prime2MeanFieldName << nl;
|
Log << " Reading/initialising field " << prime2MeanFieldName << nl;
|
||||||
|
|
||||||
@ -125,7 +195,7 @@ void Foam::functionObjects::fieldAverage::addPrime2MeanFieldType
|
|||||||
<< " since an object with that name already exists."
|
<< " since an object with that name already exists."
|
||||||
<< " Disabling averaging for field." << endl;
|
<< " Disabling averaging for field." << endl;
|
||||||
|
|
||||||
faItems_[fieldi].prime2Mean() = false;
|
item.prime2Mean() = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -142,9 +212,9 @@ void Foam::functionObjects::fieldAverage::addPrime2MeanFieldType
|
|||||||
prime2MeanFieldName,
|
prime2MeanFieldName,
|
||||||
obr().time().timeName(obr().time().startTime().value()),
|
obr().time().timeName(obr().time().startTime().value()),
|
||||||
obr(),
|
obr(),
|
||||||
restartOnOutput_
|
restartOnOutput_?
|
||||||
? IOobject::NO_READ
|
IOobject::NO_READ
|
||||||
: IOobject::READ_IF_PRESENT,
|
: IOobject::READ_IF_PRESENT,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
sqr(baseField) - sqr(meanField)
|
sqr(baseField) - sqr(meanField)
|
||||||
@ -155,7 +225,10 @@ void Foam::functionObjects::fieldAverage::addPrime2MeanFieldType
|
|||||||
|
|
||||||
|
|
||||||
template<class Type1, class Type2>
|
template<class Type1, class Type2>
|
||||||
void Foam::functionObjects::fieldAverage::addPrime2MeanField(const label fieldi)
|
void Foam::functionObjects::fieldAverage::addPrime2MeanField
|
||||||
|
(
|
||||||
|
fieldAverageItem& item
|
||||||
|
)
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type1, fvPatchField, volMesh> VolFieldType1;
|
typedef GeometricField<Type1, fvPatchField, volMesh> VolFieldType1;
|
||||||
typedef GeometricField<Type1, fvsPatchField, surfaceMesh> SurfaceFieldType1;
|
typedef GeometricField<Type1, fvsPatchField, surfaceMesh> SurfaceFieldType1;
|
||||||
@ -165,79 +238,80 @@ void Foam::functionObjects::fieldAverage::addPrime2MeanField(const label fieldi)
|
|||||||
typedef GeometricField<Type2, fvsPatchField, surfaceMesh> SurfaceFieldType2;
|
typedef GeometricField<Type2, fvsPatchField, surfaceMesh> SurfaceFieldType2;
|
||||||
typedef DimensionedField<Type2, surfGeoMesh> SurfFieldType2;
|
typedef DimensionedField<Type2, surfGeoMesh> SurfFieldType2;
|
||||||
|
|
||||||
if (faItems_[fieldi].prime2Mean())
|
if (item.prime2Mean())
|
||||||
{
|
{
|
||||||
const word& fieldName = faItems_[fieldi].fieldName();
|
if (!item.mean())
|
||||||
|
|
||||||
if (!faItems_[fieldi].mean())
|
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "To calculate the prime-squared average, the "
|
<< "To calculate the prime-squared average, the "
|
||||||
<< "mean average must also be selected for field "
|
<< "mean average must also be selected for field "
|
||||||
<< fieldName << nl << exit(FatalError);
|
<< item.fieldName() << nl << exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundObject<VolFieldType1>(fieldName))
|
addPrime2MeanFieldType<VolFieldType1, VolFieldType2>(item);
|
||||||
{
|
addPrime2MeanFieldType<SurfaceFieldType1, SurfaceFieldType2>(item);
|
||||||
addPrime2MeanFieldType<VolFieldType1, VolFieldType2>(fieldi);
|
addPrime2MeanFieldType<SurfFieldType1, SurfFieldType2>(item);
|
||||||
}
|
|
||||||
else if (foundObject<SurfaceFieldType1>(fieldName))
|
|
||||||
{
|
|
||||||
addPrime2MeanFieldType<SurfaceFieldType1, SurfaceFieldType2>
|
|
||||||
(
|
|
||||||
fieldi
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (foundObject<SurfFieldType1>(fieldName))
|
|
||||||
{
|
|
||||||
addPrime2MeanFieldType<SurfFieldType1, SurfFieldType2>
|
|
||||||
(
|
|
||||||
fieldi
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::functionObjects::fieldAverage::calculateMeanFieldType
|
void Foam::functionObjects::fieldAverage::storeWindowFieldType
|
||||||
(
|
(
|
||||||
const label fieldi
|
fieldAverageItem& item
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
const word& fieldName = faItems_[fieldi].fieldName();
|
const word& fieldName = item.fieldName();
|
||||||
|
|
||||||
if (foundObject<Type>(fieldName))
|
if (!foundObject<Type>(fieldName))
|
||||||
{
|
{
|
||||||
const Type& baseField = lookupObject<Type>(fieldName);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Type& meanField = const_cast<Type&>
|
const Type& baseField = lookupObject<Type>(fieldName);
|
||||||
|
|
||||||
|
const word windowFieldName = item.windowFieldName(this->name());
|
||||||
|
|
||||||
|
// Store on registry
|
||||||
|
obr().store
|
||||||
|
(
|
||||||
|
new Type
|
||||||
(
|
(
|
||||||
lookupObject<Type>(faItems_[fieldi].meanFieldName())
|
IOobject
|
||||||
);
|
(
|
||||||
|
windowFieldName,
|
||||||
|
obr().time().timeName(obr().time().startTime().value()),
|
||||||
|
obr(),
|
||||||
|
restartOnOutput_ ?
|
||||||
|
IOobject::NO_READ
|
||||||
|
: IOobject::READ_IF_PRESENT,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
1*baseField
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
scalar dt = obr().time().deltaTValue();
|
DebugInfo << "Create and store: " << windowFieldName << endl;
|
||||||
scalar Dt = totalTime_[fieldi];
|
|
||||||
|
|
||||||
if (faItems_[fieldi].iterBase())
|
item.addToWindow(windowFieldName, obr().time().deltaTValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::functionObjects::fieldAverage::storeWindowFields()
|
||||||
|
{
|
||||||
|
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
||||||
|
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
||||||
|
typedef DimensionedField<Type, surfGeoMesh> SurfFieldType;
|
||||||
|
|
||||||
|
for (fieldAverageItem& item : faItems_)
|
||||||
|
{
|
||||||
|
if (item.window() > 0)
|
||||||
{
|
{
|
||||||
dt = 1;
|
storeWindowFieldType<VolFieldType>(item);
|
||||||
Dt = scalar(totalIter_[fieldi]);
|
storeWindowFieldType<SurfaceFieldType>(item);
|
||||||
|
storeWindowFieldType<SurfFieldType>(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
scalar beta = dt/Dt;
|
|
||||||
|
|
||||||
if (faItems_[fieldi].window() > 0)
|
|
||||||
{
|
|
||||||
const scalar w = faItems_[fieldi].window();
|
|
||||||
|
|
||||||
if (Dt - dt >= w)
|
|
||||||
{
|
|
||||||
beta = dt/w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
meanField = (1 - beta)*meanField + beta*baseField;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,60 +323,11 @@ void Foam::functionObjects::fieldAverage::calculateMeanFields() const
|
|||||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
||||||
typedef DimensionedField<Type, surfGeoMesh> SurfFieldType;
|
typedef DimensionedField<Type, surfGeoMesh> SurfFieldType;
|
||||||
|
|
||||||
forAll(faItems_, i)
|
for (const fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
if (faItems_[i].mean())
|
item.calculateMeanField<VolFieldType>(obr());
|
||||||
{
|
item.calculateMeanField<SurfaceFieldType>(obr());
|
||||||
calculateMeanFieldType<VolFieldType>(i);
|
item.calculateMeanField<SurfFieldType>(obr());
|
||||||
calculateMeanFieldType<SurfaceFieldType>(i);
|
|
||||||
calculateMeanFieldType<SurfFieldType>(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type1, class Type2>
|
|
||||||
void Foam::functionObjects::fieldAverage::calculatePrime2MeanFieldType
|
|
||||||
(
|
|
||||||
const label fieldi
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const word& fieldName = faItems_[fieldi].fieldName();
|
|
||||||
|
|
||||||
if (foundObject<Type1>(fieldName))
|
|
||||||
{
|
|
||||||
const Type1& baseField = lookupObject<Type1>(fieldName);
|
|
||||||
const Type1& meanField =
|
|
||||||
lookupObject<Type1>(faItems_[fieldi].meanFieldName());
|
|
||||||
|
|
||||||
Type2& prime2MeanField =
|
|
||||||
lookupObjectRef<Type2>(faItems_[fieldi].prime2MeanFieldName());
|
|
||||||
|
|
||||||
scalar dt = obr().time().deltaTValue();
|
|
||||||
scalar Dt = totalTime_[fieldi];
|
|
||||||
|
|
||||||
if (faItems_[fieldi].iterBase())
|
|
||||||
{
|
|
||||||
dt = 1;
|
|
||||||
Dt = scalar(totalIter_[fieldi]);
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar beta = dt/Dt;
|
|
||||||
|
|
||||||
if (faItems_[fieldi].window() > 0)
|
|
||||||
{
|
|
||||||
const scalar w = faItems_[fieldi].window();
|
|
||||||
|
|
||||||
if (Dt - dt >= w)
|
|
||||||
{
|
|
||||||
beta = dt/w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prime2MeanField =
|
|
||||||
(1 - beta)*prime2MeanField
|
|
||||||
+ beta*sqr(baseField)
|
|
||||||
- sqr(meanField);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,21 +343,14 @@ void Foam::functionObjects::fieldAverage::calculatePrime2MeanFields() const
|
|||||||
typedef GeometricField<Type2, fvsPatchField, surfaceMesh> SurfaceFieldType2;
|
typedef GeometricField<Type2, fvsPatchField, surfaceMesh> SurfaceFieldType2;
|
||||||
typedef DimensionedField<Type2, surfGeoMesh> SurfFieldType2;
|
typedef DimensionedField<Type2, surfGeoMesh> SurfFieldType2;
|
||||||
|
|
||||||
forAll(faItems_, i)
|
for (const fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
if (faItems_[i].prime2Mean())
|
item.calculatePrime2MeanField<VolFieldType1, VolFieldType2>(obr());
|
||||||
{
|
item.calculatePrime2MeanField<SurfaceFieldType1, SurfaceFieldType2>
|
||||||
calculatePrime2MeanFieldType<VolFieldType1, VolFieldType2>(i);
|
(
|
||||||
calculatePrime2MeanFieldType<SurfaceFieldType1, SurfaceFieldType2>
|
obr()
|
||||||
(
|
);
|
||||||
i
|
item.calculatePrime2MeanField<SurfFieldType1, SurfFieldType2>(obr());
|
||||||
);
|
|
||||||
|
|
||||||
calculatePrime2MeanFieldType<SurfFieldType1, SurfFieldType2>
|
|
||||||
(
|
|
||||||
i
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,21 +358,21 @@ void Foam::functionObjects::fieldAverage::calculatePrime2MeanFields() const
|
|||||||
template<class Type1, class Type2>
|
template<class Type1, class Type2>
|
||||||
void Foam::functionObjects::fieldAverage::addMeanSqrToPrime2MeanType
|
void Foam::functionObjects::fieldAverage::addMeanSqrToPrime2MeanType
|
||||||
(
|
(
|
||||||
const label fieldi
|
const fieldAverageItem& item
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const word& fieldName = faItems_[fieldi].fieldName();
|
const word& fieldName = item.fieldName();
|
||||||
|
|
||||||
if (foundObject<Type1>(fieldName))
|
if (!foundObject<Type1>(fieldName))
|
||||||
{
|
{
|
||||||
const Type1& meanField =
|
return;
|
||||||
lookupObject<Type1>(faItems_[fieldi].meanFieldName());
|
|
||||||
|
|
||||||
Type2& prime2MeanField =
|
|
||||||
lookupObjectRef<Type2>(faItems_[fieldi].prime2MeanFieldName());
|
|
||||||
|
|
||||||
prime2MeanField += sqr(meanField);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Type1& meanField = lookupObject<Type1>(item.meanFieldName());
|
||||||
|
|
||||||
|
Type2& prime2MeanField = lookupObjectRef<Type2>(item.prime2MeanFieldName());
|
||||||
|
|
||||||
|
prime2MeanField += sqr(meanField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -369,13 +387,16 @@ void Foam::functionObjects::fieldAverage::addMeanSqrToPrime2Mean() const
|
|||||||
typedef GeometricField<Type2, fvsPatchField, surfaceMesh> SurfaceFieldType2;
|
typedef GeometricField<Type2, fvsPatchField, surfaceMesh> SurfaceFieldType2;
|
||||||
typedef DimensionedField<Type2, surfGeoMesh> SurfFieldType2;
|
typedef DimensionedField<Type2, surfGeoMesh> SurfFieldType2;
|
||||||
|
|
||||||
forAll(faItems_, i)
|
for (const fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
if (faItems_[i].prime2Mean())
|
if (item.prime2Mean())
|
||||||
{
|
{
|
||||||
addMeanSqrToPrime2MeanType<VolFieldType1, VolFieldType2>(i);
|
addMeanSqrToPrime2MeanType<VolFieldType1, VolFieldType2>(item);
|
||||||
addMeanSqrToPrime2MeanType<SurfaceFieldType1, SurfaceFieldType2>(i);
|
addMeanSqrToPrime2MeanType<SurfaceFieldType1, SurfaceFieldType2>
|
||||||
addMeanSqrToPrime2MeanType<SurfFieldType1, SurfFieldType2>(i);
|
(
|
||||||
|
item
|
||||||
|
);
|
||||||
|
addMeanSqrToPrime2MeanType<SurfFieldType1, SurfFieldType2>(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -402,22 +423,33 @@ void Foam::functionObjects::fieldAverage::writeFields() const
|
|||||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
||||||
typedef DimensionedField<Type, surfGeoMesh> SurfFieldType;
|
typedef DimensionedField<Type, surfGeoMesh> SurfFieldType;
|
||||||
|
|
||||||
forAll(faItems_, i)
|
for (const fieldAverageItem& item : faItems_)
|
||||||
{
|
{
|
||||||
if (faItems_[i].mean())
|
if (item.mean())
|
||||||
{
|
{
|
||||||
const word& fieldName = faItems_[i].meanFieldName();
|
const word& fieldName = item.meanFieldName();
|
||||||
writeFieldType<VolFieldType>(fieldName);
|
writeFieldType<VolFieldType>(fieldName);
|
||||||
writeFieldType<SurfaceFieldType>(fieldName);
|
writeFieldType<SurfaceFieldType>(fieldName);
|
||||||
writeFieldType<SurfFieldType>(fieldName);
|
writeFieldType<SurfFieldType>(fieldName);
|
||||||
}
|
}
|
||||||
if (faItems_[i].prime2Mean())
|
if (item.prime2Mean())
|
||||||
{
|
{
|
||||||
const word& fieldName = faItems_[i].prime2MeanFieldName();
|
const word& fieldName = item.prime2MeanFieldName();
|
||||||
writeFieldType<VolFieldType>(fieldName);
|
writeFieldType<VolFieldType>(fieldName);
|
||||||
writeFieldType<SurfaceFieldType>(fieldName);
|
writeFieldType<SurfaceFieldType>(fieldName);
|
||||||
writeFieldType<SurfFieldType>(fieldName);
|
writeFieldType<SurfFieldType>(fieldName);
|
||||||
}
|
}
|
||||||
|
if (item.window() > 0)
|
||||||
|
{
|
||||||
|
FIFOStack<word> fieldNames = item.windowFieldNames();
|
||||||
|
forAllConstIters(fieldNames, fieldNameIter)
|
||||||
|
{
|
||||||
|
const word& fieldName = fieldNameIter();
|
||||||
|
writeFieldType<VolFieldType>(fieldName);
|
||||||
|
writeFieldType<SurfaceFieldType>(fieldName);
|
||||||
|
writeFieldType<SurfFieldType>(fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user