From 3e8b97fef603d3ab1469097f8216cc58678d0d0e Mon Sep 17 00:00:00 2001 From: Will Bainbridge Date: Wed, 30 Nov 2022 12:31:33 +0000 Subject: [PATCH] functionObjects: fieldAverage: Corrected initialisation behaviour The fieldAverage can now average fields that do not exist at construction time, and it also supports restart on cases in which the mesh topology is changing. --- .../fields/volFields/volFieldsFwd.H | 3 + .../field/fieldAverage/fieldAverage.C | 343 ++++++++++------ .../field/fieldAverage/fieldAverage.H | 60 +-- .../fieldAverageItem/fieldAverageItem.H | 8 +- .../fieldAverage/fieldAverageTemplates.C | 375 ++++++++++-------- 5 files changed, 469 insertions(+), 320 deletions(-) diff --git a/src/finiteVolume/fields/volFields/volFieldsFwd.H b/src/finiteVolume/fields/volFields/volFieldsFwd.H index 664f4a1eeb..51a57fb3f2 100644 --- a/src/finiteVolume/fields/volFields/volFieldsFwd.H +++ b/src/finiteVolume/fields/volFields/volFieldsFwd.H @@ -54,6 +54,9 @@ class GeometricField; template using VolField = GeometricField; +template +using VolInternalField = typename VolField::Internal; + typedef GeometricField volLabelField; typedef GeometricField volScalarField; typedef GeometricField volVectorField; diff --git a/src/functionObjects/field/fieldAverage/fieldAverage.C b/src/functionObjects/field/fieldAverage/fieldAverage.C index b7d77c9d92..2e49b21a46 100644 --- a/src/functionObjects/field/fieldAverage/fieldAverage.C +++ b/src/functionObjects/field/fieldAverage/fieldAverage.C @@ -56,8 +56,43 @@ const Foam::NamedEnum // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -void Foam::functionObjects::fieldAverage::resetFields() +void Foam::functionObjects::fieldAverage::initialise() { + // Initialise any unset times + forAll(totalTime_, fieldi) + { + if (totalTime_[fieldi] < 0) + { + totalTime_[fieldi] = obr_.time().deltaTValue(); + } + } + + // Initialise mean fields + forAll(faItems_, fieldi) + { + initialiseMeanField(fieldi); + initialiseMeanField(fieldi); + initialiseMeanField(fieldi); + initialiseMeanField(fieldi); + initialiseMeanField(fieldi); + } + forAll(faItems_, fieldi) + { + initialisePrime2MeanField(fieldi); + initialisePrime2MeanField(fieldi); + } +} + + +void Foam::functionObjects::fieldAverage::restart() +{ + Log << " Restarting averaging at time " << obr_.time().name() << nl; + + // Clear the times + totalIter_ = 1; + totalTime_ = -1; + + // Clear mean fields forAll(faItems_, i) { if (faItems_[i].mean()) @@ -76,70 +111,19 @@ void Foam::functionObjects::fieldAverage::resetFields() } } } -} - - -void Foam::functionObjects::fieldAverage::initialise() -{ - if (!totalIter_.size()) - { - totalIter_.setSize(faItems_.size(), 1); - } - - if (!totalTime_.size()) - { - totalTime_.setSize(faItems_.size(), obr_.time().deltaTValue()); - } - else - { - // Check if totalTime_ has been set otherwise initialise - forAll(totalTime_, fieldi) - { - if (totalTime_[fieldi] < 0) - { - totalTime_[fieldi] = obr_.time().deltaTValue(); - } - } - } - - resetFields(); - - // Add mean fields to the field lists - forAll(faItems_, fieldi) - { - addMeanField(fieldi); - addMeanField(fieldi); - addMeanField(fieldi); - addMeanField(fieldi); - addMeanField(fieldi); - } - - // Add prime-squared mean fields to the field lists - forAll(faItems_, fieldi) - { - addPrime2MeanField(fieldi); - addPrime2MeanField(fieldi); - } - - // ensure first averaging works unconditionally - prevTimeIndex_ = -1; -} - - -void Foam::functionObjects::fieldAverage::restart() -{ - Log << " Restarting averaging at time " << obr_.time().name() - << nl << endl; - - totalIter_.clear(); - totalTime_.clear(); + // Re-create any mean fields initialise(); + + // Ensure first averaging works unconditionally + prevTimeIndex_ = -1; } void Foam::functionObjects::fieldAverage::calcAverages() { + Log << type() << " " << name() << ":" << nl; + const label currentTimeIndex = obr_.time().timeIndex(); const scalar currentTime = obr_.time().value(); @@ -147,19 +131,20 @@ void Foam::functionObjects::fieldAverage::calcAverages() { return; } - else - { - prevTimeIndex_ = currentTimeIndex; - } + + prevTimeIndex_ = currentTimeIndex; if (periodicRestart_ && currentTime > restartPeriod_*periodIndex_) { restart(); periodIndex_++; } + else + { + initialise(); + } - Log << type() << " " << name() << nl - << " Calculating averages" << nl; + Log << " Calculating averages" << nl; addMeanSqrToPrime2Mean(); addMeanSqrToPrime2Mean(); @@ -185,7 +170,8 @@ void Foam::functionObjects::fieldAverage::calcAverages() void Foam::functionObjects::fieldAverage::writeAverages() const { - Log << " Writing average fields" << endl; + Log << type() << " " << name() << ":" << nl + << " Writing average fields" << endl; writeFields(); writeFields(); @@ -193,12 +179,6 @@ void Foam::functionObjects::fieldAverage::writeAverages() const writeFields(); writeFields(); - Log << endl; -} - - -void Foam::functionObjects::fieldAverage::writeAveragingProperties() const -{ timeIOdictionary propsDict ( IOobject @@ -227,19 +207,49 @@ void Foam::functionObjects::fieldAverage::writeAveragingProperties() const } -void Foam::functionObjects::fieldAverage::readAveragingProperties() +void Foam::functionObjects::fieldAverage::read +( + const dictionary& dict, + const bool construct +) { - if ((restartOnRestart_ || restartOnOutput_) && log) + dict.readIfPresent("restartOnRestart", restartOnRestart_); + dict.readIfPresent("restartOnOutput", restartOnOutput_); + dict.readIfPresent("periodicRestart", periodicRestart_); + + if (periodicRestart_) { - Info<< " Starting averaging at time " << obr_.time().name() - << nl; + dict.lookup("restartPeriod") >> restartPeriod_; } - else + + mean_ = dict.lookupOrDefault("mean", true); + prime2Mean_ = dict.lookupOrDefault("prime2Mean", false); + base_ = baseTypeNames_[dict.lookupOrDefault("base", "time")]; + window_ = dict.lookupOrDefault("window", -1); + windowName_ = dict.lookupOrDefault("windowName", ""); + + if (construct) { + // First read of a run. Look for properties dict and read total + // iter/time values from it if available. + + faItems_.clear(); + totalIter_.clear(); + totalTime_.clear(); + + faItems_ = + PtrList + ( + dict.lookup("fields"), + fieldAverageItem::iNew(*this) + ); + totalIter_.setSize(faItems_.size(), 1); + totalTime_.setSize(faItems_.size(), -1); + typeIOobject propsDictHeader ( name() + "Properties", - obr_.time().startTime().name(), + obr_.time().name(), "uniform", obr_, IOobject::MUST_READ_IF_MODIFIED, @@ -247,40 +257,120 @@ void Foam::functionObjects::fieldAverage::readAveragingProperties() false ); - if (!propsDictHeader.headerOk()) + dictionary propsDict; + if + ( + !restartOnRestart_ + && !restartOnOutput_ + && propsDictHeader.headerOk() + ) { - Log << " Starting averaging at time " - << obr_.time().name() << nl; - - return; + propsDict = timeIOdictionary(propsDictHeader); } - timeIOdictionary propsDict(propsDictHeader); - - Log << " Restarting averaging for fields:" << nl; - - totalIter_.setSize(faItems_.size(), 1); - - // Initialise totalTime with negative values - // to indicate that it has not been set - totalTime_.setSize(faItems_.size(), -1); + bool first = true; + forAll(faItems_, fieldi) + { + const word& fieldName = faItems_[fieldi].fieldName(); + if (!propsDict.found(fieldName)) + { + if (first) + { + Log << " Starting averaging for fields:" << nl; + first = false; + } + Log << " " << fieldName << nl; + } + } + first = true; forAll(faItems_, fieldi) { const word& fieldName = faItems_[fieldi].fieldName(); if (propsDict.found(fieldName)) { - dictionary fieldDict(propsDict.subDict(fieldName)); - - totalIter_[fieldi] = fieldDict.lookup