From e68acbe31449d5829fa20cc378fa92072eae53f0 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Tue, 14 Mar 2023 10:58:46 +0100
Subject: [PATCH] STYLE: check tmp with is_reference() or movable(), instead of
 isTmp()

- missed consistency in a few places.

- return nullptr (with automatic conversion to tmp) on failures
  instead of tmp<....>(nullptr), for cleaner coding.

INT: add support for an 'immovable' tmp pointer

- this idea is from openfoam.org, to allow creation of a tmp that is
  protected from having its memory reclaimed in field operations

ENH: tmp NewImmovable factory method, forwards as immovable/movable
---
 src/OpenFOAM/memory/refPtr/refPtr.H           |  7 +-
 src/OpenFOAM/memory/refPtr/refPtrI.H          | 32 ++++++-
 src/OpenFOAM/memory/tmp/tmp.H                 | 46 ++++++++--
 src/OpenFOAM/memory/tmp/tmpI.H                | 91 ++++++++++++++-----
 .../atmAmbientTurbSource.C                    |  3 +-
 .../atmBuoyancyTurbSource.C                   |  3 +-
 .../atmLengthScaleTurbSource.C                |  3 +-
 .../atmPlantCanopyTurbSource.C                |  8 +-
 .../uncorrectedLnGrad/uncorrectedLnGrad.C     |  2 +-
 .../general/constrainHbyA/constrainHbyA.C     |  8 +-
 .../orthogonalSnGrad/orthogonalSnGrad.C       |  2 +-
 .../snGradSchemes/snGradScheme/snGradScheme.H |  8 +-
 .../uncorrectedSnGrad/uncorrectedSnGrad.C     |  2 +-
 .../schemes/CoBlended/CoBlended.H             |  5 +-
 .../schemes/cellCoBlended/cellCoBlended.H     |  5 +-
 .../schemes/fixedBlended/fixedBlended.H       |  5 +-
 .../schemes/limiterBlended/limiterBlended.H   |  5 +-
 .../schemes/localBlended/localBlended.H       |  5 +-
 .../outletStabilised/outletStabilised.H       |  5 +-
 .../surfaceInterpolationScheme.H              |  5 +-
 .../DispersionRASModel/DispersionRASModel.C   | 16 ++--
 .../DispersionRASModel/DispersionRASModel.H   |  8 +-
 .../BrownianMotion/BrownianMotionForce.C      | 15 +--
 .../BrownianMotion/BrownianMotionForce.H      | 10 +-
 24 files changed, 184 insertions(+), 115 deletions(-)

diff --git a/src/OpenFOAM/memory/refPtr/refPtr.H b/src/OpenFOAM/memory/refPtr/refPtr.H
index 73bd6af3ef7..3d0ef7d559b 100644
--- a/src/OpenFOAM/memory/refPtr/refPtr.H
+++ b/src/OpenFOAM/memory/refPtr/refPtr.H
@@ -63,6 +63,7 @@ class refPtr
         enum refType
         {
             PTR,        //!< A managed pointer (not ref-counted)
+            REF_Types,  //!< Magic value (ptr: less-than, ref: greater than)
             CREF,       //!< A const reference to an object
             REF         //!< A non-const reference to an object
         };
@@ -175,13 +176,13 @@ public:
         bool good() const noexcept { return bool(ptr_); }
 
         //- If the stored/referenced content is const
-        bool is_const() const noexcept { return (type_ == CREF); }
+        inline bool is_const() const noexcept;
 
         //- True if this is a managed pointer (not a reference)
-        bool is_pointer() const noexcept { return (type_ == PTR); }
+        inline bool is_pointer() const noexcept;
 
         //- True if this is a reference (not a pointer)
-        bool is_reference() const noexcept { return (type_ != PTR); }
+        inline bool is_reference() const noexcept;
 
         //- True if this is a non-null managed pointer
         inline bool movable() const noexcept;
diff --git a/src/OpenFOAM/memory/refPtr/refPtrI.H b/src/OpenFOAM/memory/refPtr/refPtrI.H
index a496834ce91..dbb5394903a 100644
--- a/src/OpenFOAM/memory/refPtr/refPtrI.H
+++ b/src/OpenFOAM/memory/refPtr/refPtrI.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2016-2017 OpenFOAM Foundation
-    Copyright (C) 2018-2022 OpenCFD Ltd.
+    Copyright (C) 2018-2023 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -64,7 +64,6 @@ inline constexpr Foam::refPtr<T>::refPtr(T* p) noexcept
 {}
 
 
