diff --git a/src/OpenFOAM/fields/Fields/Field/PrecisionAdaptor/PrecisionAdaptor.H b/src/OpenFOAM/fields/Fields/Field/PrecisionAdaptor/PrecisionAdaptor.H
index 80f7dbc464f4f2768c7a7a3522f081406b5cce68..0c33ed73886710a1f3a05386e8c326bb444cb180 100644
--- a/src/OpenFOAM/fields/Fields/Field/PrecisionAdaptor/PrecisionAdaptor.H
+++ b/src/OpenFOAM/fields/Fields/Field/PrecisionAdaptor/PrecisionAdaptor.H
@@ -49,28 +49,85 @@ class ConstPrecisionAdaptor
 :
     public tmp<Field<Type>>
 {
+    // Private Member Functions
+
+        //- Copy in field
+        void copyInput(const Field<InputType>& input)
+        {
+            this->clear();
+
+            Field<Type>* p = new Field<Type>(input.size());
+            this->reset(p);
+            std::copy(input.cbegin(), input.cend(), p->begin());
+        }
+
+        //- Construct from tmp Field, copy/move as required
+        void moveInput(tmp<Field<InputType>>& input)
+        {
+            if (std::is_same<Type, InputType>::value)
+            {
+                auto& tinput = reinterpret_cast<tmp<FieldType>&>(input);
+
+                if (tinput.isTmp())
+                {
+                    this->clear();
+                    this->swap(tinput);
+                }
+                else
+                {
+                    this->cref(tinput.cref());
+                }
+            }
+            else
+            {
+                this->copyInput(input());
+            }
+            input.clear();
+        }
+
+
 public:
 
+    //- The adapted field type
+    typedef Field<Type> FieldType;
+
+
     // Constructors
 
-        //- Construct from InputType
+        //- Construct from Field<InputType>, copying on input as required
         ConstPrecisionAdaptor(const Field<InputType>& input)
         :
             tmp<Field<Type>>()
         {
             if (std::is_same<Type, InputType>::value)
             {
-                // Set reference - cast for compiler to handle different types
-                this->cref(reinterpret_cast<const Field<Type>&>(input));
+                this->cref(reinterpret_cast<const FieldType&>(input));
             }
             else
             {
-                this->reset(new Field<Type>(input.size()));
-                std::copy(input.cbegin(), input.cend(), this->ref().begin());
+                this->copyInput(input);
             }
         }
 
 
+        //- Construct from tmp Field, copy/move as required
+        ConstPrecisionAdaptor(tmp<Field<InputType>>&& input)
+        :
+            tmp<Field<Type>>()
+        {
+            this->moveInput(input);
+        }
+
+
+        //- Construct from tmp Field, copy/move as required
+        ConstPrecisionAdaptor(const tmp<Field<InputType>>& input)
+        :
+            tmp<Field<Type>>()
+        {
+            this->moveInput(const_cast<tmp<Field<InputType>>&>(input));
+        }
+
+
     // Member Functions
 
         //- Return the field
@@ -82,7 +139,7 @@ public:
         {
             if (std::is_same<Type, InputType>::value)
             {
-                return reinterpret_cast<const Field<Type>&>(input);
+                return reinterpret_cast<const FieldType&>(input);
             }
             else
             {
@@ -106,8 +163,25 @@ class PrecisionAdaptor
         Field<InputType>& ref_;
 
 
+    // Private Member Functions
+
+        //- Copy in field
+        void copyInput(const Field<InputType>& input)
+        {
+            this->clear();
+
+            Field<Type>* p = new Field<Type>(input.size());
+            this->reset(p);
+            std::copy(input.cbegin(), input.cend(), p->begin());
+        }
+
+
 public:
 
+    //- The adapted field type
+    typedef Field<Type> FieldType;
+
+
     // Constructors
 
         //- Construct from Field<InputType>, copying on input as required
@@ -118,13 +192,11 @@ public:
         {
             if (std::is_same<Type, InputType>::value)
             {
-                // Set reference - cast for compiler to handle different types
-                this->cref(reinterpret_cast<const Field<Type>&>(input));
+                this->cref(reinterpret_cast<const FieldType&>(input));
             }
             else
             {
-                this->reset(new Field<Type>(input.size()));
-                std::copy(input.cbegin(), input.cend(), this->ref().begin());
+                this->copyInput(input);
             }
         }
 
@@ -134,11 +206,20 @@ public:
     {
         if (this->isTmp())
         {
-            const Field<Type>& store = this->cref();
+            const FieldType& store = this->cref();
             ref_.resize(store.size());
             std::copy(store.cbegin(), store.cend(), ref_.begin());
         }
     }
+
+
+    // Member Functions
+
+        //- Allow modification without const-ref check
+        FieldType& ref()
+        {
+            return this->constCast();
+        }
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C
index 0184d34ca080c03888f0af841f4d5db970c0b46c..25fc7a8481497e81c3a05630034bff17596b427d 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C
@@ -41,7 +41,7 @@ Foam::solverPerformance Foam::GAMGSolver::solve
 ) const
 {
     PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
-    solveScalarField& psi = tpsi.constCast();
+    solveScalarField& psi = tpsi.ref();
 
     ConstPrecisionAdaptor<solveScalar, scalar> tsource(source);
 
@@ -581,21 +581,16 @@ void Foam::GAMGSolver::solveCoarsestLevel
 {
     const label coarsestLevel = matrixLevels_.size() - 1;
 
-    label coarseComm = matrixLevels_[coarsestLevel].mesh().comm();
+    const label coarseComm = matrixLevels_[coarsestLevel].mesh().comm();
 
     if (directSolveCoarsest_)
     {
-        PrecisionAdaptor<scalar, solveScalar> tcorrField
-        (
-            coarsestCorrField
-        );
+        PrecisionAdaptor<scalar, solveScalar> tcorrField(coarsestCorrField);
+
         coarsestLUMatrixPtr_->solve
         (
-            tcorrField.constCast(),
-            ConstPrecisionAdaptor<scalar, solveScalar>
-            (
-                coarsestSource
-            )()
+            tcorrField.ref(),
+            ConstPrecisionAdaptor<scalar, solveScalar>(coarsestSource)()
         );
     }
     //else if
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C
index 9545b9cf893f8e3e82ced5b3d968d04cceafbff9..65371df01298965fac5a825d9f849f90c3d92bbb 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C
@@ -73,7 +73,7 @@ Foam::solverPerformance Foam::PBiCG::solve
 ) const
 {
     PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
-    solveScalarField& psi = tpsi.constCast();
+    solveScalarField& psi = tpsi.ref();
 
     // --- Setup class containing solver performance data
     solverPerformance solverPerf
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C
index 7ec60707c1bf4d26c394f46bf02f7e3e5fbe78e5..2694a7c757b75dbaf1f4e0d9bfbe87247949ea81 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C
@@ -282,11 +282,9 @@ Foam::solverPerformance Foam::PBiCGStab::solve
 ) const
 {
     PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
-    solveScalarField& psi = tpsi.constCast();
-
     return scalarSolve
     (
-        psi,
+        tpsi.ref(),
         ConstPrecisionAdaptor<solveScalar, scalar>(source)(),
         cmpt
     );
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C
index 5c408d02dae6147db25c9cbaa04d60d6c2d5d6f2..5131df1756b0f9703c3830e3d4537b360697781d 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C
@@ -220,7 +220,7 @@ Foam::solverPerformance Foam::PCG::solve
     PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
     return scalarSolve
     (
-        tpsi.constCast(),
+        tpsi.ref(),
         ConstPrecisionAdaptor<solveScalar, scalar>(source)(),
         cmpt
     );
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
index 47e11f4fdf32d686f5cff2a6a1a3ea1b83899078..65745e6d8742156363808227eae2f9652539b59d 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
@@ -86,7 +86,7 @@ Foam::solverPerformance Foam::smoothSolver::solve
 ) const
 {
     PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
-    solveScalarField& psi = tpsi.constCast();
+    solveScalarField& psi = tpsi.ref();
 
     // Setup class containing solver performance data
     solverPerformance solverPerf(typeName, fieldName_);
diff --git a/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C b/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C
index b7eefba11724b9f669430b6ba6c668d12bd533a1..21f0a4dc2d7fa5dea29b45ab0771c77b5a65b611 100644
--- a/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C
+++ b/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C
@@ -119,7 +119,6 @@ Foam::tmp<Foam::scalarField> Foam::faMatrix<Foam::scalar>::residual() const
     );
 
     ConstPrecisionAdaptor<scalar, solveScalar> tres_s(tres);
-
     addBoundarySource(tres_s.ref());
 
     return tres_s;
diff --git a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
index dec7e4b1f32b27a33b55ad008b7728a5974d86a8..1d37d6d73ce6d645626a6d7f08ebb30ecb7af400 100644
--- a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
+++ b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
@@ -184,7 +184,7 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated
                 bouCoeffsCmpt,
                 interfaces,
                 psiCmpt_ss(),
-                sourceCmpt_ss.constCast(),
+                sourceCmpt_ss.ref(),
                 cmpt
             );
 
@@ -194,7 +194,7 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated
                 bouCoeffsCmpt,
                 interfaces,
                 psiCmpt_ss(),
-                sourceCmpt_ss.constCast(),
+                sourceCmpt_ss.ref(),
                 cmpt
             );
         }
diff --git a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
index 1d15cbb78718ec495c8fe892292856ed6b5f98df..ba5a842267c1d536802b8bbbc2abce7a427e0062 100644
--- a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
+++ b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
@@ -215,8 +215,10 @@ Foam::tmp<Foam::scalarField> Foam::fvMatrix<Foam::scalar>::residual() const
             0
         )
     );
+
     ConstPrecisionAdaptor<scalar, solveScalar> tres_s(tres);
-    addBoundarySource(tres_s.constCast());
+    addBoundarySource(tres_s.ref());
+
     return tres_s;
 }