From e5c3e7de75e612283a1274be36bca540d34817f8 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Fri, 12 Oct 2018 18:58:28 +0200
Subject: [PATCH] ENH: COMP: handle compiler ambiguities for tmp vs movable
 references

- seen with gcc-4.9.4, but not with gcc-7

- provide additional constructors from tmp for DimensionedField, FieldField
---
 .../DimensionedField/DimensionedField.C       | 90 ++++++++++++-------
 .../DimensionedField/DimensionedField.H       | 71 +++++++++------
 .../DimensionedField/DimensionedFieldIO.C     |  5 +-
 .../FieldFields/FieldField/FieldField.C       | 77 +++++++++++-----
 .../FieldFields/FieldField/FieldField.H       | 40 ++++++---
 .../GeometricField/GeometricBoundaryField.C   | 49 +++-------
 .../GeometricField/GeometricField.C           | 46 ++++++++++
 .../GeometricField/GeometricField.H           | 30 +++++--
 8 files changed, 270 insertions(+), 138 deletions(-)

diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C
index 09e89bc28a9..94d80dea5c1 100644
--- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C
+++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C
@@ -120,6 +120,26 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 }
 
 
+template<class Type, class GeoMesh>
+Foam::DimensionedField<Type, GeoMesh>::DimensionedField
+(
+    const IOobject& io,
+    const Mesh& mesh,
+    const dimensionSet& dims,
+    const tmp<Field<Type>>& tfield
+)
+:
+    regIOobject(io),
+    Field<Type>(tfield.constCast(), tfield.movable()),
+    mesh_(mesh),
+    dimensions_(dims),
+    oriented_()
+{
+    tfield.clear();
+    checkFieldSize();
+}
+
+
 template<class Type, class GeoMesh>
 Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 (
@@ -181,26 +201,22 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 template<class Type, class GeoMesh>
 Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 (
-    DimensionedField<Type, GeoMesh>& df,
-    bool reuse
+    DimensionedField<Type, GeoMesh>&& df
 )
 :
-    regIOobject(df, reuse),
-    Field<Type>(df, reuse),
-    mesh_(df.mesh_),
-    dimensions_(df.dimensions_),
-    oriented_(df.oriented_)
+    DimensionedField<Type, GeoMesh>(df, true)
 {}
 
 
 template<class Type, class GeoMesh>
 Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 (
-    DimensionedField<Type, GeoMesh>&& df
+    DimensionedField<Type, GeoMesh>& df,
+    bool reuse
 )
 :
-    regIOobject(df, true),
-    Field<Type>(std::move(df)),
+    regIOobject(df, reuse),
+    Field<Type>(df, reuse),
     mesh_(df.mesh_),
     dimensions_(df.dimensions_),
     oriented_(df.oriented_)
@@ -214,11 +230,7 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField
     const tmp<DimensionedField<Type, GeoMesh>>& tdf
 )
 :
-    regIOobject(tdf.constCast(), tdf.movable()),
-    Field<Type>(tdf.constCast(), tdf.movable()),
-    mesh_(tdf().mesh_),
-    dimensions_(tdf().dimensions_),
-    oriented_(tdf().oriented_)
+    DimensionedField<Type, GeoMesh>(tdf.constCast(), tdf.movable())
 {
     tdf.clear();
 }
