diff --git a/src/functionObjects/field/fieldAverage/fieldAverage.C b/src/functionObjects/field/fieldAverage/fieldAverage.C index 769775639b..7c8aa89d08 100644 --- a/src/functionObjects/field/fieldAverage/fieldAverage.C +++ b/src/functionObjects/field/fieldAverage/fieldAverage.C @@ -42,38 +42,14 @@ namespace functionObjects // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -void Foam::functionObjects::fieldAverage::resetFields() -{ - for (const fieldAverageItem& item : faItems_) - { - if (item.mean()) - { - if (obr().found(item.meanFieldName())) - { - obr().checkOut(*obr()[item.meanFieldName()]); - } - } - - if (item.prime2Mean()) - { - if (obr().found(item.prime2MeanFieldName())) - { - obr().checkOut(*obr()[item.prime2MeanFieldName()]); - } - } - } -} - - void Foam::functionObjects::fieldAverage::initialize() { for (fieldAverageItem& item : faItems_) { - item.restart(0, false); + // Note: not clearing data needed for restart + item.clear(obr(), false); } - resetFields(); - Log << type() << " " << name() << ":" << nl; // Add mean fields to the field lists @@ -130,7 +106,7 @@ void Foam::functionObjects::fieldAverage::restart() for (fieldAverageItem& item : faItems_) { - item.restart(0, true); + item.clear(obr(), true); } initialize(); @@ -251,12 +227,23 @@ void Foam::functionObjects::fieldAverage::readAveragingProperties() getDict(fieldName, fieldDict); item.readState(fieldDict); - scalar userTotalTime = - obr().time().timeToUserTime(item.totalTime()); + if (item.allowRestart()) + { + scalar userTotalTime = + obr().time().timeToUserTime(item.totalTime()); - Info<< " " << fieldName - << " iters = " << item.totalIter() - << " time = " << userTotalTime << nl; + Info<< " " << fieldName + << ": iters = " << item.totalIter() + << " time = " << userTotalTime << nl; + } + else + { + item.clear(obr(), true); + + Info<< " " << fieldName + << ": starting averaging at time " + << obr().time().timeOutputValue() << endl; + } } else { diff --git a/src/functionObjects/field/fieldAverage/fieldAverage.H b/src/functionObjects/field/fieldAverage/fieldAverage.H index 52a907a405..b169bfa051 100644 --- a/src/functionObjects/field/fieldAverage/fieldAverage.H +++ b/src/functionObjects/field/fieldAverage/fieldAverage.H @@ -197,10 +197,6 @@ protected: // Initialisation routines - //- Checkout fields (causes deletion) from the database - // and reset lists - void resetFields(); - //- Reset lists (clear existing values) and initialize averaging. // Check requested field averages are valid, populate field lists void initialize(); diff --git a/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.C b/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.C index d96261d763..74927ea91f 100644 --- a/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.C +++ b/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.C @@ -68,9 +68,9 @@ Foam::functionObjects::fieldAverageItem::fieldAverageItem() : active_(false), fieldName_("unknown"), - mean_(0), + mean_(false), meanFieldName_("unknown"), - prime2Mean_(0), + prime2Mean_(false), prime2MeanFieldName_("unknown"), base_(baseType::ITER), totalIter_(0), @@ -80,7 +80,8 @@ Foam::functionObjects::fieldAverageItem::fieldAverageItem() windowType_(windowType::NONE), windowTimes_(), - windowFieldNames_() + windowFieldNames_(), + allowRestart_(true) {} @@ -103,7 +104,8 @@ Foam::functionObjects::fieldAverageItem::fieldAverageItem windowType_(faItem.windowType_), windowTimes_(faItem.windowTimes_), - windowFieldNames_(faItem.windowFieldNames_) + windowFieldNames_(faItem.windowFieldNames_), + allowRestart_(faItem.allowRestart_) {} @@ -154,16 +156,34 @@ void Foam::functionObjects::fieldAverageItem::evolve(const objectRegistry& obr) } -void Foam::functionObjects::fieldAverageItem::restart +void Foam::functionObjects::fieldAverageItem::clear ( - const scalar time0, - const bool override + const objectRegistry& obr, + bool fullClean ) { - if (totalTime_ < 0 || override) + if (mean_ && obr.found(meanFieldName_)) + { + obr.checkOut(*obr[meanFieldName_]); + } + + if (prime2Mean_ && obr.found(prime2MeanFieldName_)) + { + obr.checkOut(*obr[prime2MeanFieldName_]); + } + + for (const word& fieldName : windowFieldNames_) + { + if (obr.found(fieldName)) + { + obr.checkOut(*obr[fieldName]); + } + } + + if (totalTime_ < 0 || fullClean) { totalIter_ = 0; - totalTime_ = time0; + totalTime_ = 0; windowTimes_.clear(); windowFieldNames_.clear(); } @@ -231,6 +251,7 @@ void Foam::functionObjects::fieldAverageItem::operator= windowType_ = rhs.windowType_; windowTimes_ = rhs.windowTimes_; windowFieldNames_ = rhs.windowFieldNames_; + allowRestart_ = rhs.allowRestart_; } diff --git a/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.H b/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.H index c54bc66866..24fecbae7c 100644 --- a/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.H +++ b/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItem.H @@ -36,6 +36,8 @@ Description window 200; // optional averaging window windowName w1; // optional window name (default = "") windowType approximate; // window type + + allowRestart yes; // optional, used for windowType 'exact' } \endverbatim @@ -166,6 +168,9 @@ private: //- List of window field names (windowType = EXACT) FIFOStack windowFieldNames_; + //- Switch to write all necessary files for clean restart + bool allowRestart_; + public: @@ -237,6 +242,9 @@ public: //- Return the list of window field names (windowType = EXACT) inline const FIFOStack& windowFieldNames() const; + //- Return the allow restart flag + inline bool allowRestart() const; + //- Return the current time interval inline scalar dt(const scalar deltaT) const; @@ -249,14 +257,20 @@ public: //- Return true if time is inside window (including boundaries) inline bool inWindow(const scalar t) const; + //- Return true if we wish to store window fields + inline bool storeWindowFields() const; + + //- Return true if we wish to write window fields + inline bool writeWindowFields() 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); + //- Clear out all mean fields and (optionally) supporting data + void clear(const objectRegistry& obr, const bool fullClean); //- Read state and re-initialise values bool readState(const dictionary& dict); @@ -298,7 +312,8 @@ public: && a.totalTime_ == b.totalTime_ && a.window_ == b.window_ && a.windowName_ == b.windowName_ - && a.windowType_ == b.windowType_; + && a.windowType_ == b.windowType_ + && a.allowRestart_ == b.allowRestart_; } friend bool operator!= diff --git a/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemI.H b/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemI.H index b7426dd06e..371a3091e8 100644 --- a/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemI.H +++ b/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemI.H @@ -124,6 +124,12 @@ Foam::functionObjects::fieldAverageItem::windowFieldNames() const } +bool Foam::functionObjects::fieldAverageItem::allowRestart() const +{ + return allowRestart_; +} + + Foam::scalar Foam::functionObjects::fieldAverageItem::dt ( const scalar deltaT @@ -209,4 +215,16 @@ bool Foam::functionObjects::fieldAverageItem::inWindow(const scalar t) const } +bool Foam::functionObjects::fieldAverageItem::storeWindowFields() const +{ + return windowType_ == windowType::EXACT; +} + + +bool Foam::functionObjects::fieldAverageItem::writeWindowFields() const +{ + return (allowRestart_ && window_ > 0); +} + + // ************************************************************************* // diff --git a/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemIO.C b/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemIO.C index faef22d688..c1c3e1d19a 100644 --- a/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemIO.C +++ b/src/functionObjects/field/fieldAverage/fieldAverageItem/fieldAverageItemIO.C @@ -33,9 +33,9 @@ Foam::functionObjects::fieldAverageItem::fieldAverageItem(Istream& is) : active_(false), fieldName_("unknown"), - mean_(0), + mean_(false), meanFieldName_("unknown"), - prime2Mean_(0), + prime2Mean_(false), prime2MeanFieldName_("unknown"), base_(baseType::ITER), totalIter_(0), @@ -45,36 +45,10 @@ Foam::functionObjects::fieldAverageItem::fieldAverageItem(Istream& is) windowType_(windowType::NONE), windowTimes_(), - windowFieldNames_() + windowFieldNames_(), + allowRestart_(true) { - is.check(FUNCTION_NAME); - - const dictionaryEntry entry(dictionary::null, is); - - fieldName_ = entry.keyword(); - mean_ = readBool(entry.lookup("mean")); - prime2Mean_ = readBool(entry.lookup("prime2Mean")); - base_ = baseTypeNames_.lookup("base", entry); - window_ = entry.lookupOrDefault("window", -1.0); - - if (window_ > 0) - { - windowName_ = entry.lookupOrDefault("windowName", ""); - windowType_ = windowTypeNames_.lookup("windowType", entry); - - if (windowType_ == windowType::NONE) - { - window_ = -1; - } - } - - meanFieldName_ = fieldName_ + EXT_MEAN; - prime2MeanFieldName_ = fieldName_ + EXT_PRIME2MEAN; - if ((window_ > 0) && (!windowName_.empty())) - { - meanFieldName_ = meanFieldName_ + "_" + windowName_; - prime2MeanFieldName_ = prime2MeanFieldName_ + "_" + windowName_; - } + is >> *this; } @@ -99,15 +73,52 @@ Foam::Istream& Foam::functionObjects::operator>> if (faItem.window_ > 0) { - faItem.windowName_ = entry.lookupOrDefault("windowName", ""); faItem.windowType_ = faItem.windowTypeNames_.lookup("windowType", entry); - if (faItem.windowType_ == fieldAverageItem::windowType::NONE) + if (faItem.windowType_ != fieldAverageItem::windowType::NONE) { + if + ( + faItem.base_ == fieldAverageItem::baseType::ITER + && label(faItem.window_) < 1 + ) + { + FatalIOErrorInFunction(entry) + << "Window must be 1 or more for base type " + << faItem.baseTypeNames_[fieldAverageItem::baseType::ITER] + << exit(FatalIOError); + } + + faItem.windowName_ = entry.lookupOrDefault("windowName", ""); + + if (faItem.windowType_ == fieldAverageItem::windowType::EXACT) + { + faItem.allowRestart_ = readBool(entry.lookup("allowRestart")); + + if (!faItem.allowRestart_) + { + WarningInFunction + << faItem.windowTypeNames_[faItem.windowType_] + << " windowing for field " << faItem.fieldName_ + << " will not write intermediate files and restart will" + << " not be possible. To enable, please set" + << " 'allowRestart' to 'yes'" + << endl; + } + } + } + else + { + // Deactivate windowing faItem.window_ = -1; } } + else + { + // Deactivate windowing + faItem.window_ = -1; + } faItem.meanFieldName_ = faItem.fieldName_ + fieldAverageItem::EXT_MEAN; faItem.prime2MeanFieldName_ = @@ -121,6 +132,7 @@ Foam::Istream& Foam::functionObjects::operator>> faItem.prime2MeanFieldName_ = faItem.prime2MeanFieldName_ + "_" + faItem.windowName_; } + return is; } @@ -135,11 +147,9 @@ Foam::Ostream& Foam::functionObjects::operator<< os.beginBlock(faItem.fieldName_); - os.writeKeyword("mean") << faItem.mean_ << token::END_STATEMENT << nl; - os.writeKeyword("prime2Mean") << faItem.prime2Mean_ - << token::END_STATEMENT << nl; - os.writeKeyword("base") << faItem.baseTypeNames_[faItem.base_] - << token::END_STATEMENT << nl; + os.writeEntry("mean", faItem.mean_); + os.writeEntry("prime2Mean", faItem.prime2Mean_); + os.writeEntry("base", faItem.baseTypeNames_[faItem.base_]); if (faItem.window_ > 0) { @@ -155,6 +165,8 @@ Foam::Ostream& Foam::functionObjects::operator<< "windowType", faItem.windowTypeNames_[faItem.windowType_] ); + + os.writeEntry("allowRestart", faItem.allowRestart_); } os.endBlock() << flush; diff --git a/src/functionObjects/field/fieldAverage/fieldAverageTemplates.C b/src/functionObjects/field/fieldAverage/fieldAverageTemplates.C index 9946d67a21..5f34c9de2a 100644 --- a/src/functionObjects/field/fieldAverage/fieldAverageTemplates.C +++ b/src/functionObjects/field/fieldAverage/fieldAverageTemplates.C @@ -141,11 +141,18 @@ void Foam::functionObjects::fieldAverage::restoreWindowFieldsType IOobject::NO_WRITE ); - if (io.typeHeaderOk(false)) + if (io.typeHeaderOk(true)) { DebugInfo << "Read and store: " << name << endl; obr().store(new Type(io, fieldPtr->mesh())); } + else + { + WarningInFunction + << "Unable to read window " << Type::typeName << " " << name + << ". Averaging restart behaviour may be compromised" + << endl; + } } } @@ -262,7 +269,6 @@ void Foam::functionObjects::fieldAverage::storeWindowFieldType ) { const word& fieldName = item.fieldName(); - if (!foundObject(fieldName)) { return; @@ -306,7 +312,7 @@ void Foam::functionObjects::fieldAverage::storeWindowFields() for (fieldAverageItem& item : faItems_) { - if (item.window() > 0) + if (item.storeWindowFields()) { storeWindowFieldType(item); storeWindowFieldType(item); @@ -432,6 +438,7 @@ void Foam::functionObjects::fieldAverage::writeFields() const writeFieldType(fieldName); writeFieldType(fieldName); } + if (item.prime2Mean()) { const word& fieldName = item.prime2MeanFieldName(); @@ -439,7 +446,8 @@ void Foam::functionObjects::fieldAverage::writeFields() const writeFieldType(fieldName); writeFieldType(fieldName); } - if (item.window() > 0) + + if (item.writeWindowFields()) { FIFOStack fieldNames = item.windowFieldNames(); forAllConstIters(fieldNames, fieldNameIter)