-
 template<class T>
 inline constexpr Foam::refPtr<T>::refPtr(const T& obj) noexcept
 :
@@ -190,17 +189,40 @@ inline Foam::refPtr<T>::~refPtr() noexcept
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+template<class T>
+inline bool Foam::refPtr<T>::is_const() const noexcept
+{
+    return (type_ == CREF);
+}
+
+
+template<class T>
+inline bool Foam::refPtr<T>::is_pointer() const noexcept
+{
+    //OR: return (type_ == PTR);
+    return (type_ < REF_Types);
+}
+
+
+template<class T>
+inline bool Foam::refPtr<T>::is_reference() const noexcept
+{
+    //OR: return (type_ == CREF || type_ == REF);
+    return (type_ > REF_Types);
+}
+
+
 template<class T>
 inline bool Foam::refPtr<T>::movable() const noexcept
 {
-    return (is_pointer() && ptr_);
+    return (ptr_ && is_pointer());
 }
 
 
 template<class T>
 inline const T& Foam::refPtr<T>::cref() const
 {
-    if (is_pointer() && !ptr_)
+    if (!ptr_ && is_pointer())
     {
         FatalErrorInFunction
             << this->typeName() << " deallocated"
@@ -221,7 +243,7 @@ inline T& Foam::refPtr<T>::ref() const
             << this->typeName()
             << abort(FatalError);
     }
-    else if (is_pointer() && !ptr_)
+    else if (!ptr_ && is_pointer())
     {
         FatalErrorInFunction
             << this->typeName() << " deallocated"
diff --git a/src/OpenFOAM/memory/tmp/tmp.H b/src/OpenFOAM/memory/tmp/tmp.H
index 56661ebb248..98f8dcf222b 100644
--- a/src/OpenFOAM/memory/tmp/tmp.H
+++ b/src/OpenFOAM/memory/tmp/tmp.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2018-2022 OpenCFD Ltd.
+    Copyright (C) 2018-2023 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -34,6 +34,8 @@ Description
     and a shared_ptr without ref-counting and null deleter.
     This allows the tmp to double as a pointer management and an indirect
     pointer to externally allocated objects.
+    In contrast to std::shared_ptr, only a limited number of tmp items
+    will ever share a pointer.
 
 SourceFiles
     tmpI.H
@@ -73,6 +75,8 @@ class tmp
         enum refType
         {
             PTR,        //!< A managed pointer (ref-counted)
+            CACHE_PTR,  //!< A managed pointer (ref-counted), but immovable
+            REF_Types,  //!< Magic value (ptr: less-than, ref: greater than)
             CREF,       //!< A const reference to an object
             REF         //!< A non-const reference to an object
         };
@@ -86,9 +90,8 @@ class tmp
 
     // Private Member Functions
 
-        //- Increment the ref-count for a managed pointer
-        //- and check that it is not oversubscribed
-        inline void incrCount();
+        //- Fatal if ref-count of a managed pointer is oversubscribed
+        inline void checkUseCount() const;
 
 
 public:
@@ -117,6 +120,10 @@ public:
         //- Construct, taking ownership of the pointer.
         inline explicit tmp(T* p);
 
+        //- Construct, taking ownership of the pointer,
+        //- with specified protection against moving.
+        inline tmp(bool immovable, T* p);
+
         //- Implicit construct for a const reference to an object.
         inline constexpr tmp(const T& obj) noexcept;
 
@@ -166,6 +173,19 @@ public:
             return tmp<T>(new T(std::forward<Args>(args)...));
         }
 
+        //- Construct movable/immovable tmp with forwarding arguments
+        //  \param immovable create as non-movable pointer
+        //  \param args list of arguments with which an instance of T
+        //      will be constructed.
+        //
+        //  \note Similar to std::make_shared, but the overload for
+        //      array types is not disabled.
+        template<class... Args>
+        static tmp<T> NewImmovable(bool immovable, Args&&... args)
+        {
+            return tmp<T>(immovable, new T(std::forward<Args>(args)...));
+        }
+
         //- Construct tmp from derived type with forwarding arguments
         //  \param args list of arguments with which an instance of U
         //      will be constructed.
@@ -191,13 +211,13 @@ public:
         bool good() const noexcept { return bool(ptr_); }
 
         //- If the stored/referenced content is const
-        bool is_const() const noexcept { return (type_ == CREF); }
+        inline bool is_const() const noexcept;
 
         //- True if this is a managed pointer (not a reference)
-        bool is_pointer() const noexcept { return (type_ == PTR); }
+        inline bool is_pointer() const noexcept;
 
         //- True if this is a reference (not a pointer)
-        bool is_reference() const noexcept { return (type_ != PTR); }
+        inline bool is_reference() const noexcept;
 
         //- True if this is a non-null managed pointer with a unique ref-count
         inline bool movable() const noexcept;
@@ -239,9 +259,13 @@ public:
         //- Clear existing and transfer ownership.
         inline void reset(tmp<T>&& other) noexcept;
 
-        //- Delete managed temporary object and set to new given pointer
+        //- Delete managed temporary object and set to new given pointer.
         inline void reset(T* p = nullptr) noexcept;
 
+        //- Delete managed temporary object and set to new given pointer,
+        //- with specified protection against moving.
+        inline void reset(bool immovable, T* p) noexcept;
+
         //- Avoid inadvertent casting (to object or pointer)
         void reset(const autoPtr<T>&) = delete;
 
@@ -330,8 +354,10 @@ public:
         //- Identical to good(), or bool operator
         bool valid() const noexcept { return bool(ptr_); }
 
-        //- Identical to is_pointer()
-        bool isTmp() const noexcept { return type_ == PTR; }
+        //- Identical to is_pointer(). Prefer is_pointer() or movable().
+        //
+        //  \deprecated(2020-07) - prefer is_pointer() or movable()
+        bool isTmp() const noexcept { return is_pointer(); }
 
         //- Deprecated(2020-07) True if a null managed pointer
         //
diff --git a/src/OpenFOAM/memory/tmp/tmpI.H b/src/OpenFOAM/memory/tmp/tmpI.H
index 191b44a67f7..044b2c1bbe2 100644
--- a/src/OpenFOAM/memory/tmp/tmpI.H
+++ b/src/OpenFOAM/memory/tmp/tmpI.H
@@ -29,29 +29,29 @@ License
 #include "error.H"
 #include <typeinfo>
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 template<class T>
-inline void Foam::tmp<T>::incrCount()
+inline Foam::word Foam::tmp<T>::typeName()
 {
-    ptr_->refCount::operator++();
-
-    if (ptr_->refCount::use_count() > 1)
-    {
-        FatalErrorInFunction
-            << "Attempt to create more than 2 tmp's referring to the same"
-               " object of type tmp<" << typeid(T).name() << '>'
-            << abort(FatalError);
-    }
+    return Foam::word("tmp<" + std::string(typeid(T).name()) + '>', false);
 }
 
 
-// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class T>
-inline Foam::word Foam::tmp<T>::typeName()
+inline void Foam::tmp<T>::checkUseCount() const
 {
-    return Foam::word("tmp<" + std::string(typeid(T).name()) + '>', false);
+    if (ptr_ && ptr_->refCount::use_count() > 1)
+    {
+        FatalErrorInFunction
+            << "Attempt to create more than "
+            << (ptr_->refCount::use_count() + 1)
+            << " tmp's referring to the same object of type tmp<"
+            << typeid(T).name() << '>'
+            << abort(FatalError);
+    }
 }
 
 
@@ -90,6 +90,15 @@ inline Foam::tmp<T>::tmp(T* p)
 }
 
 