@@ -240,6 +252,17 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 {}
 
 
+template<class Type, class GeoMesh>
+Foam::DimensionedField<Type, GeoMesh>::DimensionedField
+(
+    const IOobject& io,
+    DimensionedField<Type, GeoMesh>&& df
+)
+:
+    DimensionedField<Type, GeoMesh>(io, df, true)
+{}
+
+
 template<class Type, class GeoMesh>
 Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 (
@@ -256,6 +279,21 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 {}
 
 
+#ifndef NoConstructFromTmp
+template<class Type, class GeoMesh>
+Foam::DimensionedField<Type, GeoMesh>::DimensionedField
+(
+    const IOobject& io,
+    const tmp<DimensionedField<Type, GeoMesh>>& tdf
+)
+:
+    DimensionedField<Type, GeoMesh>(io, tdf.constCast(), tdf.movable())
+{
+    tdf.clear();
+}
+#endif
+
+
 template<class Type, class GeoMesh>
 Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 (
@@ -275,15 +313,10 @@ template<class Type, class GeoMesh>
 Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 (
     const word& newName,
-    DimensionedField<Type, GeoMesh>& df,
-    bool reuse
+    DimensionedField<Type, GeoMesh>&& df
 )
 :
-    regIOobject(newName, df, true),
-    Field<Type>(df, reuse),
-    mesh_(df.mesh_),
-    dimensions_(df.dimensions_),
-    oriented_(df.oriented_)
+    DimensionedField<Type, GeoMesh>(newName, df, true)
 {}
 
 
@@ -291,11 +324,12 @@ template<class Type, class GeoMesh>
 Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 (
     const word& newName,
-    DimensionedField<Type, GeoMesh>&& df
+    DimensionedField<Type, GeoMesh>& df,
+    bool reuse
 )
 :
     regIOobject(newName, df, true),
-    Field<Type>(std::move(df)),
+    Field<Type>(df, reuse),
     mesh_(df.mesh_),
     dimensions_(df.dimensions_),
     oriented_(df.oriented_)
@@ -310,11 +344,7 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField
     const tmp<DimensionedField<Type, GeoMesh>>& tdf
 )
 :
-    regIOobject(newName, tdf(), true),
-    Field<Type>(tdf.constCast(), tdf.movable()),
-    mesh_(tdf().mesh_),
-    dimensions_(tdf().dimensions_),
-    oriented_(tdf().oriented_)
+    DimensionedField<Type, GeoMesh>(newName, tdf.constCast(), tdf.movable())
 {
     tdf.clear();
 }
@@ -356,7 +386,7 @@ Foam::DimensionedField<Type, GeoMesh>::component
         dimensions_
     );
 
-    Foam::component(tresult(), *this, d);
+    Foam::component(tresult.ref(), *this, d);
 
     return tresult;
 }
diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H
index 23d721f2030..6bebd04c8b1 100644
--- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H
+++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H
@@ -48,17 +48,18 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declaration of friend functions and operators
-
+// Forward declarations
 template<class Type, class GeoMesh> class DimensionedField;
 
-template<class Type, class GeoMesh> Ostream& operator<<
+template<class Type, class GeoMesh>
+Ostream& operator<<
 (
     Ostream& os,
     const DimensionedField<Type, GeoMesh>& df
 );
 
-template<class Type, class GeoMesh> Ostream& operator<<
+template<class Type, class GeoMesh>
+Ostream& operator<<
 (
     Ostream& os,
     const tmp<DimensionedField<Type, GeoMesh>>& tdf
@@ -152,6 +153,15 @@ public:
             List<Type>&& field
         );
 
+        //- Construct from components, copy or transfer tmp content
+        DimensionedField
+        (
+            const IOobject& io,
+            const Mesh& mesh,
+            const dimensionSet& dims,
+            const tmp<Field<Type>>& tfield
+        );
+
         //- Construct from components, setting the initial size and assigning
         //- the dimensions, but not initialising any field values.
         //  Used for temporary fields which are initialised after construction
@@ -192,25 +202,15 @@ public:
         );
 
         //- Copy construct
-        DimensionedField
-        (
-            const DimensionedField<Type, GeoMesh>& df
-        );
-
-        //- Copy construct or reuse (move) as specified.
-        DimensionedField
-        (
-            DimensionedField<Type, GeoMesh>& df,
-            bool reuse
-        );
+        DimensionedField(const DimensionedField<Type, GeoMesh>& df);
 
         //- Move construct
-        explicit DimensionedField
-        (
-            DimensionedField<Type, GeoMesh>&& df
-        );
+        DimensionedField(DimensionedField<Type, GeoMesh>&& df);
+
+        //- Copy construct or reuse (move) as specified.
+        DimensionedField(DimensionedField<Type, GeoMesh>& df, bool reuse);
 
