diff --git a/src/OpenFOAM/db/Time/Time.C b/src/OpenFOAM/db/Time/Time.C index 33b98f0959..62e6ed1ea9 100644 --- a/src/OpenFOAM/db/Time/Time.C +++ b/src/OpenFOAM/db/Time/Time.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -364,6 +364,7 @@ Foam::Time::Time writeCompression_(IOstream::UNCOMPRESSED), graphFormat_("raw"), runTimeModifiable_(false), + cacheTemporaryObjects_(true), functionObjects_(*this, enableFunctionObjects) { @@ -440,6 +441,7 @@ Foam::Time::Time writeCompression_(IOstream::UNCOMPRESSED), graphFormat_("raw"), runTimeModifiable_(false), + cacheTemporaryObjects_(true), functionObjects_ ( @@ -523,6 +525,7 @@ Foam::Time::Time writeCompression_(IOstream::UNCOMPRESSED), graphFormat_("raw"), runTimeModifiable_(false), + cacheTemporaryObjects_(true), functionObjects_(*this, enableFunctionObjects) { @@ -600,6 +603,7 @@ Foam::Time::Time writeCompression_(IOstream::UNCOMPRESSED), graphFormat_("raw"), runTimeModifiable_(false), + cacheTemporaryObjects_(true), functionObjects_(*this, enableFunctionObjects) { @@ -804,6 +808,11 @@ bool Foam::Time::run() const { if (!running && timeIndex_ != startTimeIndex_) { + if (cacheTemporaryObjects_) + { + cacheTemporaryObjects_ = checkCacheTemporaryObjects(); + } + functionObjects_.execute(); functionObjects_.end(); } @@ -821,6 +830,11 @@ bool Foam::Time::run() const } else { + if (cacheTemporaryObjects_) + { + cacheTemporaryObjects_ = checkCacheTemporaryObjects(); + } + functionObjects_.execute(); } } diff --git a/src/OpenFOAM/db/Time/Time.H b/src/OpenFOAM/db/Time/Time.H index 7d95352b24..aff3a14040 100644 --- a/src/OpenFOAM/db/Time/Time.H +++ b/src/OpenFOAM/db/Time/Time.H @@ -187,6 +187,9 @@ private: //- Is runtime modification of dictionaries allowed? Switch runTimeModifiable_; + //- Is temporary object cache enabled + mutable bool cacheTemporaryObjects_; + //- Function objects executed at start and on ++, += mutable functionObjectList functionObjects_; diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistry.C b/src/OpenFOAM/db/objectRegistry/objectRegistry.C index 926c4b43b0..8d00a9426b 100644 --- a/src/OpenFOAM/db/objectRegistry/objectRegistry.C +++ b/src/OpenFOAM/db/objectRegistry/objectRegistry.C @@ -42,6 +42,46 @@ bool Foam::objectRegistry::parentNotTime() const } +void Foam::objectRegistry::readCacheTemporaryObjects() const +{ + if + ( + !cacheTemporaryObjectsSet_ + && time_.controlDict().found("cacheTemporaryObjects") + ) + { + cacheTemporaryObjectsSet_ = true; + + const dictionary& controlDict = time_.controlDict(); + + wordList cacheTemporaryObjects; + + if (controlDict.isDict("cacheTemporaryObjects")) + { + if(controlDict.subDict("cacheTemporaryObjects").found(name())) + { + controlDict.subDict("cacheTemporaryObjects").lookup(name()) + >> cacheTemporaryObjects; + } + } + else + { + controlDict.lookup("cacheTemporaryObjects") + >> cacheTemporaryObjects; + } + + forAll(cacheTemporaryObjects, i) + { + cacheTemporaryObjects_.insert + ( + cacheTemporaryObjects[i], + {false, false} + ); + } + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::objectRegistry::objectRegistry @@ -67,7 +107,8 @@ Foam::objectRegistry::objectRegistry time_(t), parent_(t), dbDir_(name()), - event_(1) + event_(1), + cacheTemporaryObjectsSet_(false) {} @@ -82,7 +123,8 @@ Foam::objectRegistry::objectRegistry time_(io.time()), parent_(io.db()), dbDir_(parent_.dbDir()/local()/name()), - event_(1) + event_(1), + cacheTemporaryObjectsSet_(false) { writeOpt() = IOobject::AUTO_WRITE; } @@ -92,6 +134,7 @@ Foam::objectRegistry::objectRegistry Foam::objectRegistry::~objectRegistry() { + cacheTemporaryObjects_.clear(); clear(); } @@ -290,6 +333,75 @@ void Foam::objectRegistry::clear() } +void Foam::objectRegistry::resetCacheTemporaryObject +( + const regIOobject& ob +) const +{ + if (cacheTemporaryObjects_.size()) + { + HashTable>::iterator iter + ( + cacheTemporaryObjects_.find(ob.name()) + ); + + // If object ob if is in the cacheTemporaryObjects list + // and has been cached reset the cached flag + if (iter != cacheTemporaryObjects_.end()) + { + iter().first() = false; + } + } +} + + +bool Foam::objectRegistry::checkCacheTemporaryObjects() const +{ + bool enabled = cacheTemporaryObjects_.size(); + + forAllConstIter(HashTable, *this, iter) + { + const objectRegistry* orPtr_ = + dynamic_cast(iter()); + + // Protect against re-searching the top-level registry + if (orPtr_ && orPtr_ != this) + { + enabled = orPtr_->checkCacheTemporaryObjects() || enabled; + } + } + + if (enabled) + { + forAllIter + ( + typename HashTable>, + cacheTemporaryObjects_, + iter + ) + { + if (!iter().second()) + { + Warning + << "Could not find temporary object " << iter.key() + << " in registry " << name() << nl + << "Available temporary objects " + << temporaryObjects_ + << endl; + } + else + { + iter().second() = false; + } + } + + temporaryObjects_.clear(); + } + + return enabled; +} + + void Foam::objectRegistry::rename(const word& newName) { regIOobject::rename(newName); diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistry.H b/src/OpenFOAM/db/objectRegistry/objectRegistry.H index 98248c6a9b..e6cbfd4ae6 100644 --- a/src/OpenFOAM/db/objectRegistry/objectRegistry.H +++ b/src/OpenFOAM/db/objectRegistry/objectRegistry.H @@ -38,6 +38,8 @@ SourceFiles #include "HashTable.H" #include "regIOobject.H" #include "wordReList.H" +#include "HashSet.H" +#include "Pair.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -67,6 +69,17 @@ class objectRegistry //- Current event mutable label event_; + //- Table of temporary object names with current state + mutable HashTable> cacheTemporaryObjects_; + + //- State of cacheTemporaryObjects_, set true after reading + mutable bool cacheTemporaryObjectsSet_; + + //- Accumulated list of temporary objects available to cache + // Used to provide diagnostics in case the requested object is not + // available + mutable HashSet temporaryObjects_; + // Private Member Functions @@ -74,6 +87,8 @@ class objectRegistry // Used to terminate searching within the ancestors bool parentNotTime() const; + void readCacheTemporaryObjects() const; + public: @@ -199,6 +214,17 @@ public: //- Remove all regIOobject owned by the registry void clear(); + template + bool cacheTemporaryObject(Object& ob) const; + + //- Reset cache state of the given object + // in the cacheTemporaryObjects set + void resetCacheTemporaryObject(const regIOobject& ob) const; + + //- Check that all objects in the cacheTemporaryObjects set + // were cached + bool checkCacheTemporaryObjects() const; + // Reading diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C b/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C index 301959b01f..d12c595bb2 100644 --- a/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C +++ b/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -211,4 +211,64 @@ Type& Foam::objectRegistry::lookupObjectRef(const word& name) const } +template +bool Foam::objectRegistry::cacheTemporaryObject(Object& ob) const +{ + readCacheTemporaryObjects(); + + if (cacheTemporaryObjects_.size()) + { + temporaryObjects_.insert(ob.name()); + + HashTable>::iterator iter + ( + cacheTemporaryObjects_.find(ob.name()) + ); + + // Cache object ob if is in the cacheTemporaryObjects list + // and hasn't been cached yet + if (iter != cacheTemporaryObjects_.end() && iter().first() == false) + { + iter().first() = true; + iter().second() = true; + + if (ob.db().template foundObject(ob.name())) + { + Object& cachedOb = + ob.db().template lookupObjectRef(ob.name()); + + // If the object is already cached in the database delete it + if (&cachedOb != &ob && cachedOb.ownedByRegistry()) + { + cachedOb.release(); + cachedOb.checkOut(); + cachedOb.rename(cachedOb.name() + "Cached"); + delete &cachedOb; + } + } + + if (debug) + { + Info<< "Caching " << ob.name() + << " of type " << ob.type() << endl; + } + + ob.release(); + ob.checkOut(); + store(new Object(move(ob))); + + return true; + } + else + { + return false; + } + } + else + { + return false; + } +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/db/regIOobject/regIOobject.C b/src/OpenFOAM/db/regIOobject/regIOobject.C index 76355ec71b..07119fb1cd 100644 --- a/src/OpenFOAM/db/regIOobject/regIOobject.C +++ b/src/OpenFOAM/db/regIOobject/regIOobject.C @@ -162,6 +162,8 @@ Foam::regIOobject::~regIOobject() } } + db().resetCacheTemporaryObject(*this); + // Check out of objectRegistry if not owned by the registry if (!ownedByRegistry_) { diff --git a/src/OpenFOAM/db/regIOobject/regIOobject.H b/src/OpenFOAM/db/regIOobject/regIOobject.H index bc66bd12b8..a17504a0c1 100644 --- a/src/OpenFOAM/db/regIOobject/regIOobject.H +++ b/src/OpenFOAM/db/regIOobject/regIOobject.H @@ -57,19 +57,6 @@ class regIOobject : public IOobject { - -protected: - - //- Helper: check readOpt flags and read if necessary - bool readHeaderOk - ( - const IOstream::streamFormat PstreamFormat, - const word& typeName - ); - - -private: - // Private Data //- Is this object registered with the registry @@ -97,6 +84,16 @@ private: void operator=(const regIOobject&); +protected: + + //- Helper: check readOpt flags and read if necessary + bool readHeaderOk + ( + const IOstream::streamFormat PstreamFormat, + const word& typeName + ); + + public: // Static data diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C index c2d9156eaf..8164b8fa76 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C @@ -25,6 +25,7 @@ License #include "DimensionedField.H" #include "dimensionedType.H" +#include "Time.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -382,7 +383,9 @@ DimensionedField::New template DimensionedField::~DimensionedField() -{} +{ + db().cacheTemporaryObject(*this); +} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C index b3a85950c1..eba598ae9a 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C @@ -933,6 +933,8 @@ Foam::GeometricField::New template class PatchField, class GeoMesh> Foam::GeometricField::~GeometricField() { + this->db().cacheTemporaryObject(*this); + deleteDemandDrivenData(field0Ptr_); deleteDemandDrivenData(fieldPrevIterPtr_); }