+template<class T>
+inline Foam::tmp<T>::tmp(bool immovable, T* p)
+:
+    tmp<T>(p)
+{
+    if (ptr_ && immovable) type_ = CACHE_PTR;
+}
+
+
 template<class T>
 inline constexpr Foam::tmp<T>::tmp(const T& obj) noexcept
 :
@@ -130,7 +139,8 @@ inline Foam::tmp<T>::tmp(const tmp<T>& rhs)
     {
         if (ptr_)
         {
-            this->incrCount();
+            ptr_->refCount::operator++();
+            this->checkUseCount();
         }
         else
         {
@@ -160,7 +170,8 @@ inline Foam::tmp<T>::tmp(const tmp<T>& rhs, bool reuse)
             }
             else
             {
-                this->incrCount();
+                ptr_->refCount::operator++();
+                this->checkUseCount();
             }
         }
         else
@@ -192,17 +203,40 @@ inline Foam::tmp<T>::~tmp() noexcept
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+template<class T>
+inline bool Foam::tmp<T>::is_const() const noexcept
+{
+    return (type_ == CREF);
+}
+
+
+template<class T>
+inline bool Foam::tmp<T>::is_pointer() const noexcept
+{
+    //OR: return (type_ == PTR || type_ == CACHE_PTR);
+    return (type_ < REF_Types);
+}
+
+
+template<class T>
+inline bool Foam::tmp<T>::is_reference() const noexcept
+{
+    //OR: return (type_ == CREF || type_ == REF);
+    return (type_ > REF_Types);
+}
+
+
 template<class T>
 inline bool Foam::tmp<T>::movable() const noexcept
 {
-    return (is_pointer() && ptr_ && ptr_->refCount::unique());
+    return (ptr_ && type_ == PTR && ptr_->refCount::unique());
 }
 
 
 template<class T>
 inline const T& Foam::tmp<T>::cref() const
 {
-    if (is_pointer() && !ptr_)
+    if (!ptr_ && is_pointer())
     {
         FatalErrorInFunction
             << this->typeName() << " deallocated"
@@ -223,7 +257,7 @@ inline T& Foam::tmp<T>::ref() const
             << this->typeName()
             << abort(FatalError);
     }
-    else if (is_pointer() && !ptr_)
+    else if (!ptr_ && is_pointer())
     {
         FatalErrorInFunction
             << this->typeName() << " deallocated"
@@ -244,7 +278,7 @@ inline T* Foam::tmp<T>::ptr() const
             << abort(FatalError);
     }
 
-    if (is_pointer())
+    if (type_ == PTR)
     {
         if (!ptr_->refCount::unique())
         {
@@ -262,6 +296,7 @@ inline T* Foam::tmp<T>::ptr() const
         return p;
     }
 
+    // CACHE_PTR (immovable) is cloned, as per a reference
     return ptr_->clone().ptr();
 }
 
@@ -269,7 +304,7 @@ inline T* Foam::tmp<T>::ptr() const
 template<class T>
 inline void Foam::tmp<T>::clear() const noexcept
 {
-    if (is_pointer() && ptr_)
+    if (ptr_ && is_pointer())
     {
         if (ptr_->refCount::unique())
         {
@@ -293,6 +328,14 @@ inline void Foam::tmp<T>::reset(T* p) noexcept
 }
 
 
+template<class T>
+inline void Foam::tmp<T>::reset(bool immovable, T* p) noexcept
+{
+    reset(p);
+    if (ptr_ && immovable) type_ = CACHE_PTR;
+}
+
+
 template<class T>
 inline void Foam::tmp<T>::reset(tmp<T>&& other) noexcept
 {
@@ -382,7 +425,7 @@ inline void Foam::tmp<T>::swap(tmp<T>& other) noexcept
 template<class T>
 inline const T* Foam::tmp<T>::operator->() const
 {
-    if (is_pointer() && !ptr_)
+    if (!ptr_ && is_pointer())
     {
         FatalErrorInFunction
             << this->typeName() << " deallocated"
@@ -403,7 +446,7 @@ inline T* Foam::tmp<T>::operator->()
             << this->typeName()
             << abort(FatalError);
     }
-    else if (is_pointer() && !ptr_)
+    else if (!ptr_ && is_pointer())
     {
         FatalErrorInFunction
             << this->typeName() << " deallocated"
@@ -428,7 +471,7 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& other)
     if (other.is_pointer())
     {
         ptr_ = other.ptr_;
-        type_ = PTR;
+        type_ = other.type_;
 
         other.ptr_ = nullptr;
         other.type_ = PTR;
diff --git a/src/atmosphericModels/fvOptions/atmAmbientTurbSource/atmAmbientTurbSource.C b/src/atmosphericModels/fvOptions/atmAmbientTurbSource/atmAmbientTurbSource.C
index 3fb7f1e708e..1685e500b61 100644
--- a/src/atmosphericModels/fvOptions/atmAmbientTurbSource/atmAmbientTurbSource.C
+++ b/src/atmosphericModels/fvOptions/atmAmbientTurbSource/atmAmbientTurbSource.C
@@ -134,8 +134,7 @@ Foam::fv::atmAmbientTurbSource::atmAmbientTurbSource
     else
     {
         FatalErrorInFunction
-            << "Unable to find neither epsilon nor omega field." << nl
-            << "atmAmbientTurbSource needs either epsilon or omega field."
+            << "Needs either epsilon or omega field."
             << abort(FatalError);
     }
 
diff --git a/src/atmosphericModels/fvOptions/atmBuoyancyTurbSource/atmBuoyancyTurbSource.C b/src/atmosphericModels/fvOptions/atmBuoyancyTurbSource/atmBuoyancyTurbSource.C
index 29b0d9ed4f7..cc6e074cb0f 100644
--- a/src/atmosphericModels/fvOptions/atmBuoyancyTurbSource/atmBuoyancyTurbSource.C
+++ b/src/atmosphericModels/fvOptions/atmBuoyancyTurbSource/atmBuoyancyTurbSource.C
@@ -226,8 +226,7 @@ Foam::fv::atmBuoyancyTurbSource::atmBuoyancyTurbSource
     else
     {
         FatalErrorInFunction
-            << "Unable to find neither epsilon nor omega field." << nl
-            << "atmBuoyancyTurbSource needs either epsilon or omega field."
+            << "Needs either epsilon or omega field."
             << abort(FatalError);
     }
 
diff --git a/src/atmosphericModels/fvOptions/atmLengthScaleTurbSource/atmLengthScaleTurbSource.C b/src/atmosphericModels/fvOptions/atmLengthScaleTurbSource/atmLengthScaleTurbSource.C
index bbb26ecd6fa..421a7d4d67e 100644
--- a/src/atmosphericModels/fvOptions/atmLengthScaleTurbSource/atmLengthScaleTurbSource.C
+++ b/src/atmosphericModels/fvOptions/atmLengthScaleTurbSource/atmLengthScaleTurbSource.C
@@ -161,8 +161,7 @@ Foam::fv::atmLengthScaleTurbSource::atmLengthScaleTurbSource
     else
     {
         FatalErrorInFunction
-            << "Unable to find neither epsilon nor omega field." << nl
-            << "atmLengthScaleTurbSource needs either epsilon or omega field."
+            << "Needs either epsilon or omega field."
             << abort(FatalError);
     }
 
diff --git a/src/atmosphericModels/fvOptions/atmPlantCanopyTurbSource/atmPlantCanopyTurbSource.C b/src/atmosphericModels/fvOptions/atmPlantCanopyTurbSource/atmPlantCanopyTurbSource.C
index c7df352eb91..9ced80a9a16 100644
--- a/src/atmosphericModels/fvOptions/atmPlantCanopyTurbSource/atmPlantCanopyTurbSource.C
+++ b/src/atmosphericModels/fvOptions/atmPlantCanopyTurbSource/atmPlantCanopyTurbSource.C
@@ -123,8 +123,9 @@ Foam::fv::atmPlantCanopyTurbSource::atmPlantCanopyTurbSource
     tmp<volScalarField> tepsilon = turbPtr->epsilon();
     tmp<volScalarField> tomega = turbPtr->omega();
 
-    if (!tepsilon.isTmp())
+    if (tepsilon.is_reference())
     {
+        isEpsilon_ = true;
         fieldNames_[0] = tepsilon().name();
 
         const dictionary& turbDict = turbPtr->coeffDict();
@@ -132,7 +133,7 @@ Foam::fv::atmPlantCanopyTurbSource::atmPlantCanopyTurbSource
         C1_.read("C1", turbDict);
         C2_.read("C2", turbDict);
     }
-    else if (!tomega.isTmp())
+    else if (tomega.is_reference())
     {
         isEpsilon_ = false;
         fieldNames_[0] = tomega().name();
@@ -143,8 +144,7 @@ Foam::fv::atmPlantCanopyTurbSource::atmPlantCanopyTurbSource
     else
     {
         FatalErrorInFunction
-            << "Unable to find neither epsilon nor omega field." << nl
-            << "atmPlantCanopyTurbSource needs either epsilon or omega field."
+            << "Needs either epsilon or omega field."
             << abort(FatalError);
     }
 
diff --git a/src/finiteArea/finiteArea/lnGradSchemes/uncorrectedLnGrad/uncorrectedLnGrad.C b/src/finiteArea/finiteArea/lnGradSchemes/uncorrectedLnGrad/uncorrectedLnGrad.C
index 19b6641e575..ccc3155a1a0 100644
--- a/src/finiteArea/finiteArea/lnGradSchemes/uncorrectedLnGrad/uncorrectedLnGrad.C
+++ b/src/finiteArea/finiteArea/lnGradSchemes/uncorrectedLnGrad/uncorrectedLnGrad.C
@@ -49,7 +49,7 @@ uncorrectedLnGrad<Type>::correction
 ) const
 {
     NotImplemented;
-    return tmp<GeometricField<Type, faePatchField, edgeMesh>>(nullptr);
+    return nullptr;
 }
 
 
diff --git a/src/finiteVolume/cfdTools/general/constrainHbyA/constrainHbyA.C b/src/finiteVolume/cfdTools/general/constrainHbyA/constrainHbyA.C
index 61c1f89de58..4b56ed40963 100644
--- a/src/finiteVolume/cfdTools/general/constrainHbyA/constrainHbyA.C
+++ b/src/finiteVolume/cfdTools/general/constrainHbyA/constrainHbyA.C
@@ -40,18 +40,18 @@ Foam::tmp<Foam::volVectorField> Foam::constrainHbyA
 {
     tmp<volVectorField> tHbyANew;
 
-    if (tHbyA.isTmp())
+    if (tHbyA.movable())
     {
         tHbyANew = tHbyA;
         tHbyANew.ref().rename("HbyA");
     }
     else
     {
-        tHbyANew = new volVectorField("HbyA", tHbyA);
+        // Clone and use given name
+        tHbyANew.reset(new volVectorField("HbyA", tHbyA));
     }
 
-    volVectorField& HbyA = tHbyANew.ref();
-    volVectorField::Boundary& HbyAbf = HbyA.boundaryFieldRef();
+    auto& HbyAbf = tHbyANew.ref().boundaryFieldRef();
 
     forAll(U.boundaryField(), patchi)
     {
diff --git a/src/finiteVolume/finiteVolume/snGradSchemes/orthogonalSnGrad/orthogonalSnGrad.C b/src/finiteVolume/finiteVolume/snGradSchemes/orthogonalSnGrad/orthogonalSnGrad.C
index 64380af3add..4ee99b4adce 100644
--- a/src/finiteVolume/finiteVolume/snGradSchemes/orthogonalSnGrad/orthogonalSnGrad.C
+++ b/src/finiteVolume/finiteVolume/snGradSchemes/orthogonalSnGrad/orthogonalSnGrad.C
@@ -50,7 +50,7 @@ orthogonalSnGrad<Type>::correction
 ) const
 {
     NotImplemented;
-    return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>(nullptr);
+    return nullptr;
 }
 
 
diff --git a/src/finiteVolume/finiteVolume/snGradSchemes/snGradScheme/snGradScheme.H b/src/finiteVolume/finiteVolume/snGradSchemes/snGradScheme/snGradScheme.H
index d19a63bf3fe..b460f0a9a84 100644
--- a/src/finiteVolume/finiteVolume/snGradSchemes/snGradScheme/snGradScheme.H
+++ b/src/finiteVolume/finiteVolume/snGradSchemes/snGradScheme/snGradScheme.H
@@ -172,15 +172,11 @@ public:
             return false;
         }
 
-        //- Return the explicit correction to the snGrad
-        //- for the given field
+        //- Return the explicit correction to the snGrad for the given field
         virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
         correction(const GeometricField<Type, fvPatchField, volMesh>&) const
         {
-            return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-            (
-                nullptr
-            );
+            return nullptr;
         }
 
         //- Return the snGrad of the given cell field
diff --git a/src/finiteVolume/finiteVolume/snGradSchemes/uncorrectedSnGrad/uncorrectedSnGrad.C b/src/finiteVolume/finiteVolume/snGradSchemes/uncorrectedSnGrad/uncorrectedSnGrad.C
index 793e16a563d..ea5a36dd869 100644
--- a/src/finiteVolume/finiteVolume/snGradSchemes/uncorrectedSnGrad/uncorrectedSnGrad.C
+++ b/src/finiteVolume/finiteVolume/snGradSchemes/uncorrectedSnGrad/uncorrectedSnGrad.C
@@ -50,7 +50,7 @@ uncorrectedSnGrad<Type>::correction
 ) const
 {
     NotImplemented;
-    return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>(nullptr);
+    return nullptr;
 }
 
 
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CoBlended/CoBlended.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CoBlended/CoBlended.H
index fd7f661afbf..9e41919ab4b 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CoBlended/CoBlended.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CoBlended/CoBlended.H
@@ -315,10 +315,7 @@ public:
             }
             else
             {
-                return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-                (
-                    nullptr
-                );
+                return nullptr;
             }
         }
 };
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cellCoBlended/cellCoBlended.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cellCoBlended/cellCoBlended.H
index d9ca8e77a32..123ab26b0f2 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cellCoBlended/cellCoBlended.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cellCoBlended/cellCoBlended.H
@@ -342,10 +342,7 @@ public:
             }
             else
             {
-                return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-                (
-                    nullptr
-                );
+                return nullptr;
             }
         }
 };
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/fixedBlended/fixedBlended.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/fixedBlended/fixedBlended.H
index 92b6f83e11c..4c706f02011 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/fixedBlended/fixedBlended.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/fixedBlended/fixedBlended.H
@@ -242,10 +242,7 @@ public:
             }
             else
             {
-                return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-                (
-                    nullptr
-                );
+                return nullptr;
             }
         }
 
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/limiterBlended/limiterBlended.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/limiterBlended/limiterBlended.H
index cfa6d0e603c..f040a92dcd4 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/limiterBlended/limiterBlended.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/limiterBlended/limiterBlended.H
@@ -222,10 +222,7 @@ public:
             }
             else
             {
-                return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-                (
-                    nullptr
-                );
+                return nullptr;
             }
         }
 };
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/localBlended/localBlended.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/localBlended/localBlended.H
index 3ee9a60be00..55892b91b21 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/localBlended/localBlended.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/localBlended/localBlended.H
@@ -234,10 +234,7 @@ public:
             }
             else
             {
-                return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-                (
-                    nullptr
-                );
+                return nullptr;
             }
         }
 };
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/outletStabilised/outletStabilised.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/outletStabilised/outletStabilised.H
index 91f283d4a74..381ab0cc03e 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/outletStabilised/outletStabilised.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/outletStabilised/outletStabilised.H
@@ -238,10 +238,7 @@ public:
             }
             else
             {
-                return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-                (
-                    nullptr
-                );
+                return nullptr;
             }
         }
 };
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolationScheme/surfaceInterpolationScheme.H b/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolationScheme/surfaceInterpolationScheme.H
index 53ec747eb3f..14c6d7ba00e 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolationScheme/surfaceInterpolationScheme.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolationScheme/surfaceInterpolationScheme.H
@@ -203,10 +203,7 @@ public:
         virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
         correction(const GeometricField<Type, fvPatchField, volMesh>&) const
         {
-            return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-            (
-                nullptr
-            );
+            return nullptr;
         }
 
         //- Return the face-interpolate of the given cell field