-        //- Construct as copy of tmp<DimensionedField> deleting argument
+        //- Construct from tmp\<DimensionedField\> deleting argument
         #ifndef NoConstructFromTmp
         DimensionedField
         (
@@ -225,6 +225,13 @@ public:
             const DimensionedField<Type, GeoMesh>& df
         );
 
+        //- Move construct, resetting IO parameters
+        DimensionedField
+        (
+            const IOobject& io,
+            DimensionedField<Type, GeoMesh>&& df
+        );
+
         //- Copy or move construct, resetting IO parameters.
         DimensionedField
         (
@@ -233,19 +240,21 @@ public:
             bool reuse
         );
 
-        //- Copy construct, resetting name
+        //- Construct from tmp\<DimensionedField\> deleting argument,
+        //- resetting IO parameters.
+        #ifndef NoConstructFromTmp
         DimensionedField
         (
-            const word& newName,
-            const DimensionedField<Type, GeoMesh>& df
+            const IOobject& io,
+            const tmp<DimensionedField<Type, GeoMesh>>& tdf
         );
+        #endif
 
-        //- Copy or move construct, resetting name.
+        //- Copy construct with a new name
         DimensionedField
         (
             const word& newName,
-            DimensionedField<Type, GeoMesh>& df,
-            bool reuse
+            const DimensionedField<Type, GeoMesh>& df
         );
 
         //- Move construct with a new name
@@ -255,7 +264,15 @@ public:
             DimensionedField<Type, GeoMesh>&& df
         );
 
-        //- Construct as copy resetting name
+        //- Copy or move construct, resetting name.
+        DimensionedField
+        (
+            const word& newName,
+            DimensionedField<Type, GeoMesh>& df,
+            bool reuse
+        );
+
+        //- Construct with a new name from tmp\<DimensionedField\>
         #ifndef NoConstructFromTmp
         DimensionedField
         (
diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C
index 612785cdfc2..cb1895f5258 100644
--- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C
+++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C
@@ -26,7 +26,6 @@ License
 #include "DimensionedField.H"
 #include "IOstreams.H"
 
-
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class Type, class GeoMesh>
@@ -81,7 +80,7 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 )
 :
     regIOobject(io),
-    Field<Type>(0),
+    Field<Type>(),
     mesh_(mesh),
     dimensions_(dimless),
     oriented_()
@@ -100,7 +99,7 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField
 )
 :
     regIOobject(io),
-    Field<Type>(0),
+    Field<Type>(),
     mesh_(mesh),
     dimensions_(dimless),
     oriented_()
diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C
index ad98f6a02f1..f7292276004 100644
--- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C
+++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C
@@ -132,24 +132,37 @@ FieldField<Field, Type>::FieldField
 
 
 template<template<class> class Field, class Type>
-FieldField<Field, Type>::FieldField(const FieldField<Field, Type>& f)
+FieldField<Field, Type>::FieldField(const FieldField<Field, Type>& ff)
 :
-    refCount(),
-    PtrList<Field<Type>>(f)
+    PtrList<Field<Type>>(ff)
 {}
 
 
 template<template<class> class Field, class Type>
-FieldField<Field, Type>::FieldField(FieldField<Field, Type>& f, bool reuse)
+FieldField<Field, Type>::FieldField(FieldField<Field, Type>&& ff)
 :
-    PtrList<Field<Type>>(f, reuse)
+    PtrList<Field<Type>>(std::move(ff))
 {}
 
 
 template<template<class> class Field, class Type>
-FieldField<Field, Type>::FieldField(const PtrList<Field<Type>>& tl)
+FieldField<Field, Type>::FieldField(FieldField<Field, Type>& ff, bool reuse)
 :
-    PtrList<Field<Type>>(tl)
+    PtrList<Field<Type>>(ff, reuse)
+{}
+
+
+template<template<class> class Field, class Type>
+FieldField<Field, Type>::FieldField(const PtrList<Field<Type>>& list)
+:
+    PtrList<Field<Type>>(list)
+{}
+
+
+template<template<class> class Field, class Type>
+FieldField<Field, Type>::FieldField(PtrList<Field<Type>>&& list)
+:
+    PtrList<Field<Type>>(std::move(list))
 {}
 
 
@@ -185,17 +198,17 @@ tmp<FieldField<Field, Type>> FieldField<Field, Type>::NewCalculatedType
     const FieldField<Field, Type2>& ff
 )
 {
-    FieldField<Field, Type>* nffPtr
-    (
-        new FieldField<Field, Type>(ff.size())
-    );
+    const label len = ff.size();
+
+    auto tresult = tmp<FieldField<Field, Type>>::New(len);
+    auto& result = tresult.ref();
 
-    forAll(*nffPtr, i)
+    for (label i=0; i<len; ++i)
     {
-        nffPtr->set(i, Field<Type>::NewCalculatedType(ff[i]).ptr());
+        result.set(i, Field<Type>::NewCalculatedType(ff[i]).ptr());
     }
 
-    return tmp<FieldField<Field, Type>>(nffPtr);
+    return tresult;
 }
 
 
@@ -261,13 +274,13 @@ void FieldField<Field, Type>::replace
 template<template<class> class Field, class Type>
 tmp<FieldField<Field, Type>> FieldField<Field, Type>::T() const
 {
-    tmp<FieldField<Field, Type>> transpose
+    auto tresult
     (
         FieldField<Field, Type>::NewCalculatedType(*this)
     );
 
-    ::Foam::T(transpose.ref(), *this);
-    return transpose;
+    ::Foam::T(tresult.ref(), *this);
+    return tresult;
 }
 
 
@@ -282,6 +295,7 @@ void FieldField<Field, Type>::operator=(const FieldField<Field, Type>& f)
             << "attempted assignment to self"
             << abort(FatalError);
     }
+    // No size checking done
 
     forAll(*this, i)
     {
@@ -290,20 +304,39 @@ void FieldField<Field, Type>::operator=(const FieldField<Field, Type>& f)
 }
 
 
+template<template<class> class Field, class Type>
+void FieldField<Field, Type>::operator=(FieldField<Field, Type>&& ff)
+{
+    if (this == &ff)
+    {
+        FatalErrorInFunction
+            << "attempted assignment to self"
+            << abort(FatalError);
+    }
+
+    PtrList<Field<Type>>::transfer(ff);
+}
+
+
 template<template<class> class Field, class Type>
 void FieldField<Field, Type>::operator=(const tmp<FieldField>& tf)
 {
-    if (this == &(tf()))
+    // The cref() method also checks that tmp is not nullptr.
+    if (this == &(tf.cref()))
     {
         FatalErrorInFunction
             << "attempted assignment to self"
             << abort(FatalError);
     }
 
-    // This is dodgy stuff, don't try this at home.
-    FieldField* fieldPtr = tf.ptr();
-    PtrList<Field<Type>>::transfer(*fieldPtr);
-    delete fieldPtr;
+    PtrList<Field<Type>>::clear();
+
+    // Release the tmp pointer, or clone const reference for a new pointer.
+    // Error potential when tmp is non-unique.
+
+    auto* tptr = tf.ptr();
+    PtrList<Field<Type>>::transfer(*tptr);
+    delete tptr;
 }
 
 
diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H
index bae0375b681..690e1df64be 100644
--- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H
+++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H
@@ -25,7 +25,7 @@ Class
     Foam::FieldField
 
 Description
-    Generic field type.
+    A field of fields is a PtrList of fields with reference counting.
 
 SourceFiles
     FieldField.C
@@ -91,29 +91,33 @@ public:
 
         //- Construct given size
         //  Used for temporary fields which are initialised after construction
-        explicit FieldField(const label);
+        explicit FieldField(const label size);
 
-        //- Construct using the Field sizes from the given FieldField
-        //  and the given Field type.
-        //  Used for temporary fields which are initialised after construction
-        FieldField(const word&, const FieldField<Field, Type>&);
+        //- Clone construct with new type
+        FieldField(const word& type, const FieldField<Field, Type>& ff);
+
+        //- Copy construct, cloning each element
+        FieldField(const FieldField<Field, Type>& ff);
 