diff --git a/src/lagrangian/turbulence/submodels/Kinematic/DispersionModel/DispersionRASModel/DispersionRASModel.C b/src/lagrangian/turbulence/submodels/Kinematic/DispersionModel/DispersionRASModel/DispersionRASModel.C
index acc0a9f0702..2917c7d132d 100644
--- a/src/lagrangian/turbulence/submodels/Kinematic/DispersionModel/DispersionRASModel/DispersionRASModel.C
+++ b/src/lagrangian/turbulence/submodels/Kinematic/DispersionModel/DispersionRASModel/DispersionRASModel.C
@@ -98,8 +98,8 @@ Foam::DispersionRASModel<CloudType>::DispersionRASModel
 :
     DispersionModel<CloudType>(owner),
     kPtr_(nullptr),
-    ownK_(false),
     epsilonPtr_(nullptr),
+    ownK_(false),
     ownEpsilon_(false)
 {}
 
@@ -112,8 +112,8 @@ Foam::DispersionRASModel<CloudType>::DispersionRASModel
 :
     DispersionModel<CloudType>(dm),
     kPtr_(dm.kPtr_),
-    ownK_(dm.ownK_),
     epsilonPtr_(dm.epsilonPtr_),
+    ownK_(dm.ownK_),
     ownEpsilon_(dm.ownEpsilon_)
 {
     dm.ownK_ = false;
@@ -138,20 +138,22 @@ void Foam::DispersionRASModel<CloudType>::cacheFields(const bool store)
     if (store)
     {
         tmp<volScalarField> tk = this->kModel();
-        if (tk.isTmp())
+        if (tk.movable())
         {
+            // Take ownership
             kPtr_ = tk.ptr();
             ownK_ = true;
         }
         else
         {
-            kPtr_ = &tk();
+            kPtr_ = &tk.cref();
             ownK_ = false;
         }
 
         tmp<volScalarField> tepsilon = this->epsilonModel();
-        if (tepsilon.isTmp())
+        if (tepsilon.movable())
         {
+            // Take ownership
             epsilonPtr_ = tepsilon.ptr();
             ownEpsilon_ = true;
         }
@@ -163,12 +165,12 @@ void Foam::DispersionRASModel<CloudType>::cacheFields(const bool store)
     }
     else
     {
-        if (ownK_ && kPtr_)
+        if (ownK_)
         {
             deleteDemandDrivenData(kPtr_);
             ownK_ = false;
         }
-        if (ownEpsilon_ && epsilonPtr_)
+        if (ownEpsilon_)
         {
             deleteDemandDrivenData(epsilonPtr_);
             ownEpsilon_ = false;
diff --git a/src/lagrangian/turbulence/submodels/Kinematic/DispersionModel/DispersionRASModel/DispersionRASModel.H b/src/lagrangian/turbulence/submodels/Kinematic/DispersionModel/DispersionRASModel/DispersionRASModel.H
index a99a3e5c182..cbe84a7c5f3 100644
--- a/src/lagrangian/turbulence/submodels/Kinematic/DispersionModel/DispersionRASModel/DispersionRASModel.H
+++ b/src/lagrangian/turbulence/submodels/Kinematic/DispersionModel/DispersionRASModel/DispersionRASModel.H
@@ -60,13 +60,13 @@ protected:
             //- Turbulence k
             const volScalarField* kPtr_;
 
-            //- Take ownership of the k field
-            mutable bool ownK_;
-
             //- Turbulence epsilon
             const volScalarField* epsilonPtr_;
 
-            //- Take ownership of the epsilon field
+            //- Local ownership of the k field
+            mutable bool ownK_;
+
+            //- Local ownership of the epsilon field
             mutable bool ownEpsilon_;
 
 
diff --git a/src/lagrangian/turbulence/submodels/Thermodynamic/ParticleForces/BrownianMotion/BrownianMotionForce.C b/src/lagrangian/turbulence/submodels/Thermodynamic/ParticleForces/BrownianMotion/BrownianMotionForce.C
index 2f65c0cef98..adf38116963 100644
--- a/src/lagrangian/turbulence/submodels/Thermodynamic/ParticleForces/BrownianMotion/BrownianMotionForce.C
+++ b/src/lagrangian/turbulence/submodels/Thermodynamic/ParticleForces/BrownianMotion/BrownianMotionForce.C
@@ -77,8 +77,8 @@ Foam::BrownianMotionForce<CloudType>::BrownianMotionForce
     ParticleForce<CloudType>(owner, mesh, dict, typeName, true),
     rndGen_(owner.rndGen()),
     lambda_(this->coeffs().getScalar("lambda")),
-    turbulence_(this->coeffs().getBool("turbulence")),
     kPtr_(nullptr),
+    turbulence_(this->coeffs().getBool("turbulence")),
     ownK_(false)
 {}
 
@@ -92,8 +92,8 @@ Foam::BrownianMotionForce<CloudType>::BrownianMotionForce
     ParticleForce<CloudType>(bmf),
     rndGen_(bmf.rndGen_),
     lambda_(bmf.lambda_),
-    turbulence_(bmf.turbulence_),
     kPtr_(nullptr),
+    turbulence_(bmf.turbulence_),
     ownK_(false)
 {}
 
@@ -102,7 +102,9 @@ Foam::BrownianMotionForce<CloudType>::BrownianMotionForce
 
 template<class CloudType>
 Foam::BrownianMotionForce<CloudType>::~BrownianMotionForce()
-{}
+{
+    cacheFields(false);
+}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -115,20 +117,21 @@ void Foam::BrownianMotionForce<CloudType>::cacheFields(const bool store)
         if (store)
         {
             tmp<volScalarField> tk = kModel();
-            if (tk.isTmp())
+            if (tk.movable())
             {
+                // Take ownership
                 kPtr_ = tk.ptr();
                 ownK_ = true;
             }
             else
             {
-                kPtr_ = &tk();
+                kPtr_ = &tk.cref();
                 ownK_ = false;
             }
         }
         else
         {
-            if (ownK_ && kPtr_)
+            if (ownK_)
             {
                 deleteDemandDrivenData(kPtr_);
                 ownK_ = false;
diff --git a/src/lagrangian/turbulence/submodels/Thermodynamic/ParticleForces/BrownianMotion/BrownianMotionForce.H b/src/lagrangian/turbulence/submodels/Thermodynamic/ParticleForces/BrownianMotion/BrownianMotionForce.H
index 9405a4473da..57bbbdfdb2b 100644
--- a/src/lagrangian/turbulence/submodels/Thermodynamic/ParticleForces/BrownianMotion/BrownianMotionForce.H
+++ b/src/lagrangian/turbulence/submodels/Thermodynamic/ParticleForces/BrownianMotion/BrownianMotionForce.H
@@ -65,7 +65,7 @@ class BrownianMotionForce
 :
     public ParticleForce<CloudType>
 {
-    // Private data
+    // Private Data
 
         //- Reference to the cloud random number generator
         Random& rndGen_;
@@ -73,13 +73,13 @@ class BrownianMotionForce
         //- Molecular free path length [m]
         const scalar lambda_;
 
-        //- Turbulence flag
-        bool turbulence_;
-
         //- Pointer to the turbulence kinetic energy field
         const volScalarField* kPtr_;
 
-        //- Flag that indicates ownership of turbulence k field
+        //- Turbulence flag
+        bool turbulence_;
+
+        //- Local ownership of the turbulence k field
         bool ownK_;
 
 
-- 
GitLab