-        //- Construct as copy
-        FieldField(const FieldField<Field, Type>&);
+        //- Move construct
+        FieldField(FieldField<Field, Type>&& ff);
 
         //- Construct as copy or re-use as specified.
-        FieldField(FieldField<Field, Type>&, bool reuse);
+        FieldField(FieldField<Field, Type>& ff, bool reuse);
+
+        //- Copy construct from PtrList
+        FieldField(const PtrList<Field<Type>>& list);
 
-        //- Construct as copy of a PtrList<Field, Type>
-        FieldField(const PtrList<Field<Type>>&);
+        //- Move construct from PtrList
+        FieldField(PtrList<Field<Type>>&& list);
 
-        //- Construct as copy of tmp<FieldField>
+        //- Move/copy construct from tmp<FieldField>
         #ifndef NoConstructFromTmp
-        FieldField(const tmp<FieldField<Field, Type>>&);
+        FieldField(const tmp<FieldField<Field, Type>>& tf);
         #endif
 
         //- Construct from Istream
-        FieldField(Istream&);
+        FieldField(Istream& is);
 
         //- Clone
         tmp<FieldField<Field, Type>> clone() const;
@@ -147,8 +151,16 @@ public:
 
     // Member operators
 
+        //- Copy assignment
         void operator=(const FieldField<Field, Type>&);
+
+        //- Move assignment
+        void operator=(FieldField<Field, Type>&&);
+
+        //- Move or clone assignment
         void operator=(const tmp<FieldField<Field, Type>>&);
+
+        //- Assign uniform value
         void operator=(const Type&);
 
         void operator+=(const FieldField<Field, Type>&);
diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C
index ee127be2788..2ebf52925c7 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C
@@ -36,17 +36,13 @@ readField
     const dictionary& dict
 )
 {
+    DebugInFunction << nl;
+
     // Clear the boundary field if already initialised
     this->clear();
 
     this->setSize(bmesh_.size());
 
-    if (debug)
-    {
-        InfoInFunction << endl;
-    }
-
-
     label nUnset = this->size();
 
     // 1. Handle explicit patch names. Note that there can be only one explicit
@@ -217,10 +213,7 @@ Boundary
     FieldField<PatchField, Type>(bmesh.size()),
     bmesh_(bmesh)
 {
-    if (debug)
-    {
-        InfoInFunction << endl;
-    }
+    DebugInFunction << nl;
 
     forAll(bmesh_, patchi)
     {
@@ -251,10 +244,7 @@ Boundary
     FieldField<PatchField, Type>(bmesh.size()),
     bmesh_(bmesh)
 {
-    if (debug)
-    {
-        InfoInFunction << endl;
-    }
+    DebugInFunction << nl;
 
     if
     (
@@ -318,10 +308,7 @@ Boundary
     FieldField<PatchField, Type>(bmesh.size()),
     bmesh_(bmesh)
 {
-    if (debug)
-    {
-        InfoInFunction << endl;
-    }
+    DebugInFunction << nl;
 
     forAll(bmesh_, patchi)
     {
@@ -342,10 +329,7 @@ Boundary
     FieldField<PatchField, Type>(btf.size()),
     bmesh_(btf.bmesh_)
 {
-    if (debug)
-    {
-        InfoInFunction << endl;
-    }
+    DebugInFunction << nl;
 
     forAll(bmesh_, patchi)
     {
@@ -365,10 +349,7 @@ Boundary
     FieldField<PatchField, Type>(btf),
     bmesh_(btf.bmesh_)
 {
-    if (debug)
-    {
-        InfoInFunction << endl;
-    }
+    DebugInFunction << nl;
 }
 
 
@@ -394,10 +375,7 @@ template<class Type, template<class> class PatchField, class GeoMesh>
 void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::
 updateCoeffs()
 {
-    if (debug)
-    {
-        InfoInFunction << endl;
-    }
+    DebugInFunction << nl;
 
     forAll(*this, patchi)
     {
@@ -410,10 +388,7 @@ template<class Type, template<class> class PatchField, class GeoMesh>
 void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary::
 evaluate()
 {
-    if (debug)
-    {
-        InfoInFunction << endl;
-    }
+    DebugInFunction << nl;
 
     if
     (
@@ -479,14 +454,14 @@ types() const
 {
     const FieldField<PatchField, Type>& pff = *this;
 
-    wordList Types(pff.size());
+    wordList list(pff.size());
 
     forAll(pff, patchi)
     {
-        Types[patchi] = pff[patchi].type();
+        list[patchi] = pff[patchi].type();
     }
 
-    return Types;
+    return list;
 }
 
 
diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C
index e7a088c522e..df75d2ac64f 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C
@@ -304,6 +304,52 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
 }
 
 
+template<class Type, template<class> class PatchField, class GeoMesh>
+Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
+(
+    const IOobject& io,
+    const Mesh& mesh,
+    const dimensionSet& ds,
+    const Field<Type>& iField,
+    const word& patchFieldType
+)
+:
+    Internal(io, mesh, ds, iField),
+    timeIndex_(this->time().timeIndex()),
+    field0Ptr_(nullptr),
+    fieldPrevIterPtr_(nullptr),
+    boundaryField_(mesh.boundary(), *this, patchFieldType)
+{
+    DebugInFunction
+        << "Copy construct from internal field" << nl << this->info() << endl;
+
+    readIfPresent();
+}
+
+
+template<class Type, template<class> class PatchField, class GeoMesh>
+Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
+(
+    const IOobject& io,
+    const Mesh& mesh,
+    const dimensionSet& ds,
+    Field<Type>&& iField,
+    const word& patchFieldType
+)
+:
+    Internal(io, mesh, ds, std::move(iField)),
+    timeIndex_(this->time().timeIndex()),
+    field0Ptr_(nullptr),
+    fieldPrevIterPtr_(nullptr),
+    boundaryField_(mesh.boundary(), *this, patchFieldType)
+{
+    DebugInFunction
+        << "Move construct from internal field" << nl << this->info() << endl;
+
+    readIfPresent();
+}
+
+
 template<class Type, template<class> class PatchField, class GeoMesh>
 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
 (
diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
index a7941db125c..d9ac7efa0ed 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
@@ -180,11 +180,11 @@ public:
             (
                 const BoundaryMesh& bmesh,
                 const Internal& field,
-                const dictionary&
+                const dictionary& dict
             );
 
 
-        // Member functions
+        // Member Functions
 
             //- Read the boundary field
             void readField
@@ -344,6 +344,26 @@ public:
             const PtrList<PatchField<Type>>& ptfl
         );
 
+        //- Copy construct from internal field, with specified patch type
+        GeometricField
+        (
+            const IOobject& io,
+            const Mesh& mesh,
+            const dimensionSet& ds,
+            const Field<Type>& iField,
+            const word& patchFieldType = PatchField<Type>::calculatedType()
+        );
+
+        //- Move construct from internal field, with specified patch type
+        GeometricField
+        (
+            const IOobject& io,
+            const Mesh& mesh,
+            const dimensionSet& ds,
+            Field<Type>&& iField,
+            const word& patchFieldType = PatchField<Type>::calculatedType()
+        );
+
         //- Copy construct from components
         GeometricField
         (
@@ -376,7 +396,7 @@ public:
             const GeometricField<Type, PatchField, GeoMesh>& gf
         );
 
-        //- Construct as copy of tmp<GeometricField> deleting argument
+        //- Construct from tmp\<GeometricField\> deleting argument
         #ifndef NoConstructFromTmp
         GeometricField
         (
@@ -400,14 +420,14 @@ public:
         );
         #endif
 
-        //- Construct as copy resetting name
+        //- Copy construct with a new name
         GeometricField
         (
             const word& newName,
             const GeometricField<Type, PatchField, GeoMesh>& gf
         );
 
-        //- Construct as copy resetting name
+        //- Construct with a new name from tmp\<GeometricField\>
         #ifndef NoConstructFromTmp
         GeometricField
         (
-- 
GitLab