diff --git a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C
index cc0240be0ba1c2f3b2f8585b3ec60155afe5253e..0edc4f1273fabcf8ab67b1fbdb921dcd30c0da43 100644
--- a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C
+++ b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C
@@ -614,9 +614,12 @@ Foam::sqr(const dimensioned<Type>& dt)
 }
 
 template<class Type>
-Foam::dimensioned<Foam::scalar> Foam::magSqr(const dimensioned<Type>& dt)
+Foam::dimensioned<typename Foam::typeOfMag<Type>::type>
+Foam::magSqr(const dimensioned<Type>& dt)
 {
-    return dimensioned<scalar>
+    typedef typename typeOfMag<Type>::type magType;
+
+    return dimensioned<magType>
     (
         "magSqr(" + dt.name() + ')',
         magSqr(dt.dimensions()),
@@ -625,9 +628,12 @@ Foam::dimensioned<Foam::scalar> Foam::magSqr(const dimensioned<Type>& dt)
 }
 
 template<class Type>
-Foam::dimensioned<Foam::scalar> Foam::mag(const dimensioned<Type>& dt)
+Foam::dimensioned<typename Foam::typeOfMag<Type>::type>
+Foam::mag(const dimensioned<Type>& dt)
 {
-    return dimensioned<scalar>
+    typedef typename typeOfMag<Type>::type magType;
+
+    return dimensioned<magType>
     (
         "mag(" + dt.name() + ')',
         dt.dimensions(),
diff --git a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H
index 2e768cbda56c5fb7dabff8334324b0ef12aa815b..b7bd77bccb7a168827dbd1cecad781a40d4b6136 100644
--- a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H
+++ b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H
@@ -437,10 +437,12 @@ dimensioned<typename outerProduct<Type, Type>::type>
 sqr(const dimensioned<Type>&);
 
 template<class Type>
-dimensioned<scalar> magSqr(const dimensioned<Type>&);
+dimensioned<typename typeOfMag<Type>::type>
+magSqr(const dimensioned<Type>& dt);
 
 template<class Type>
-dimensioned<scalar> mag(const dimensioned<Type>&);
+dimensioned<typename typeOfMag<Type>::type>
+mag(const dimensioned<Type>& dt);
 
 template<class Type>
 dimensioned<Type> cmptMultiply
diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.C
index 2573a39afb2c2775048ddb8ec0b2bd668a325b7e..ae637a741706470ac966a2196f1649fb7187e52f 100644
--- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.C
+++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.C
@@ -141,13 +141,13 @@ sqr(const tmp<DimensionedField<Type, GeoMesh>>& tdf)
 
 
 template<class Type, class GeoMesh>
-tmp<DimensionedField<scalar, GeoMesh>> magSqr
-(
-    const DimensionedField<Type, GeoMesh>& df
-)
+tmp<DimensionedField<typename typeOfMag<Type>::type, GeoMesh>>
+magSqr(const DimensionedField<Type, GeoMesh>& df)
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     auto tres =
-        tmp<DimensionedField<scalar, GeoMesh>>::New
+        tmp<DimensionedField<magType, GeoMesh>>::New
         (
             IOobject
             (
@@ -165,15 +165,15 @@ tmp<DimensionedField<scalar, GeoMesh>> magSqr
 }
 
 template<class Type, class GeoMesh>
-tmp<DimensionedField<scalar, GeoMesh>> magSqr
-(
-    const tmp<DimensionedField<Type, GeoMesh>>& tdf
-)
+tmp<DimensionedField<typename typeOfMag<Type>::type, GeoMesh>>
+magSqr(const tmp<DimensionedField<Type, GeoMesh>>& tdf)
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     const DimensionedField<Type, GeoMesh>& df = tdf();
 
     auto tres =
-        reuseTmpDimensionedField<scalar, Type, GeoMesh>::New
+        reuseTmpDimensionedField<magType, Type, GeoMesh>::New
         (
             tdf,
             "magSqr(" + df.name() + ')',
@@ -188,13 +188,13 @@ tmp<DimensionedField<scalar, GeoMesh>> magSqr
 
 
 template<class Type, class GeoMesh>
-tmp<DimensionedField<scalar, GeoMesh>> mag
-(
-    const DimensionedField<Type, GeoMesh>& df
-)
+tmp<DimensionedField<typename typeOfMag<Type>::type, GeoMesh>>
+mag(const DimensionedField<Type, GeoMesh>& df)
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     auto tres =
-        tmp<DimensionedField<scalar, GeoMesh>>::New
+        tmp<DimensionedField<magType, GeoMesh>>::New
         (
             IOobject
             (
@@ -212,15 +212,15 @@ tmp<DimensionedField<scalar, GeoMesh>> mag
 }
 
 template<class Type, class GeoMesh>
-tmp<DimensionedField<scalar, GeoMesh>> mag
-(
-    const tmp<DimensionedField<Type, GeoMesh>>& tdf
-)
+tmp<DimensionedField<typename typeOfMag<Type>::type, GeoMesh>>
+mag(const tmp<DimensionedField<Type, GeoMesh>>& tdf)
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     const DimensionedField<Type, GeoMesh>& df = tdf();
 
     auto tres =
-        reuseTmpDimensionedField<scalar, Type, GeoMesh>::New
+        reuseTmpDimensionedField<magType, Type, GeoMesh>::New
         (
             tdf,
             "mag(" + df.name() + ')',
@@ -325,11 +325,10 @@ UNARY_REDUCTION_FUNCTION(Type, max, gMax)
 UNARY_REDUCTION_FUNCTION(Type, min, gMin)
 UNARY_REDUCTION_FUNCTION(Type, sum, gSum)
 UNARY_REDUCTION_FUNCTION(Type, average, gAverage)
-
 UNARY_REDUCTION_FUNCTION(MinMax<Type>, minMax, gMinMax)
 UNARY_REDUCTION_FUNCTION(scalarMinMax, minMaxMag, gMinMaxMag)
 
-UNARY_REDUCTION_FUNCTION(scalar, sumMag, gSumMag)
+UNARY_REDUCTION_FUNCTION(typename typeOfMag<Type>::type, sumMag, gSumMag)
 
 #undef UNARY_REDUCTION_FUNCTION
 
diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.H b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.H
index 198aa981eb6a749e2cd2a0dda67f87b5fe779fa3..1b055d94bbcc8300197ecdf47c905fa33fcda9a2 100644
--- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.H
+++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.H
@@ -62,34 +62,29 @@ tmp<DimensionedField<typename outerProduct<Type, Type>::type, GeoMesh>>
 sqr(const tmp<DimensionedField<Type, GeoMesh>>& tdf);
 
 template<class Type, class GeoMesh>
-tmp<DimensionedField<scalar, GeoMesh>> magSqr
-(
-    const DimensionedField<Type, GeoMesh>& df
-);
+tmp<DimensionedField<typename typeOfMag<Type>::type, GeoMesh>>
+magSqr(const DimensionedField<Type, GeoMesh>& df);
 
 template<class Type, class GeoMesh>
-tmp<DimensionedField<scalar, GeoMesh>> magSqr
-(
-    const tmp<DimensionedField<Type, GeoMesh>>& tdf
-);
+tmp<DimensionedField<typename typeOfMag<Type>::type, GeoMesh>>
+magSqr(const tmp<DimensionedField<Type, GeoMesh>>& tdf);
 
 template<class Type, class GeoMesh>
-tmp<DimensionedField<scalar, GeoMesh>> mag
-(
-    const DimensionedField<Type, GeoMesh>& df
-);
+tmp<DimensionedField<typename typeOfMag<Type>::type, GeoMesh>>
+mag(const DimensionedField<Type, GeoMesh>& df);
 
 template<class Type, class GeoMesh>
-tmp<DimensionedField<scalar, GeoMesh>> mag
-(
-    const tmp<DimensionedField<Type, GeoMesh>>& tdf
-);
+tmp<DimensionedField<typename typeOfMag<Type>::type, GeoMesh>>
+mag(const tmp<DimensionedField<Type, GeoMesh>>& tdf);
 
 template<class Type, class GeoMesh>
 tmp
 <
     DimensionedField
-        <typename DimensionedField<Type, GeoMesh>::cmptType, GeoMesh>
+    <
+        typename DimensionedField<Type, GeoMesh>::cmptType,
+        GeoMesh
+    >
 >
 cmptAv(const DimensionedField<Type, GeoMesh>& df);
 
@@ -97,7 +92,10 @@ template<class Type, class GeoMesh>
 tmp
 <
     DimensionedField
-        <typename DimensionedField<Type, GeoMesh>::cmptType, GeoMesh>
+    <
+        typename DimensionedField<Type, GeoMesh>::cmptType,
+        GeoMesh
+    >
 >
 cmptAv(const tmp<DimensionedField<Type, GeoMesh>>& tdf);
 
@@ -123,7 +121,7 @@ UNARY_REDUCTION_FUNCTION(Type, average, gAverage)
 UNARY_REDUCTION_FUNCTION(MinMax<Type>, minMax, gMinMax)
 UNARY_REDUCTION_FUNCTION(scalarMinMax, minMaxMag, gMinMaxMag)
 
-UNARY_REDUCTION_FUNCTION(scalar, sumMag, gSumMag)
+UNARY_REDUCTION_FUNCTION(typename typeOfMag<Type>::type, sumMag, gSumMag)
 
 #undef UNARY_REDUCTION_FUNCTION
 
diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.C b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.C
index 159c223198bbdd3f1289743ba0093ce2a5772d77..2a5abbb551f0a12f1cb6719fd6ae2b6552732820 100644
--- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.C
+++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.C
@@ -158,7 +158,11 @@ sqr(const tmp<FieldField<Field, Type>>& tf)
 
 
 template<template<class> class Field, class Type>
-void magSqr(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f)
+void magSqr
+(
+    FieldField<Field, typename typeOfMag<Type>::type>& sf,
+    const FieldField<Field, Type>& f
+)
 {
     forAll(sf, i)
     {
@@ -167,11 +171,14 @@ void magSqr(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f)
 }
 
 template<template<class> class Field, class Type>
-tmp<FieldField<Field, scalar>> magSqr(const FieldField<Field, Type>& f)
+tmp<FieldField<Field, typename typeOfMag<Type>::type>>
+magSqr(const FieldField<Field, Type>& f)
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     auto tres
     (
-        FieldField<Field, scalar>::NewCalculatedType(f)
+        FieldField<Field, magType>::NewCalculatedType(f)
     );
 
     magSqr(tres.ref(), f);
@@ -179,11 +186,14 @@ tmp<FieldField<Field, scalar>> magSqr(const FieldField<Field, Type>& f)
 }
 
 template<template<class> class Field, class Type>
-tmp<FieldField<Field, scalar>> magSqr(const tmp<FieldField<Field, Type>>& tf)
+tmp<FieldField<Field, typename typeOfMag<Type>::type>>
+magSqr(const tmp<FieldField<Field, Type>>& tf)
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     auto tres
     (
-        reuseTmpFieldField<Field, scalar, Type>::New(tf)
+        reuseTmpFieldField<Field, magType, Type>::New(tf)
     );
 
     magSqr(tres.ref(), tf());
@@ -193,7 +203,11 @@ tmp<FieldField<Field, scalar>> magSqr(const tmp<FieldField<Field, Type>>& tf)
 
 
 template<template<class> class Field, class Type>
-void mag(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f)
+void mag
+(
+    FieldField<Field, typename typeOfMag<Type>::type>& sf,
+    const FieldField<Field, Type>& f
+)
 {
     forAll(sf, i)
     {
@@ -202,11 +216,14 @@ void mag(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f)
 }
 
 template<template<class> class Field, class Type>
-tmp<FieldField<Field, scalar>> mag(const FieldField<Field, Type>& f)
+tmp<FieldField<Field, typename typeOfMag<Type>::type>>
+mag(const FieldField<Field, Type>& f)
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     auto tres
     (
-        FieldField<Field, scalar>::NewCalculatedType(f)
+        FieldField<Field, magType>::NewCalculatedType(f)
     );
 
     mag(tres.ref(), f);
@@ -214,11 +231,14 @@ tmp<FieldField<Field, scalar>> mag(const FieldField<Field, Type>& f)
 }
 
 template<template<class> class Field, class Type>
-tmp<FieldField<Field, scalar>> mag(const tmp<FieldField<Field, Type>>& tf)
+tmp<FieldField<Field, typename typeOfMag<Type>::type>>
+mag(const tmp<FieldField<Field, Type>>& tf)
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     auto tres
     (
-        reuseTmpFieldField<Field, scalar, Type>::New(tf)
+        reuseTmpFieldField<Field, magType, Type>::New(tf)
     );
 
     mag(tres.ref(), tf());
@@ -480,19 +500,21 @@ Type sum(const FieldField<Field, Type>& f)
 TMP_UNARY_FUNCTION(Type, sum)
 
 template<template<class> class Field, class Type>
-scalar sumMag(const FieldField<Field, Type>& f)
+typename typeOfMag<Type>::type sumMag(const FieldField<Field, Type>& f)
 {
-    scalar SumMag = 0.0;
+    typedef typename typeOfMag<Type>::type magType;
+
+    magType result = Zero;
 
     forAll(f, i)
     {
-        SumMag += sumMag(f[i]);
+        result += sumMag(f[i]);
     }
 
-    return SumMag;
+    return result;
 }
 
-TMP_UNARY_FUNCTION(scalar, sumMag)
+TMP_UNARY_FUNCTION(typename typeOfMag<Type>::type, sumMag)
 
 template<template<class> class Field, class Type>
 Type average(const FieldField<Field, Type>& f)
@@ -555,25 +577,24 @@ TMP_UNARY_FUNCTION(scalarMinMax, minMaxMag)
 
 
 // With reduction on ReturnType
-#define G_UNARY_FUNCTION(returnType, gFunc, func, rFunc)                       \
+#define G_UNARY_FUNCTION(ReturnType, gFunc, func, rFunc)                       \
                                                                                \
 template<template<class> class Field, class Type>                              \
-returnType gFunc(const FieldField<Field, Type>& f)                             \
+ReturnType gFunc(const FieldField<Field, Type>& f)                             \
 {                                                                              \
-    returnType res = func(f);                                                  \
-    reduce(res, rFunc##Op<returnType>());                                      \
+    ReturnType res = func(f);                                                  \
+    reduce(res, rFunc##Op<ReturnType>());                                      \
     return res;                                                                \
 }                                                                              \
-TMP_UNARY_FUNCTION(returnType, gFunc)
+TMP_UNARY_FUNCTION(ReturnType, gFunc)
 
 G_UNARY_FUNCTION(Type, gMax, max, max)
 G_UNARY_FUNCTION(Type, gMin, min, min)
 G_UNARY_FUNCTION(Type, gSum, sum, sum)
-
 G_UNARY_FUNCTION(MinMax<Type>, gMinMax, minMax, sum)
 G_UNARY_FUNCTION(scalarMinMax, gMinMaxMag, minMaxMag, sum)
 
-G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum)
+G_UNARY_FUNCTION(typename typeOfMag<Type>::type, gSumMag, sumMag, sum)
 
 #undef G_UNARY_FUNCTION
 
diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.H b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.H
index 18be310352ce226375154977c8980659c2bb9121..9b1dd6b45905bd2fc48654df032150a7532574f2 100644
--- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.H
+++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.H
@@ -90,23 +90,35 @@ sqr(const tmp<FieldField<Field, Type>>& tf);
 
 
 template<template<class> class Field, class Type>
-void magSqr(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f);
+void magSqr
+(
+    FieldField<Field, typename typeOfMag<Type>::type>& sf,
+    const FieldField<Field, Type>& f
+);
 
 template<template<class> class Field, class Type>
-tmp<FieldField<Field, scalar>> magSqr(const FieldField<Field, Type>& f);
+tmp<FieldField<Field, typename typeOfMag<Type>::type>>
+magSqr(const FieldField<Field, Type>& f);
 
 template<template<class> class Field, class Type>
-tmp<FieldField<Field, scalar>> magSqr(const tmp<FieldField<Field, Type>>& tf);
+tmp<FieldField<Field, typename typeOfMag<Type>::type>>
+magSqr(const tmp<FieldField<Field, Type>>& tf);
 
 
 template<template<class> class Field, class Type>
-void mag(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f);
+void mag
+(
+    FieldField<Field, typename typeOfMag<Type>::type>& res,
+    const FieldField<Field, Type>& f
+);
 
 template<template<class> class Field, class Type>
-tmp<FieldField<Field, scalar>> mag(const FieldField<Field, Type>& f);
+tmp<FieldField<Field, typename typeOfMag<Type>::type>>
+mag(const FieldField<Field, Type>& f);
 
 template<template<class> class Field, class Type>
-tmp<FieldField<Field, scalar>> mag(const tmp<FieldField<Field, Type>>& tf);
+tmp<FieldField<Field, typename typeOfMag<Type>::type>>
+mag(const tmp<FieldField<Field, Type>>& tf);
 
 
 template<template<class> class Field, class Type>
@@ -214,9 +226,9 @@ TMP_UNARY_FUNCTION(Type, sum)
 
 
 template<template<class> class Field, class Type>
-scalar sumMag(const FieldField<Field, Type>& f);
+typename typeOfMag<Type>::type sumMag(const FieldField<Field, Type>& f);
 
-TMP_UNARY_FUNCTION(scalar, sumMag)
+TMP_UNARY_FUNCTION(typename typeOfMag<Type>::type, sumMag)
 
 
 template<template<class> class Field, class Type>
@@ -239,20 +251,19 @@ TMP_UNARY_FUNCTION(scalarMinMax, minMaxMag)
 
 
 // With reduction on ReturnType
-#define G_UNARY_FUNCTION(returnType, gFunc, func, rFunc)                       \
+#define G_UNARY_FUNCTION(ReturnType, gFunc, func, rFunc)                       \
                                                                                \
 template<template<class> class Field, class Type>                              \
-returnType gFunc(const FieldField<Field, Type>& f);                            \
-TMP_UNARY_FUNCTION(returnType, gFunc)
+ReturnType gFunc(const FieldField<Field, Type>& f);                            \
+TMP_UNARY_FUNCTION(ReturnType, gFunc)
 
 G_UNARY_FUNCTION(Type, gMax, max, max)
 G_UNARY_FUNCTION(Type, gMin, min, min)
 G_UNARY_FUNCTION(Type, gSum, sum, sum)
-
 G_UNARY_FUNCTION(MinMax<Type>, gMinMax, minMax, sum)
 G_UNARY_FUNCTION(scalarMinMax, gMinMaxMag, minMaxMag, sum)
 
-G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum)
+G_UNARY_FUNCTION(typename typeOfMag<Type>::type, gSumMag, sumMag, sum)
 
 #undef G_UNARY_FUNCTION
 
diff --git a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C
index 9404946e0721e1580eb753c42937f01437c3dae3..b6a498640780f04fa0421fdf17caf3edbf061c53 100644
--- a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C
+++ b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C
@@ -146,23 +146,35 @@ sqr(const tmp<Field<Type>>& tf)
 
 
 template<class Type>
-void magSqr(Field<scalar>& res, const UList<Type>& f)
+void magSqr
+(
+    Field<typename typeOfMag<Type>::type>& res,
+    const UList<Type>& f
+)
 {
-    TFOR_ALL_F_OP_FUNC_F(scalar, res, =, magSqr, Type, f)
+    typedef typename typeOfMag<Type>::type magType;
+
+    TFOR_ALL_F_OP_FUNC_F(magType, res, =, magSqr, Type, f)
 }
 
 template<class Type>
-tmp<Field<scalar>> magSqr(const UList<Type>& f)
+tmp<Field<typename typeOfMag<Type>::type>>
+magSqr(const UList<Type>& f)
 {
-    auto tres = tmp<Field<scalar>>::New(f.size());
+    typedef typename typeOfMag<Type>::type magType;
+
+    auto tres = tmp<Field<magType>>::New(f.size());
     magSqr(tres.ref(), f);
     return tres;
 }
 
 template<class Type>
-tmp<Field<scalar>> magSqr(const tmp<Field<Type>>& tf)
+tmp<Field<typename typeOfMag<Type>::type>>
+magSqr(const tmp<Field<Type>>& tf)
 {
-    auto tres = reuseTmp<scalar, Type>::New(tf);
+    typedef typename typeOfMag<Type>::type magType;
+
+    auto tres = reuseTmp<magType, Type>::New(tf);
     magSqr(tres.ref(), tf());
     tf.clear();
     return tres;
@@ -170,23 +182,35 @@ tmp<Field<scalar>> magSqr(const tmp<Field<Type>>& tf)
 
 
 template<class Type>
-void mag(Field<scalar>& res, const UList<Type>& f)
+void mag
+(
+    Field<typename typeOfMag<Type>::type>& res,
+    const UList<Type>& f
+)
 {
-    TFOR_ALL_F_OP_FUNC_F(scalar, res, =, mag, Type, f)
+    typedef typename typeOfMag<Type>::type magType;
+
+    TFOR_ALL_F_OP_FUNC_F(magType, res, =, mag, Type, f)
 }
 
 template<class Type>
-tmp<Field<scalar>> mag(const UList<Type>& f)
+tmp<Field<typename typeOfMag<Type>::type>>
+mag(const UList<Type>& f)
 {
-    auto tres = tmp<Field<scalar>>::New(f.size());
+    typedef typename typeOfMag<Type>::type magType;
+
+    auto tres = tmp<Field<magType>>::New(f.size());
     mag(tres.ref(), f);
     return tres;
 }
 
 template<class Type>
-tmp<Field<scalar>> mag(const tmp<Field<Type>>& tf)
+tmp<Field<typename typeOfMag<Type>::type>>
+mag(const tmp<Field<Type>>& tf)
 {
-    auto tres = reuseTmp<scalar, Type>::New(tf);
+    typedef typename typeOfMag<Type>::type magType;
+
+    auto tres = reuseTmp<magType, Type>::New(tf);
     mag(tres.ref(), tf());
     tf.clear();
     return tres;
@@ -341,14 +365,14 @@ TMP_UNARY_FUNCTION(Type, min)
 template<class Type>
 Type sum(const UList<Type>& f)
 {
+    Type Sum = Zero;
+
     if (f.size())
     {
-        Type Sum = Zero;
         TFOR_ALL_S_OP_F(Type, Sum, +=, Type, f)
-        return Sum;
     }
 
-    return Zero;
+    return Sum;
 }
 
 TMP_UNARY_FUNCTION(Type, sum)
@@ -413,15 +437,15 @@ Type minMagSqr(const UList<Type>& f)
 TMP_UNARY_FUNCTION(Type, minMagSqr)
 
 template<class Type>
-typename pTraits<Type>::cmptType
+typename scalarProduct<Type, Type>::type
 sumProd(const UList<Type>& f1, const UList<Type>& f2)
 {
-    typedef typename pTraits<Type>::cmptType outType;
+    typedef typename scalarProduct<Type, Type>::type prodType;
 
-    outType result = Zero;
+    prodType result = Zero;
     if (f1.size() && (f1.size() == f2.size()))
     {
-        TFOR_ALL_S_OP_F_OP_F(outType, result, +=, Type, f1, &&, Type, f2)
+        TFOR_ALL_S_OP_F_OP_F(prodType, result, +=, Type, f1, &&, Type, f2)
     }
     return result;
 }
@@ -450,41 +474,54 @@ Type sumCmptProd(const UList<Type>& f1, const UList<Type>& f2)
 
 
 template<class Type>
-scalar sumSqr(const UList<Type>& f)
+typename outerProduct1<Type>::type
+sumSqr(const UList<Type>& f)
 {
-    scalar SumSqr = 0;
+    typedef typename outerProduct1<Type>::type prodType;
+    prodType result = Zero;
     if (f.size())
     {
-        TFOR_ALL_S_OP_FUNC_F(scalar, SumSqr, +=, sqr, Type, f)
+        TFOR_ALL_S_OP_FUNC_F(prodType, result, +=, sqr, Type, f)
     }
-    return SumSqr;
+    return result;
+}
+
+template<class Type>
+typename outerProduct1<Type>::type
+sumSqr(const tmp<Field<Type>>& tf)
+{
+    typedef typename outerProduct1<Type>::type prodType;
+    prodType result = sumSqr(tf());
+    tf.clear();
+    return result;
 }
 
-TMP_UNARY_FUNCTION(scalar, sumSqr)
 
 template<class Type>
-scalar sumMag(const UList<Type>& f)
+typename typeOfMag<Type>::type
+sumMag(const UList<Type>& f)
 {
-    scalar SumMag = 0;
+    typedef typename typeOfMag<Type>::type magType;
+    magType result = Zero;
     if (f.size())
     {
-        TFOR_ALL_S_OP_FUNC_F(scalar, SumMag, +=, mag, Type, f)
+        TFOR_ALL_S_OP_FUNC_F(magType, result, +=, mag, Type, f)
     }
-    return SumMag;
+    return result;
 }
 
-TMP_UNARY_FUNCTION(scalar, sumMag)
+TMP_UNARY_FUNCTION(typename typeOfMag<Type>::type, sumMag)
 
 
 template<class Type>
 Type sumCmptMag(const UList<Type>& f)
 {
-    Type SumMag = Zero;
+    Type result = Zero;
     if (f.size())
     {
-        TFOR_ALL_S_OP_FUNC_F(scalar, SumMag, +=, cmptMag, Type, f)
+        TFOR_ALL_S_OP_FUNC_F(Type, result, +=, cmptMag, Type, f)
     }
-    return SumMag;
+    return result;
 }
 
 TMP_UNARY_FUNCTION(Type, sumCmptMag)
@@ -530,24 +567,24 @@ G_UNARY_FUNCTION(Type, gSumCmptMag, sumCmptMag, sum)
 G_UNARY_FUNCTION(MinMax<Type>, gMinMax, minMax, sum)
 G_UNARY_FUNCTION(scalarMinMax, gMinMaxMag, minMaxMag, sum)
 
-G_UNARY_FUNCTION(scalar, gSumSqr, sumSqr, sum)
-G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum)
+G_UNARY_FUNCTION(typename outerProduct1<Type>::type, gSumSqr, sumSqr, sum)
+G_UNARY_FUNCTION(typename typeOfMag<Type>::type, gSumMag, sumMag, sum)
 
 #undef G_UNARY_FUNCTION
 
 
 template<class Type>
-typename pTraits<Type>::cmptType gSumProd
+typename scalarProduct<Type, Type>::type gSumProd
 (
     const UList<Type>& f1,
     const UList<Type>& f2,
     const label comm
 )
 {
-    typedef typename pTraits<Type>::cmptType outType;
+    typedef typename scalarProduct<Type, Type>::type prodType;
 
-    outType result = sumProd(f1, f2);
-    reduce(result, sumOp<outType>(), Pstream::msgType(), comm);
+    prodType result = sumProd(f1, f2);
+    reduce(result, sumOp<prodType>(), Pstream::msgType(), comm);
     return result;
 }
 
diff --git a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.H b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.H
index c64aa4798a9468a467f80a93fe52f0c93f36bfe8..e80d01df2bfd0967b4cc0718b53c1a9f491d04f0 100644
--- a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.H
+++ b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.H
@@ -94,23 +94,35 @@ sqr(const tmp<Field<Type>>& tf);
 
 
 template<class Type>
-void magSqr(Field<scalar>& res, const UList<Type>& f);
+void magSqr
+(
+    Field<typename typeOfMag<Type>::type>& res,
+    const UList<Type>& f
+);
 
 template<class Type>
-tmp<Field<scalar>> magSqr(const UList<Type>& f);
+tmp<Field<typename typeOfMag<Type>::type>>
+magSqr(const UList<Type>& f);
 
 template<class Type>
-tmp<Field<scalar>> magSqr(const tmp<Field<Type>>& tf);
+tmp<Field<typename typeOfMag<Type>::type>>
+magSqr(const tmp<Field<Type>>& tf);
 
 
 template<class Type>
-void mag(Field<scalar>& res, const UList<Type>& f);
+void mag
+(
+    Field<typename typeOfMag<Type>::type>& res,
+    const UList<Type>& f
+);
 
 template<class Type>
-tmp<Field<scalar>> mag(const UList<Type>& f);
+tmp<Field<typename typeOfMag<Type>::type>>
+mag(const UList<Type>& f);
 
 template<class Type>
-tmp<Field<scalar>> mag(const tmp<Field<Type>>& tf);
+tmp<Field<typename typeOfMag<Type>::type>>
+mag(const tmp<Field<Type>>& tf);
 
 
 template<class Type>
@@ -197,7 +209,8 @@ TMP_UNARY_FUNCTION(Type, minMagSqr)
 
 
 template<class Type>
-typename pTraits<Type>::cmptType sumProd
+typename scalarProduct<Type, Type>::type
+sumProd
 (
     const UList<Type>& f1,
     const UList<Type>& f2
@@ -207,14 +220,15 @@ template<class Type>
 Type sumCmptProd(const UList<Type>& f1, const UList<Type>& f2);
 
 template<class Type>
-scalar sumSqr(const UList<Type>& f);
+typename outerProduct1<Type>::type sumSqr(const UList<Type>& f);
 
-TMP_UNARY_FUNCTION(scalar, sumSqr)
+template<class Type>
+typename outerProduct1<Type>::type sumSqr(const tmp<Field<Type>>& tf);
 
 template<class Type>
-scalar sumMag(const UList<Type>& f);
+typename typeOfMag<Type>::type sumMag(const UList<Type>& f);
 
-TMP_UNARY_FUNCTION(scalar, sumMag)
+TMP_UNARY_FUNCTION(typename typeOfMag<Type>::type, sumMag)
 
 template<class Type>
 Type sumCmptMag(const UList<Type>& f);
@@ -244,13 +258,14 @@ G_UNARY_FUNCTION(Type, gSumCmptMag, sumCmptMag, sum)
 G_UNARY_FUNCTION(MinMax<Type>, gMinMax, minMax, sum)
 G_UNARY_FUNCTION(scalarMinMax, gMinMaxMag, minMaxMag, sum)
 
-G_UNARY_FUNCTION(scalar, gSumSqr, sumSqr, sum)
-G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum)
+G_UNARY_FUNCTION(typename outerProduct1<Type>::type, gSumSqr, sumSqr, sum)
+G_UNARY_FUNCTION(typename typeOfMag<Type>::type, gSumMag, sumMag, sum)
 
 #undef G_UNARY_FUNCTION
 
+
 template<class Type>
-typename pTraits<Type>::cmptType gSumProd
+typename scalarProduct<Type, Type>::type gSumProd
 (
     const UList<Type>& f1,
     const UList<Type>& f2,
diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.C
index 6c2a4d3b0c875e126c69d047cb7fb9e149a319aa..b750be483d37177e3b33435a3832b6aba6419a5a 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.C
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.C
@@ -257,7 +257,7 @@ sqr(const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf)
 template<class Type, template<class> class PatchField, class GeoMesh>
 void magSqr
 (
-    GeometricField<scalar, PatchField, GeoMesh>& gsf,
+    GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>& gsf,
     const GeometricField<Type, PatchField, GeoMesh>& gf
 )
 {
@@ -268,13 +268,16 @@ void magSqr
 
 
 template<class Type, template<class> class PatchField, class GeoMesh>
-tmp<GeometricField<scalar, PatchField, GeoMesh>> magSqr
+tmp<GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>>
+magSqr
 (
     const GeometricField<Type, PatchField, GeoMesh>& gf
 )
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     auto tres =
-        tmp<GeometricField<scalar, PatchField, GeoMesh>>::New
+        tmp<GeometricField<magType, PatchField, GeoMesh>>::New
         (
             IOobject
             (
@@ -294,30 +297,13 @@ tmp<GeometricField<scalar, PatchField, GeoMesh>> magSqr
 }
 
 template<class Type, template<class> class PatchField, class GeoMesh>
-tmp<GeometricField<scalar, PatchField, GeoMesh>> magSqr
+tmp<GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>>
+magSqr
 (
     const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
 )
 {
-    const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
-
-    auto tres =
-        tmp<GeometricField<scalar, PatchField, GeoMesh>>::New
-        (
-            IOobject
-            (
-                "magSqr(" + gf.name() + ')',
-                gf.instance(),
-                gf.db(),
-                IOobject::NO_READ,
-                IOobject::NO_WRITE
-            ),
-            gf.mesh(),
-            sqr(gf.dimensions())
-        );
-
-    magSqr(tres.ref(), gf);
-
+    auto tres = magSqr(tgf.cref());
     tgf.clear();
 
     return tres;
@@ -327,7 +313,7 @@ tmp<GeometricField<scalar, PatchField, GeoMesh>> magSqr
 template<class Type, template<class> class PatchField, class GeoMesh>
 void mag
 (
-    GeometricField<scalar, PatchField, GeoMesh>& gsf,
+    GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>& gsf,
     const GeometricField<Type, PatchField, GeoMesh>& gf
 )
 {
@@ -338,13 +324,16 @@ void mag
 
 
 template<class Type, template<class> class PatchField, class GeoMesh>
-tmp<GeometricField<scalar, PatchField, GeoMesh>> mag
+tmp<GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>>
+mag
 (
     const GeometricField<Type, PatchField, GeoMesh>& gf
 )
 {
+    typedef typename typeOfMag<Type>::type magType;
+
     auto tres =
-        tmp<GeometricField<scalar, PatchField, GeoMesh>>::New
+        tmp<GeometricField<magType, PatchField, GeoMesh>>::New
         (
             IOobject
             (
@@ -364,30 +353,13 @@ tmp<GeometricField<scalar, PatchField, GeoMesh>> mag
 }
 
 template<class Type, template<class> class PatchField, class GeoMesh>
-tmp<GeometricField<scalar, PatchField, GeoMesh>> mag
+tmp<GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>>
+mag
 (
     const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
 )
 {
-    const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
-
-    auto tres =
-        tmp<GeometricField<scalar, PatchField, GeoMesh>>::New
-        (
-            IOobject
-            (
-                "mag(" + gf.name() + ')',
-                gf.instance(),
-                gf.db(),
-                IOobject::NO_READ,
-                IOobject::NO_WRITE
-            ),
-            gf.mesh(),
-            gf.dimensions()
-        );
-
-    mag(tres.ref(), gf);
-
+    auto tres = mag(tgf.cref());
     tgf.clear();
 
     return tres;
@@ -559,7 +531,7 @@ dimensioned<returnType> func                                                   \
 
 UNARY_REDUCTION_FUNCTION(Type, sum, gSum)
 UNARY_REDUCTION_FUNCTION(Type, average, gAverage)
-UNARY_REDUCTION_FUNCTION(scalar, sumMag, gSumMag)
+UNARY_REDUCTION_FUNCTION(typename typeOfMag<Type>::type, sumMag, gSumMag)
 
 #undef UNARY_REDUCTION_FUNCTION
 
diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.H
index 142ffbee1fa9a2065938633ccad9ceecebc6f6b5..e617526c6d319cdcbca7138751dd3cdda0097733 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.H
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.H
@@ -142,18 +142,20 @@ sqr(const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf);
 template<class Type, template<class> class PatchField, class GeoMesh>
 void magSqr
 (
-    GeometricField<scalar, PatchField, GeoMesh>& gsf,
+    GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>& gsf,
     const GeometricField<Type, PatchField, GeoMesh>& gf
 );
 
 template<class Type, template<class> class PatchField, class GeoMesh>
-tmp<GeometricField<scalar, PatchField, GeoMesh>> magSqr
+tmp<GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>>
+magSqr
 (
     const GeometricField<Type, PatchField, GeoMesh>& gf
 );
 
 template<class Type, template<class> class PatchField, class GeoMesh>
-tmp<GeometricField<scalar, PatchField, GeoMesh>> magSqr
+tmp<GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>>
+magSqr
 (
     const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
 );
@@ -161,18 +163,20 @@ tmp<GeometricField<scalar, PatchField, GeoMesh>> magSqr
 template<class Type, template<class> class PatchField, class GeoMesh>
 void mag
 (
-    GeometricField<scalar, PatchField, GeoMesh>& gsf,
+    GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>& gsf,
     const GeometricField<Type, PatchField, GeoMesh>& gf
 );
 
 template<class Type, template<class> class PatchField, class GeoMesh>
-tmp<GeometricField<scalar, PatchField, GeoMesh>> mag
+tmp<GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>>
+mag
 (
     const GeometricField<Type, PatchField, GeoMesh>& gf
 );
 
 template<class Type, template<class> class PatchField, class GeoMesh>
-tmp<GeometricField<scalar, PatchField, GeoMesh>> mag
+tmp<GeometricField<typename typeOfMag<Type>::type, PatchField, GeoMesh>>
+mag
 (
     const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
 );
@@ -252,7 +256,7 @@ dimensioned<returnType> func                                                   \
 
 UNARY_REDUCTION_FUNCTION(Type, sum, gSum)
 UNARY_REDUCTION_FUNCTION(Type, average, gAverage)
-UNARY_REDUCTION_FUNCTION(scalar, sumMag, gSumMag)
+UNARY_REDUCTION_FUNCTION(typename typeOfMag<Type>::type, sumMag, gSumMag)
 
 #undef UNARY_REDUCTION_FUNCTION
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.C
index 9474b23115b718ae9bff110c7d67fcfc7bbf2257..6a94875a1b9ab1fb0f8e76699dc32e32304bbeaf 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2012 OpenFOAM Foundation
@@ -46,7 +46,7 @@ Foam::cyclicLduInterfaceField::~cyclicLduInterfaceField()
 
 void Foam::cyclicLduInterfaceField::transformCoupleField
 (
-    scalarField& f,
+    solveScalarField& f,
     const direction cmpt
 ) const
 {
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.H
index 4b043caff403bd3ca268510d382f164773a73b29..27177491fc013ca243d7c2a9221fc1c60c6c2b18 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2012 OpenFOAM Foundation
@@ -93,7 +93,7 @@ public:
         //- Transform given patch component field
         void transformCoupleField
         (
-            scalarField& f,
+            solveScalarField& f,
             const direction cmpt
         ) const;
 };
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.C
index 2da1345eff1177105f00124d4ad6f73b7ebc32ec..c282d083ec358b9963119c16105a23d54e09b4a7 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.C
@@ -35,10 +35,4 @@ defineTypeNameAndDebug(lduInterfaceField, 0);
 }
 
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::lduInterfaceField::~lduInterfaceField()
-{}
-
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H
index db5342a1340f15a7cb96b795122547f170f39f10..9aaeaacd999244112b0f63584ac608e68d096f92 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -93,7 +93,7 @@ public:
 
 
     //- Destructor
-    virtual ~lduInterfaceField();
+    virtual ~lduInterfaceField() = default;
 
 
     // Member Functions
@@ -137,11 +137,11 @@ public:
             //  or subtract coupled contributions to matrix
             virtual void initInterfaceMatrixUpdate
             (
-                scalarField&,
+                solveScalarField& result,
                 const bool add,
-                const scalarField&,
-                const scalarField&,
-                const direction,
+                const solveScalarField& psiInternal,
+                const scalarField& coeffs,
+                const direction cmpt,
                 const Pstream::commsTypes commsType
             ) const
             {}
@@ -150,11 +150,11 @@ public:
             //  or subtract coupled contributions to matrix
             virtual void updateInterfaceMatrix
             (
-                scalarField&,
+                solveScalarField& result,
                 const bool add,
-                const scalarField&,
-                const scalarField&,
-                const direction,
+                const solveScalarField& psiInternal,
+                const scalarField& coeffs,
+                const direction cmpt,
                 const Pstream::commsTypes commsType
             ) const = 0;
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/processorLduInterfaceField/processorLduInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/processorLduInterfaceField/processorLduInterfaceField.C
index 896f36747a3d3a4d9221d9140edc872e9fdf2090..48413780ea692e8a5307b27a9330b7cf61e89e83 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/processorLduInterfaceField/processorLduInterfaceField.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/processorLduInterfaceField/processorLduInterfaceField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2012 OpenFOAM Foundation
@@ -46,7 +46,7 @@ Foam::processorLduInterfaceField::~processorLduInterfaceField()
 
 void Foam::processorLduInterfaceField::transformCoupleField
 (
-    scalarField& f,
+    solveScalarField& f,
     const direction cmpt
 ) const
 {
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/processorLduInterfaceField/processorLduInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/processorLduInterfaceField/processorLduInterfaceField.H
index 78f0806a50dd5c42a51c45a118ff7c437409d32a..bd78e33d7318d1bea8fc2330de0dcf1ef57ce4d5 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/processorLduInterfaceField/processorLduInterfaceField.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/processorLduInterfaceField/processorLduInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2014 OpenFOAM Foundation
@@ -99,7 +99,7 @@ public:
         //- Transform given patch component field
         void transformCoupleField
         (
-            scalarField& f,
+            solveScalarField& f,
             const direction cmpt
         ) const;
 };
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.C
index aa028aa3ba8719c99183606bc791728ed01652bd..98757289b29bbdb99ea9cef5a1b3e3e46c824b95 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -29,7 +29,7 @@ License
 #include "IOstreams.H"
 #include "Switch.H"
 #include "objectRegistry.H"
-#include "IOField.H"
+#include "scalarIOField.H"
 #include "Time.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@@ -319,7 +319,7 @@ const Foam::scalarField& Foam::lduMatrix::upper() const
 
 void Foam::lduMatrix::setResidualField
 (
-    const Field<scalar>& residual,
+    const scalarField& residual,
     const word& fieldName,
     const bool initial
 ) const
@@ -339,8 +339,8 @@ void Foam::lduMatrix::setResidualField
         lookupName = word("residual:" + fieldName);
     }
 
-    IOField<scalar>* residualPtr =
-        lduMesh_.thisDb().getObjectPtr<IOField<scalar>>(lookupName);
+    scalarIOField* residualPtr =
+        lduMesh_.thisDb().getObjectPtr<scalarIOField>(lookupName);
 
     if (residualPtr)
     {
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
index b94d08a1bbe854a869c80e4486431b7d855e15fc..16ea5af785cd1e0ea8613d841e6f227d8f9dec66 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -262,12 +262,12 @@ public:
 
             //- Return the matrix norm used to normalise the residual for the
             //- stopping criterion
-            scalar normFactor
+            solveScalarField::cmptType normFactor
             (
-                const scalarField& psi,
-                const scalarField& source,
-                const scalarField& Apsi,
-                scalarField& tmpField
+                const solveScalarField& psi,
+                const solveScalarField& source,
+                const solveScalarField& Apsi,
+                solveScalarField& tmpField
             ) const;
     };
 
@@ -404,11 +404,20 @@ public:
             //- Smooth the solution for a given number of sweeps
             virtual void smooth
             (
-                scalarField& psi,
+                solveScalarField& psi,
                 const scalarField& source,
                 const direction cmpt,
                 const label nSweeps
             ) const = 0;
+
+            //- Smooth the solution for a given number of sweeps
+            virtual void scalarSmooth
+            (
+                solveScalarField& psi,
+                const solveScalarField& source,
+                const direction cmpt,
+                const label nSweeps
+            ) const = 0;
     };
 
 
@@ -495,8 +504,8 @@ public:
             //- Return wA the preconditioned form of residual rA
             virtual void precondition
             (
-                scalarField& wA,
-                const scalarField& rA,
+                solveScalarField& wA,
+                const solveScalarField& rA,
                 const direction cmpt=0
             ) const = 0;
 
@@ -505,8 +514,8 @@ public:
             //  This is only required for preconditioning asymmetric matrices.
             virtual void preconditionT
             (
-                scalarField& wT,
-                const scalarField& rT,
+                solveScalarField& wT,
+                const solveScalarField& rT,
                 const direction cmpt=0
             ) const
             {
@@ -624,8 +633,8 @@ public:
             //- Matrix multiplication with updated interfaces.
             void Amul
             (
-                scalarField&,
-                const tmp<scalarField>&,
+                solveScalarField&,
+                const tmp<solveScalarField>&,
                 const FieldField<Field, scalar>&,
                 const lduInterfaceFieldPtrsList&,
                 const direction cmpt
@@ -634,8 +643,8 @@ public:
             //- Matrix transpose multiplication with updated interfaces.
             void Tmul
             (
-                scalarField&,
-                const tmp<scalarField>&,
+                solveScalarField&,
+                const tmp<solveScalarField>&,
                 const FieldField<Field, scalar>&,
                 const lduInterfaceFieldPtrsList&,
                 const direction cmpt
@@ -645,7 +654,7 @@ public:
             //- Sum the coefficients on each row of the matrix
             void sumA
             (
-                scalarField&,
+                solveScalarField&,
                 const FieldField<Field, scalar>&,
                 const lduInterfaceFieldPtrsList&
             ) const;
@@ -653,17 +662,17 @@ public:
 
             void residual
             (
-                scalarField& rA,
-                const scalarField& psi,
+                solveScalarField& rA,
+                const solveScalarField& psi,
                 const scalarField& source,
                 const FieldField<Field, scalar>& interfaceBouCoeffs,
                 const lduInterfaceFieldPtrsList& interfaces,
                 const direction cmpt
             ) const;
 
-            tmp<scalarField> residual
+            tmp<solveScalarField> residual
             (
-                const scalarField& psi,
+                const solveScalarField& psi,
                 const scalarField& source,
                 const FieldField<Field, scalar>& interfaceBouCoeffs,
                 const lduInterfaceFieldPtrsList& interfaces,
@@ -678,8 +687,8 @@ public:
                 const bool add,
                 const FieldField<Field, scalar>& interfaceCoeffs,
                 const lduInterfaceFieldPtrsList& interfaces,
-                const scalarField& psiif,
-                scalarField& result,
+                const solveScalarField& psiif,
+                solveScalarField& result,
                 const direction cmpt
             ) const;
 
@@ -689,8 +698,8 @@ public:
                 const bool add,
                 const FieldField<Field, scalar>& interfaceCoeffs,
                 const lduInterfaceFieldPtrsList& interfaces,
-                const scalarField& psiif,
-                scalarField& result,
+                const solveScalarField& psiif,
+                solveScalarField& result,
                 const direction cmpt
             ) const;
 
@@ -698,7 +707,7 @@ public:
             //- if it exists
             void setResidualField
             (
-                const Field<scalar>& residual,
+                const scalarField& residual,
                 const word& fieldName,
                 const bool initial
             ) const;
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixATmul.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixATmul.C
index 933c429f1204991e807750e7e98051e22a182f7e..a89e18211c9b1571873fac4e0e8b6cdf27974526 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixATmul.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixATmul.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -35,17 +35,17 @@ Description
 
 void Foam::lduMatrix::Amul
 (
-    scalarField& Apsi,
-    const tmp<scalarField>& tpsi,
+    solveScalarField& Apsi,
+    const tmp<solveScalarField>& tpsi,
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
     const direction cmpt
 ) const
 {
-    scalar* __restrict__ ApsiPtr = Apsi.begin();
+    solveScalar* __restrict__ ApsiPtr = Apsi.begin();
 
-    const scalarField& psi = tpsi();
-    const scalar* const __restrict__ psiPtr = psi.begin();
+    const solveScalarField& psi = tpsi();
+    const solveScalar* const __restrict__ psiPtr = psi.begin();
 
     const scalar* const __restrict__ diagPtr = diag().begin();
 
@@ -98,17 +98,17 @@ void Foam::lduMatrix::Amul
 
 void Foam::lduMatrix::Tmul
 (
-    scalarField& Tpsi,
-    const tmp<scalarField>& tpsi,
+    solveScalarField& Tpsi,
+    const tmp<solveScalarField>& tpsi,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
     const direction cmpt
 ) const
 {
-    scalar* __restrict__ TpsiPtr = Tpsi.begin();
+    solveScalar* __restrict__ TpsiPtr = Tpsi.begin();
 
-    const scalarField& psi = tpsi();
-    const scalar* const __restrict__ psiPtr = psi.begin();
+    const solveScalarField& psi = tpsi();
+    const solveScalar* const __restrict__ psiPtr = psi.begin();
 
     const scalar* const __restrict__ diagPtr = diag().begin();
 
@@ -159,12 +159,12 @@ void Foam::lduMatrix::Tmul
 
 void Foam::lduMatrix::sumA
 (
-    scalarField& sumA,
+    solveScalarField& sumA,
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const lduInterfaceFieldPtrsList& interfaces
 ) const
 {
-    scalar* __restrict__ sumAPtr = sumA.begin();
+    solveScalar* __restrict__ sumAPtr = sumA.begin();
 
     const scalar* __restrict__ diagPtr = diag().begin();
 
@@ -208,17 +208,17 @@ void Foam::lduMatrix::sumA
 
 void Foam::lduMatrix::residual
 (
-    scalarField& rA,
-    const scalarField& psi,
+    solveScalarField& rA,
+    const solveScalarField& psi,
     const scalarField& source,
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
     const direction cmpt
 ) const
 {
-    scalar* __restrict__ rAPtr = rA.begin();
+    solveScalar* __restrict__ rAPtr = rA.begin();
 
-    const scalar* const __restrict__ psiPtr = psi.begin();
+    const solveScalar* const __restrict__ psiPtr = psi.begin();
     const scalar* const __restrict__ diagPtr = diag().begin();
     const scalar* const __restrict__ sourcePtr = source.begin();
 
@@ -278,16 +278,16 @@ void Foam::lduMatrix::residual
 }
 
 
-Foam::tmp<Foam::scalarField> Foam::lduMatrix::residual
+Foam::tmp<Foam::Field<Foam::solveScalar>> Foam::lduMatrix::residual
 (
-    const scalarField& psi,
+    const solveScalarField& psi,
     const scalarField& source,
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
     const direction cmpt
 ) const
 {
-    tmp<scalarField> trA(new scalarField(psi.size()));
+    tmp<solveScalarField> trA(new solveScalarField(psi.size()));
     residual(trA.ref(), psi, source, interfaceBouCoeffs, interfaces, cmpt);
     return trA;
 }
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSolver.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSolver.C
index c202616abc352fb0fee8d8155340602ad72bf399..42e24d04b5b1b36ad7d4e3fa1cbb42101f6070b8 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSolver.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSolver.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -170,12 +170,12 @@ void Foam::lduMatrix::solver::read(const dictionary& solverControls)
 }
 
 
-Foam::scalar Foam::lduMatrix::solver::normFactor
+Foam::solveScalarField::cmptType Foam::lduMatrix::solver::normFactor
 (
-    const scalarField& psi,
-    const scalarField& source,
-    const scalarField& Apsi,
-    scalarField& tmpField
+    const solveScalarField& psi,
+    const solveScalarField& source,
+    const solveScalarField& Apsi,
+    solveScalarField& tmpField
 ) const
 {
     // --- Calculate A dot reference value of psi
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C
index db26b154165512647b93e1528ed2ce11219800cd..515cb10354a7377fea6683a3575971792c96416a 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -34,8 +34,8 @@ void Foam::lduMatrix::initMatrixInterfaces
     const bool add,
     const FieldField<Field, scalar>& coupleCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    const scalarField& psiif,
-    scalarField& result,
+    const solveScalarField& psiif,
+    solveScalarField& result,
     const direction cmpt
 ) const
 {
@@ -103,8 +103,8 @@ void Foam::lduMatrix::updateMatrixInterfaces
     const bool add,
     const FieldField<Field, scalar>& coupleCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    const scalarField& psiif,
-    scalarField& result,
+    const solveScalarField& psiif,
+    solveScalarField& result,
     const direction cmpt
 ) const
 {
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.C
index 85e638699a76ecba9713b1754778c19b0902d6d5..daab66fe717c956dbe16ae25802a4a4352e3c04a 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "DICPreconditioner.H"
+#include <algorithm>
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -48,8 +49,11 @@ Foam::DICPreconditioner::DICPreconditioner
 )
 :
     lduMatrix::preconditioner(sol),
-    rD_(sol.matrix().diag())
+    rD_(sol.matrix().diag().size())
 {
+    const scalarField& diag = sol.matrix().diag();
+    std::copy(diag.begin(), diag.end(), rD_.begin());
+
     calcReciprocalD(rD_, sol.matrix());
 }
 
@@ -58,11 +62,11 @@ Foam::DICPreconditioner::DICPreconditioner
 
 void Foam::DICPreconditioner::calcReciprocalD
 (
-    scalarField& rD,
+    solveScalarField& rD,
     const lduMatrix& matrix
 )
 {
-    scalar* __restrict__ rDPtr = rD.begin();
+    solveScalar* __restrict__ rDPtr = rD.begin();
 
     const label* const __restrict__ uPtr = matrix.lduAddr().upperAddr().begin();
     const label* const __restrict__ lPtr = matrix.lduAddr().lowerAddr().begin();
@@ -88,14 +92,14 @@ void Foam::DICPreconditioner::calcReciprocalD
 
 void Foam::DICPreconditioner::precondition
 (
-    scalarField& wA,
-    const scalarField& rA,
+    solveScalarField& wA,
+    const solveScalarField& rA,
     const direction
 ) const
 {
-    scalar* __restrict__ wAPtr = wA.begin();
-    const scalar* __restrict__ rAPtr = rA.begin();
-    const scalar* __restrict__ rDPtr = rD_.begin();
+    solveScalar* __restrict__ wAPtr = wA.begin();
+    const solveScalar* __restrict__ rAPtr = rA.begin();
+    const solveScalar* __restrict__ rDPtr = rD_.begin();
 
     const label* const __restrict__ uPtr =
         solver_.matrix().lduAddr().upperAddr().begin();
@@ -104,9 +108,9 @@ void Foam::DICPreconditioner::precondition
     const scalar* const __restrict__ upperPtr =
         solver_.matrix().upper().begin();
 
-    label nCells = wA.size();
-    label nFaces = solver_.matrix().upper().size();
-    label nFacesM1 = nFaces - 1;
+    const label nCells = wA.size();
+    const label nFaces = solver_.matrix().upper().size();
+    const label nFacesM1 = nFaces - 1;
 
     for (label cell=0; cell<nCells; cell++)
     {
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.H
index c3262c88c701db13957f3858706535a18df998a5..6c59f0617169802776f41bd7fa0ecdc3c5073ab2 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -60,7 +60,7 @@ class DICPreconditioner
     // Private data
 
         //- The reciprocal preconditioned diagonal
-        scalarField rD_;
+        solveScalarField rD_;
 
 
 public:
@@ -87,13 +87,13 @@ public:
     // Member Functions
 
         //- Calculate the reciprocal of the preconditioned diagonal
-        static void calcReciprocalD(scalarField& rD, const lduMatrix& matrix);
+        static void calcReciprocalD(solveScalarField&, const lduMatrix&);
 
         //- Return wA the preconditioned form of residual rA
         virtual void precondition
         (
-            scalarField& wA,
-            const scalarField& rA,
+            solveScalarField& wA,
+            const solveScalarField& rA,
             const direction cmpt=0
         ) const;
 };
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.C
index 8160fe17e6a2655363c49c450716d366617138b4..d48f95b0ba0e8a14abd067b6b0c103070e99d7f6 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "DILUPreconditioner.H"
+#include <algorithm>
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -48,8 +49,11 @@ Foam::DILUPreconditioner::DILUPreconditioner
 )
 :
     lduMatrix::preconditioner(sol),
-    rD_(sol.matrix().diag())
+    rD_(sol.matrix().diag().size())
 {
+    const scalarField& diag = sol.matrix().diag();
+    std::copy(diag.begin(), diag.end(), rD_.begin());
+
     calcReciprocalD(rD_, sol.matrix());
 }
 
@@ -58,11 +62,11 @@ Foam::DILUPreconditioner::DILUPreconditioner
 
 void Foam::DILUPreconditioner::calcReciprocalD
 (
-    scalarField& rD,
+    solveScalarField& rD,
     const lduMatrix& matrix
 )
 {
-    scalar* __restrict__ rDPtr = rD.begin();
+    solveScalar* __restrict__ rDPtr = rD.begin();
 
     const label* const __restrict__ uPtr = matrix.lduAddr().upperAddr().begin();
     const label* const __restrict__ lPtr = matrix.lduAddr().lowerAddr().begin();
@@ -78,7 +82,7 @@ void Foam::DILUPreconditioner::calcReciprocalD
 
 
     // Calculate the reciprocal of the preconditioned diagonal
-    label nCells = rD.size();
+    const label nCells = rD.size();
 
     for (label cell=0; cell<nCells; cell++)
     {
@@ -89,14 +93,14 @@ void Foam::DILUPreconditioner::calcReciprocalD
 
 void Foam::DILUPreconditioner::precondition
 (
-    scalarField& wA,
-    const scalarField& rA,
+    solveScalarField& wA,
+    const solveScalarField& rA,
     const direction
 ) const
 {
-    scalar* __restrict__ wAPtr = wA.begin();
-    const scalar* __restrict__ rAPtr = rA.begin();
-    const scalar* __restrict__ rDPtr = rD_.begin();
+    solveScalar* __restrict__ wAPtr = wA.begin();
+    const solveScalar* __restrict__ rAPtr = rA.begin();
+    const solveScalar* __restrict__ rDPtr = rD_.begin();
 
     const label* const __restrict__ uPtr =
         solver_.matrix().lduAddr().upperAddr().begin();
@@ -110,21 +114,18 @@ void Foam::DILUPreconditioner::precondition
     const scalar* const __restrict__ lowerPtr =
         solver_.matrix().lower().begin();
 
-    label nCells = wA.size();
-    label nFaces = solver_.matrix().upper().size();
-    label nFacesM1 = nFaces - 1;
+    const label nCells = wA.size();
+    const label nFaces = solver_.matrix().upper().size();
+    const label nFacesM1 = nFaces - 1;
 
     for (label cell=0; cell<nCells; cell++)
     {
         wAPtr[cell] = rDPtr[cell]*rAPtr[cell];
     }
 
-
-    label sface;
-
     for (label face=0; face<nFaces; face++)
     {
-        sface = losortPtr[face];
+        const label sface = losortPtr[face];
         wAPtr[uPtr[sface]] -=
             rDPtr[uPtr[sface]]*lowerPtr[sface]*wAPtr[lPtr[sface]];
     }
@@ -139,14 +140,14 @@ void Foam::DILUPreconditioner::precondition
 
 void Foam::DILUPreconditioner::preconditionT
 (
-    scalarField& wT,
-    const scalarField& rT,
+    solveScalarField& wT,
+    const solveScalarField& rT,
     const direction
 ) const
 {
-    scalar* __restrict__ wTPtr = wT.begin();
-    const scalar* __restrict__ rTPtr = rT.begin();
-    const scalar* __restrict__ rDPtr = rD_.begin();
+    solveScalar* __restrict__ wTPtr = wT.begin();
+    const solveScalar* __restrict__ rTPtr = rT.begin();
+    const solveScalar* __restrict__ rDPtr = rD_.begin();
 
     const label* const __restrict__ uPtr =
         solver_.matrix().lduAddr().upperAddr().begin();
@@ -160,9 +161,9 @@ void Foam::DILUPreconditioner::preconditionT
     const scalar* const __restrict__ lowerPtr =
         solver_.matrix().lower().begin();
 
-    label nCells = wT.size();
-    label nFaces = solver_.matrix().upper().size();
-    label nFacesM1 = nFaces - 1;
+    const label nCells = wT.size();
+    const label nFaces = solver_.matrix().upper().size();
+    const label nFacesM1 = nFaces - 1;
 
     for (label cell=0; cell<nCells; cell++)
     {
@@ -176,11 +177,9 @@ void Foam::DILUPreconditioner::preconditionT
     }
 
 
-    label sface;
-
     for (label face=nFacesM1; face>=0; face--)
     {
-        sface = losortPtr[face];
+        const label sface = losortPtr[face];
         wTPtr[lPtr[sface]] -=
             rDPtr[lPtr[sface]]*lowerPtr[sface]*wTPtr[uPtr[sface]];
     }
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.H
index bff7d55baaf2f2e6656a2c2e3ab52aa06035144f..28743d449c1aa81c71bb29e9a1aae8cb3a4469af 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -60,7 +60,7 @@ class DILUPreconditioner
     // Private data
 
         //- The reciprocal preconditioned diagonal
-        scalarField rD_;
+        solveScalarField rD_;
 
 
 public:
@@ -87,21 +87,21 @@ public:
     // Member Functions
 
         //- Calculate the reciprocal of the preconditioned diagonal
-        static void calcReciprocalD(scalarField& rD, const lduMatrix& matrix);
+        static void calcReciprocalD(solveScalarField&, const lduMatrix&);
 
         //- Return wA the preconditioned form of residual rA
         virtual void precondition
         (
-            scalarField& wA,
-            const scalarField& rA,
+            solveScalarField& wA,
+            const solveScalarField& rA,
             const direction cmpt=0
         ) const;
 
         //- Return wT the transpose-matrix preconditioned form of residual rT.
         virtual void preconditionT
         (
-            scalarField& wT,
-            const scalarField& rT,
+            solveScalarField& wT,
+            const solveScalarField& rT,
             const direction cmpt=0
         ) const;
 };
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.C
index bf7db89c03fc1008aa0d4902215e372fa8f55643..7d173d55af23756b41430ae7893c2aaf5a599034 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "FDICPreconditioner.H"
+#include <algorithm>
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -48,13 +49,16 @@ Foam::FDICPreconditioner::FDICPreconditioner
 )
 :
     lduMatrix::preconditioner(sol),
-    rD_(sol.matrix().diag()),
+    rD_(sol.matrix().diag().size()),
     rDuUpper_(sol.matrix().upper().size()),
     rDlUpper_(sol.matrix().upper().size())
 {
-    scalar* __restrict__ rDPtr = rD_.begin();
-    scalar* __restrict__ rDuUpperPtr = rDuUpper_.begin();
-    scalar* __restrict__ rDlUpperPtr = rDlUpper_.begin();
+    const scalarField& diag = sol.matrix().diag();
+    std::copy(diag.begin(), diag.end(), rD_.begin());
+
+    solveScalar* __restrict__ rDPtr = rD_.begin();
+    solveScalar* __restrict__ rDuUpperPtr = rDuUpper_.begin();
+    solveScalar* __restrict__ rDlUpperPtr = rDlUpper_.begin();
 
     const label* const __restrict__ uPtr =
         solver_.matrix().lduAddr().upperAddr().begin();
@@ -63,8 +67,8 @@ Foam::FDICPreconditioner::FDICPreconditioner
     const scalar* const __restrict__ upperPtr =
         solver_.matrix().upper().begin();
 
-    label nCells = rD_.size();
-    label nFaces = solver_.matrix().upper().size();
+    const label nCells = rD_.size();
+    const label nFaces = solver_.matrix().upper().size();
 
     for (label face=0; face<nFaces; face++)
     {
@@ -89,26 +93,26 @@ Foam::FDICPreconditioner::FDICPreconditioner
 
 void Foam::FDICPreconditioner::precondition
 (
-    scalarField& wA,
-    const scalarField& rA,
+    solveScalarField& wA,
+    const solveScalarField& rA,
     const direction
 ) const
 {
-    scalar* __restrict__ wAPtr = wA.begin();
-    const scalar* __restrict__ rAPtr = rA.begin();
-    const scalar* __restrict__ rDPtr = rD_.begin();
+    solveScalar* __restrict__ wAPtr = wA.begin();
+    const solveScalar* __restrict__ rAPtr = rA.begin();
+    const solveScalar* __restrict__ rDPtr = rD_.begin();
 
     const label* const __restrict__ uPtr =
         solver_.matrix().lduAddr().upperAddr().begin();
     const label* const __restrict__ lPtr =
         solver_.matrix().lduAddr().lowerAddr().begin();
 
-    const scalar* const __restrict__ rDuUpperPtr = rDuUpper_.begin();
-    const scalar* const __restrict__ rDlUpperPtr = rDlUpper_.begin();
+    const solveScalar* const __restrict__ rDuUpperPtr = rDuUpper_.begin();
+    const solveScalar* const __restrict__ rDlUpperPtr = rDlUpper_.begin();
 
-    label nCells = wA.size();
-    label nFaces = solver_.matrix().upper().size();
-    label nFacesM1 = nFaces - 1;
+    const label nCells = wA.size();
+    const label nFaces = solver_.matrix().upper().size();
+    const label nFacesM1 = nFaces - 1;
 
     for (label cell=0; cell<nCells; cell++)
     {
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.H
index c7ccd3b5e82d60f2667c7ba54e2ef43ddf149214..64ae1566ffba643b5889dd9c3abed5f282ac5d2e 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -62,9 +62,9 @@ class FDICPreconditioner
     // Private data
 
         //- The reciprocal preconditioned diagonal
-        scalarField rD_;
-        scalarField rDuUpper_;
-        scalarField rDlUpper_;
+        solveScalarField rD_;
+        solveScalarField rDuUpper_;
+        solveScalarField rDlUpper_;
 
 
     // Private Member Functions
@@ -102,8 +102,8 @@ public:
         //- Return wA the preconditioned form of residual rA
         virtual void precondition
         (
-            scalarField& wA,
-            const scalarField& rA,
+            solveScalarField& wA,
+            const solveScalarField& rA,
             const direction cmpt=0
         ) const;
 };
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.C
index f96d43099b559017fbf1c919e5e786c442d27133..d6c77a6f8e5e9d7242eee5ae18b2de15f84f7688 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "GAMGPreconditioner.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -82,29 +83,29 @@ void Foam::GAMGPreconditioner::readControls()
 
 void Foam::GAMGPreconditioner::precondition
 (
-    scalarField& wA,
-    const scalarField& rA,
+    solveScalarField& wA,
+    const solveScalarField& rA_ss,
     const direction cmpt
 ) const
 {
     wA = 0.0;
-    scalarField AwA(wA.size());
-    scalarField finestCorrection(wA.size());
-    scalarField finestResidual(rA);
+    solveScalarField AwA(wA.size());
+    solveScalarField finestCorrection(wA.size());
+    solveScalarField finestResidual(rA_ss);
 
     // Create coarse grid correction fields
-    PtrList<scalarField> coarseCorrFields;
+    PtrList<solveScalarField> coarseCorrFields;
 
     // Create coarse grid sources
-    PtrList<scalarField> coarseSources;
+    PtrList<solveScalarField> coarseSources;
 
     // Create the smoothers for all levels
     PtrList<lduMatrix::smoother> smoothers;
 
     // Scratch fields if processor-agglomerated coarse level meshes
     // are bigger than original. Usually not needed
-    scalarField ApsiScratch;
-    scalarField finestCorrectionScratch;
+    solveScalarField ApsiScratch;
+    solveScalarField finestCorrectionScratch;
 
     // Initialise the above data structures
     initVcycle
@@ -116,8 +117,15 @@ void Foam::GAMGPreconditioner::precondition
         finestCorrectionScratch
     );
 
+
+    // Storage area when solveScalar != scalar
+    scalarField rA_s;
+
     for (label cycle=0; cycle<nVcycles_; cycle++)
     {
+        const scalarField& rA =
+            ConstPrecisionAdaptor<scalar, solveScalar>::get(rA_ss, rA_s);
+
         Vcycle
         (
             smoothers,
@@ -143,7 +151,7 @@ void Foam::GAMGPreconditioner::precondition
         {
             // Calculate finest level residual field
             matrix_.Amul(AwA, wA, interfaceBouCoeffs_, interfaces_, cmpt);
-            finestResidual = rA;
+            finestResidual = rA_ss;
             finestResidual -= AwA;
         }
     }
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.H
index a9e90e05e699987db148124cf9eecc54bdfcf7dc..1ee71b19b83f4da58699d3aa94b16863d66d6948 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -93,8 +93,8 @@ public:
         //- Return wA the preconditioned form of residual rA
         virtual void precondition
         (
-            scalarField& wA,
-            const scalarField& rA,
+            solveScalarField& wA,
+            const solveScalarField& rA,
             const direction cmpt=0
         ) const;
 };
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.C
index aa2d7f451a3d94b05f835654b6d239b3ec4c3678..59f2b6cf2b045503ae9fb322048d47de7e61e70f 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2004-2010-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -54,10 +54,10 @@ Foam::diagonalPreconditioner::diagonalPreconditioner
     lduMatrix::preconditioner(sol),
     rD(sol.matrix().diag().size())
 {
-    scalar* __restrict__ rDPtr = rD.begin();
+    solveScalar* __restrict__ rDPtr = rD.begin();
     const scalar* __restrict__ DPtr = solver_.matrix().diag().begin();
 
-    label nCells = rD.size();
+    const label nCells = rD.size();
 
     // Generate reciprocal diagonal
     for (label cell=0; cell<nCells; cell++)
@@ -71,16 +71,16 @@ Foam::diagonalPreconditioner::diagonalPreconditioner
 
 void Foam::diagonalPreconditioner::precondition
 (
-    scalarField& wA,
-    const scalarField& rA,
+    solveScalarField& wA,
+    const solveScalarField& rA,
     const direction
 ) const
 {
-    scalar* __restrict__ wAPtr = wA.begin();
-    const scalar* __restrict__ rAPtr = rA.begin();
-    const scalar* __restrict__ rDPtr = rD.begin();
+    solveScalar* __restrict__ wAPtr = wA.begin();
+    const solveScalar* __restrict__ rAPtr = rA.begin();
+    const solveScalar* __restrict__ rDPtr = rD.begin();
 
-    label nCells = wA.size();
+    const label nCells = wA.size();
 
     for (label cell=0; cell<nCells; cell++)
     {
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.H
index 62f72b88392b9350e23c3387422c1d044a6d77eb..108d0aa6ceffcff064590b9bad3bd5d79049dfe5 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -61,7 +61,7 @@ class diagonalPreconditioner
     // Private data
 
         //- The reciprocal diagonal
-        scalarField rD;
+        solveScalarField rD;
 
 
     // Private Member Functions
@@ -99,16 +99,16 @@ public:
         //- Return wA the preconditioned form of residual rA
         virtual void precondition
         (
-            scalarField& wA,
-            const scalarField& rA,
+            solveScalarField& wA,
+            const solveScalarField& rA,
             const direction cmpt=0
         ) const;
 
         //- Return wT the transpose-matrix preconditioned form of residual rT.
         virtual void preconditionT
         (
-            scalarField& wT,
-            const scalarField& rT,
+            solveScalarField& wT,
+            const solveScalarField& rT,
             const direction cmpt=0
         ) const
         {
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.C
index 163fa366d2eb6f9dc33362e8a9c43c6631111243..53911410301d190d91c180915d3f0cfd914b5461 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -59,15 +59,15 @@ Foam::noPreconditioner::noPreconditioner
 
 void Foam::noPreconditioner::precondition
 (
-    scalarField& wA,
-    const scalarField& rA,
+    solveScalarField& wA,
+    const solveScalarField& rA,
     const direction
 ) const
 {
-    scalar* __restrict__ wAPtr = wA.begin();
-    const scalar* __restrict__ rAPtr = rA.begin();
+    solveScalar* __restrict__ wAPtr = wA.begin();
+    const solveScalar* __restrict__ rAPtr = rA.begin();
 
-    label nCells = wA.size();
+    const label nCells = wA.size();
 
     for (label cell=0; cell<nCells; cell++)
     {
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.H
index 5c379ca181fcade55213d4dcd35eaba451f73901..9f82eabe58d0baa6d809363fb8270529cb1276f6 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -90,16 +90,16 @@ public:
         //- Return wA the preconditioned form of residual rA
         virtual void precondition
         (
-            scalarField& wA,
-            const scalarField& rA,
+            solveScalarField& wA,
+            const solveScalarField& rA,
             const direction cmpt=0
         ) const;
 
         //- Return wT the transpose-matrix preconditioned form of residual rT.
         virtual void preconditionT
         (
-            scalarField& wT,
-            const scalarField& rT,
+            solveScalarField& wT,
+            const solveScalarField& rT,
             const direction cmpt=0
         ) const
         {
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.C b/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.C
index a8c7bed7bdca8615a892fdbe3f86fa743446b00d..60479d41214b8d7811dcebcc91a5c38332c09176 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.C
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -27,6 +27,8 @@ License
 
 #include "DICSmoother.H"
 #include "DICPreconditioner.H"
+#include "PrecisionAdaptor.H"
+#include <algorithm>
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -58,8 +60,11 @@ Foam::DICSmoother::DICSmoother
         interfaceIntCoeffs,
         interfaces
     ),
-    rD_(matrix_.diag())
+    rD_(matrix_.diag().size())
 {
+    const scalarField& diag = matrix_.diag();
+    std::copy(diag.begin(), diag.end(), rD_.begin());
+
     DICPreconditioner::calcReciprocalD(rD_, matrix_);
 }
 
@@ -68,13 +73,13 @@ Foam::DICSmoother::DICSmoother
 
 void Foam::DICSmoother::smooth
 (
-    scalarField& psi,
+    solveScalarField& psi,
     const scalarField& source,
     const direction cmpt,
     const label nSweeps
 ) const
 {
-    const scalar* const __restrict__ rDPtr = rD_.begin();
+    const solveScalar* const __restrict__ rDPtr = rD_.begin();
     const scalar* const __restrict__ upperPtr = matrix_.upper().begin();
     const label* const __restrict__ uPtr =
         matrix_.lduAddr().upperAddr().begin();
@@ -82,8 +87,8 @@ void Foam::DICSmoother::smooth
         matrix_.lduAddr().lowerAddr().begin();
 
     // Temporary storage for the residual
-    scalarField rA(rD_.size());
-    scalar* __restrict__ rAPtr = rA.begin();
+    solveScalarField rA(rD_.size());
+    solveScalar* __restrict__ rAPtr = rA.begin();
 
     for (label sweep=0; sweep<nSweeps; sweep++)
     {
@@ -97,19 +102,22 @@ void Foam::DICSmoother::smooth
             cmpt
         );
 
-        rA *= rD_;
+        forAll(rA, i)
+        {
+            rA[i] *= rD_[i];
+        }
 
-        label nFaces = matrix_.upper().size();
+        const label nFaces = matrix_.upper().size();
         for (label facei=0; facei<nFaces; facei++)
         {
-            label u = uPtr[facei];
+            const label u = uPtr[facei];
             rAPtr[u] -= rDPtr[u]*upperPtr[facei]*rAPtr[lPtr[facei]];
         }
 
-        label nFacesM1 = nFaces - 1;
+        const label nFacesM1 = nFaces - 1;
         for (label facei=nFacesM1; facei>=0; facei--)
         {
-            label l = lPtr[facei];
+            const label l = lPtr[facei];
             rAPtr[l] -= rDPtr[l]*upperPtr[facei]*rAPtr[uPtr[facei]];
         }
 
@@ -118,4 +126,22 @@ void Foam::DICSmoother::smooth
 }
 
 
+void Foam::DICSmoother::scalarSmooth
+(
+    solveScalarField& psi,
+    const solveScalarField& source,
+    const direction cmpt,
+    const label nSweeps
+) const
+{
+    smooth
+    (
+        psi,
+        ConstPrecisionAdaptor<scalar, solveScalar>(source),
+        cmpt,
+        nSweeps
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.H
index 86a47cbfbf4c01d94935e25a7971b90734f8fe3f..f67b3c84f3cde2cd236aa0abfcef109f65fdcad4 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -62,7 +62,7 @@ class DICSmoother
     // Private data
 
         //- The reciprocal preconditioned diagonal
-        scalarField rD_;
+        solveScalarField rD_;
 
 
 public:
@@ -89,11 +89,20 @@ public:
         //- Smooth the solution for a given number of sweeps
         void smooth
         (
-            scalarField& psi,
+            solveScalarField& psi,
             const scalarField& source,
             const direction cmpt,
             const label nSweeps
         ) const;
+
+        //- Smooth the solution for a given number of sweeps
+        void scalarSmooth
+        (
+            solveScalarField& psi,
+            const solveScalarField& source,
+            const direction cmpt,
+            const label nSweeps
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.C b/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.C
index 43d95d791a1672e2e2aabb668173bcd7779bfb97..5855bd91a8b3970f5f2f6b91cbc572ded84b0f29 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.C
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -80,7 +80,7 @@ Foam::DICGaussSeidelSmoother::DICGaussSeidelSmoother
 
 void Foam::DICGaussSeidelSmoother::smooth
 (
-    scalarField& psi,
+    solveScalarField& psi,
     const scalarField& source,
     const direction cmpt,
     const label nSweeps
@@ -91,4 +91,17 @@ void Foam::DICGaussSeidelSmoother::smooth
 }
 
 
+void Foam::DICGaussSeidelSmoother::scalarSmooth
+(
+    solveScalarField& psi,
+    const solveScalarField& source,
+    const direction cmpt,
+    const label nSweeps
+) const
+{
+    dicSmoother_.scalarSmooth(psi, source, cmpt, nSweeps);
+    gsSmoother_.scalarSmooth(psi, source, cmpt, nSweeps);
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.H
index b2d4bf119abf9bf1a84f0f32261ae5f43d0e71bc..a88ef0c2bb511c79effa20c4ac9f9a62d39c1d22 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -89,11 +89,20 @@ public:
         //- Smooth the solution for a given number of sweeps
         virtual void smooth
         (
-            scalarField& psi,
+            solveScalarField& psi,
             const scalarField& Source,
             const direction cmpt,
             const label nSweeps
         ) const;
+
+        //- Smooth the solution for a given number of sweeps
+        virtual void scalarSmooth
+        (
+            solveScalarField& psi,
+            const solveScalarField& Source,
+            const direction cmpt,
+            const label nSweeps
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.C b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.C
index e487b93880487e4c5c0d3853d9c450168a46295e..4b2108ae0f17da042cbc486e9022f030c5fd54ae 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.C
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -27,6 +27,8 @@ License
 
 #include "DILUSmoother.H"
 #include "DILUPreconditioner.H"
+#include "PrecisionAdaptor.H"
+#include <algorithm>
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -58,8 +60,11 @@ Foam::DILUSmoother::DILUSmoother
         interfaceIntCoeffs,
         interfaces
     ),
-    rD_(matrix_.diag())
+    rD_(matrix_.diag().size())
 {
+    const scalarField& diag = matrix_.diag();
+    std::copy(diag.begin(), diag.end(), rD_.begin());
+
     DILUPreconditioner::calcReciprocalD(rD_, matrix_);
 }
 
@@ -68,13 +73,13 @@ Foam::DILUSmoother::DILUSmoother
 
 void Foam::DILUSmoother::smooth
 (
-    scalarField& psi,
+    solveScalarField& psi,
     const scalarField& source,
     const direction cmpt,
     const label nSweeps
 ) const
 {
-    const scalar* const __restrict__ rDPtr = rD_.begin();
+    const solveScalar* const __restrict__ rDPtr = rD_.begin();
 
     const label* const __restrict__ uPtr =
         matrix_.lduAddr().upperAddr().begin();
@@ -85,8 +90,8 @@ void Foam::DILUSmoother::smooth
     const scalar* const __restrict__ lowerPtr = matrix_.lower().begin();
 
     // Temporary storage for the residual
-    scalarField rA(rD_.size());
-    scalar* __restrict__ rAPtr = rA.begin();
+    solveScalarField rA(rD_.size());
+    solveScalar* __restrict__ rAPtr = rA.begin();
 
     for (label sweep=0; sweep<nSweeps; sweep++)
     {
@@ -100,19 +105,22 @@ void Foam::DILUSmoother::smooth
             cmpt
         );
 
-        rA *= rD_;
+        forAll(rA, i)
+        {
+            rA[i] *= rD_[i];
+        }
 
-        label nFaces = matrix_.upper().size();
+        const label nFaces = matrix_.upper().size();
         for (label face=0; face<nFaces; face++)
         {
-            label u = uPtr[face];
+            const label u = uPtr[face];
             rAPtr[u] -= rDPtr[u]*lowerPtr[face]*rAPtr[lPtr[face]];
         }
 
-        label nFacesM1 = nFaces - 1;
+        const label nFacesM1 = nFaces - 1;
         for (label face=nFacesM1; face>=0; face--)
         {
-            label l = lPtr[face];
+            const label l = lPtr[face];
             rAPtr[l] -= rDPtr[l]*upperPtr[face]*rAPtr[uPtr[face]];
         }
 
@@ -121,4 +129,22 @@ void Foam::DILUSmoother::smooth
 }
 
 
+void Foam::DILUSmoother::scalarSmooth
+(
+    solveScalarField& psi,
+    const solveScalarField& source,
+    const direction cmpt,
+    const label nSweeps
+) const
+{
+    smooth
+    (
+        psi,
+        ConstPrecisionAdaptor<scalar, solveScalar>(source),
+        cmpt,
+        nSweeps
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.H
index 66b4f2c76064d468c6d29061373f04650ba119a5..4d2cfdf4773c55bb0f817b8791bdc44a28cb4f09 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -58,7 +58,7 @@ class DILUSmoother
     // Private data
 
         //- The reciprocal preconditioned diagonal
-        scalarField rD_;
+        solveScalarField rD_;
 
 
 public:
@@ -85,11 +85,20 @@ public:
         //- Smooth the solution for a given number of sweeps
         void smooth
         (
-            scalarField& psi,
+            solveScalarField& psi,
             const scalarField& source,
             const direction cmpt,
             const label nSweeps
         ) const;
+
+        //- Smooth the solution for a given number of sweeps
+        void scalarSmooth
+        (
+            solveScalarField& psi,
+            const solveScalarField& source,
+            const direction cmpt,
+            const label nSweeps
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.C b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.C
index 65c0f4659401de614a4720198ba205e86ca6e778..4e85cb18ac856d3d20ec7b1adddc2f151a31b5eb 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.C
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "DILUGaussSeidelSmoother.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -79,16 +80,34 @@ Foam::DILUGaussSeidelSmoother::DILUGaussSeidelSmoother
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void Foam::DILUGaussSeidelSmoother::scalarSmooth
+(
+    solveScalarField& psi,
+    const solveScalarField& source,
+    const direction cmpt,
+    const label nSweeps
+) const
+{
+    diluSmoother_.scalarSmooth(psi, source, cmpt, nSweeps);
+    gsSmoother_.scalarSmooth(psi, source, cmpt, nSweeps);
+}
+
+
 void Foam::DILUGaussSeidelSmoother::smooth
 (
-    scalarField& psi,
+    solveScalarField& psi,
     const scalarField& source,
     const direction cmpt,
     const label nSweeps
 ) const
 {
-    diluSmoother_.smooth(psi, source, cmpt, nSweeps);
-    gsSmoother_.smooth(psi, source, cmpt, nSweeps);
+    scalarSmooth
+    (
+        psi,
+        ConstPrecisionAdaptor<solveScalar, scalar>(source),
+        cmpt,
+        nSweeps
+    );
 }
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.H
index c237ce6682cda55dfc41199c7c7b10ff35d0358c..8b5fb85ab35597b340bff05ddb6519896e0a0fc1 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -86,11 +86,20 @@ public:
         //- Smooth the solution for a given number of sweeps
         virtual void smooth
         (
-            scalarField& psi,
+            solveScalarField& psi,
             const scalarField& Source,
             const direction cmpt,
             const label nSweeps
         ) const;
+
+        //- Smooth the solution for a given number of sweeps
+        void scalarSmooth
+        (
+            solveScalarField& psi,
+            const solveScalarField& source,
+            const direction cmpt,
+            const label nSweeps
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/FDIC/FDICSmoother.C b/src/OpenFOAM/matrices/lduMatrix/smoothers/FDIC/FDICSmoother.C
index 4e3463563a36b75604fa5bcfd2b61f93e365e439..8c0e1a3cd5d7f9d8234697b1daff0cc6083df3e7 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/FDIC/FDICSmoother.C
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/FDIC/FDICSmoother.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -27,6 +27,7 @@ License
 
 #include "FDICSmoother.H"
 #include "FDICPreconditioner.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -73,8 +74,8 @@ Foam::FDICSmoother::FDICSmoother
     const scalar* const __restrict__ upperPtr =
         matrix_.upper().begin();
 
-    label nCells = rD_.size();
-    label nFaces = matrix_.upper().size();
+    const label nCells = rD_.size();
+    const label nFaces = matrix_.upper().size();
 
     for (label face=0; face<nFaces; face++)
     {
@@ -99,7 +100,7 @@ Foam::FDICSmoother::FDICSmoother
 
 void Foam::FDICSmoother::smooth
 (
-    scalarField& psi,
+    solveScalarField& psi,
     const scalarField& source,
     const direction cmpt,
     const label nSweeps
@@ -114,8 +115,8 @@ void Foam::FDICSmoother::smooth
         matrix_.lduAddr().lowerAddr().begin();
 
     // Temporary storage for the residual
-    scalarField rA(rD_.size());
-    scalar* __restrict__ rAPtr = rA.begin();
+    solveScalarField rA(rD_.size());
+    solveScalar* __restrict__ rAPtr = rA.begin();
 
     for (label sweep=0; sweep<nSweeps; sweep++)
     {
@@ -131,13 +132,13 @@ void Foam::FDICSmoother::smooth
 
         rA *= rD_;
 
-        label nFaces = matrix_.upper().size();
+        const label nFaces = matrix_.upper().size();
         for (label face=0; face<nFaces; face++)
         {
             rAPtr[uPtr[face]] -= rDuUpperPtr[face]*rAPtr[lPtr[face]];
         }
 
-        label nFacesM1 = nFaces - 1;
+        const label nFacesM1 = nFaces - 1;
         for (label face=nFacesM1; face>=0; face--)
         {
             rAPtr[lPtr[face]] -= rDlUpperPtr[face]*rAPtr[uPtr[face]];
@@ -148,4 +149,22 @@ void Foam::FDICSmoother::smooth
 }
 
 
+void Foam::FDICSmoother::scalarSmooth
+(
+    solveScalarField& psi,
+    const solveScalarField& source,
+    const direction cmpt,
+    const label nSweeps
+) const
+{
+    smooth
+    (
+        psi,
+        ConstPrecisionAdaptor<scalar, solveScalar>(source),
+        cmpt,
+        nSweeps
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/FDIC/FDICSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/FDIC/FDICSmoother.H
index ff32ab2dcb31edda8d097b67465513d41797fcbc..9825ed8599185e815e2eb57a1e401fd9743f9c2b 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/FDIC/FDICSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/FDIC/FDICSmoother.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2012 OpenFOAM Foundation
@@ -88,11 +88,20 @@ public:
         //- Smooth the solution for a given number of sweeps
         void smooth
         (
-            scalarField& psi,
+            solveScalarField& psi,
             const scalarField& source,
             const direction cmpt,
             const label nSweeps
         ) const;
+
+        //- Smooth the solution for a given number of sweeps
+        virtual void scalarSmooth
+        (
+            solveScalarField& psi,
+            const solveScalarField& source,
+            const direction cmpt,
+            const label nSweeps
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/GaussSeidel/GaussSeidelSmoother.C b/src/OpenFOAM/matrices/lduMatrix/smoothers/GaussSeidel/GaussSeidelSmoother.C
index b7363c30a0ef7996c45bfa8429c0522b4838fbd8..2b51fde682fa16d1ccff0c59547f52bfc1b986a0 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/GaussSeidel/GaussSeidelSmoother.C
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/GaussSeidel/GaussSeidelSmoother.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "GaussSeidelSmoother.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -68,21 +69,21 @@ Foam::GaussSeidelSmoother::GaussSeidelSmoother
 void Foam::GaussSeidelSmoother::smooth
 (
     const word& fieldName_,
-    scalarField& psi,
+    solveScalarField& psi,
     const lduMatrix& matrix_,
-    const scalarField& source,
+    const solveScalarField& source,
     const FieldField<Field, scalar>& interfaceBouCoeffs_,
     const lduInterfaceFieldPtrsList& interfaces_,
     const direction cmpt,
     const label nSweeps
 )
 {
-    scalar* __restrict__ psiPtr = psi.begin();
+    solveScalar* __restrict__ psiPtr = psi.begin();
 
     const label nCells = psi.size();
 
-    scalarField bPrime(nCells);
-    scalar* __restrict__ bPrimePtr = bPrime.begin();
+    solveScalarField bPrime(nCells);
+    solveScalar* __restrict__ bPrimePtr = bPrime.begin();
 
     const scalar* const __restrict__ diagPtr = matrix_.diag().begin();
     const scalar* const __restrict__ upperPtr =
@@ -133,7 +134,7 @@ void Foam::GaussSeidelSmoother::smooth
             cmpt
         );
 
-        scalar psii;
+        solveScalar psii;
         label fStart;
         label fEnd = ownStartPtr[0];
 
@@ -169,11 +170,33 @@ void Foam::GaussSeidelSmoother::smooth
 
 void Foam::GaussSeidelSmoother::smooth
 (
-    scalarField& psi,
+    solveScalarField& psi,
     const scalarField& source,
     const direction cmpt,
     const label nSweeps
 ) const
+{
+    smooth
+    (
+        fieldName_,
+        psi,
+        matrix_,
+        ConstPrecisionAdaptor<solveScalar, scalar>(source),
+        interfaceBouCoeffs_,
+        interfaces_,
+        cmpt,
+        nSweeps
+    );
+}
+
+
+void Foam::GaussSeidelSmoother::scalarSmooth
+(
+    solveScalarField& psi,
+    const solveScalarField& source,
+    const direction cmpt,
+    const label nSweeps
+) const
 {
     smooth
     (
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/GaussSeidel/GaussSeidelSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/GaussSeidel/GaussSeidelSmoother.H
index eba5b75b092bc583d142cef2bbc35be101ffa1f8..da40385dd9b740660c17ae76bb332c137273c894 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/GaussSeidel/GaussSeidelSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/GaussSeidel/GaussSeidelSmoother.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -81,9 +81,9 @@ public:
         static void smooth
         (
             const word& fieldName,
-            scalarField& psi,
+            solveScalarField& psi,
             const lduMatrix& matrix,
-            const scalarField& source,
+            const solveScalarField& source,
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
             const direction cmpt,
@@ -94,11 +94,20 @@ public:
         //- Smooth the solution for a given number of sweeps
         virtual void smooth
         (
-            scalarField& psi,
+            solveScalarField& psi,
             const scalarField& Source,
             const direction cmpt,
             const label nSweeps
         ) const;
+
+        //- Smooth the solution for a given number of sweeps
+        virtual void scalarSmooth
+        (
+            solveScalarField& psi,
+            const solveScalarField& Source,
+            const direction cmpt,
+            const label nSweeps
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/nonBlockingGaussSeidel/nonBlockingGaussSeidelSmoother.C b/src/OpenFOAM/matrices/lduMatrix/smoothers/nonBlockingGaussSeidel/nonBlockingGaussSeidelSmoother.C
index 6d282d18e2d0f4e3d1f9e73a6cc388f300ea86dc..9b1f9277ce260ea0ef129916d70735ac3e9355dd 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/nonBlockingGaussSeidel/nonBlockingGaussSeidelSmoother.C
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/nonBlockingGaussSeidel/nonBlockingGaussSeidelSmoother.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "nonBlockingGaussSeidelSmoother.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -95,22 +96,22 @@ Foam::nonBlockingGaussSeidelSmoother::nonBlockingGaussSeidelSmoother
 void Foam::nonBlockingGaussSeidelSmoother::smooth
 (
     const word& fieldName_,
-    scalarField& psi,
+    solveScalarField& psi,
     const lduMatrix& matrix_,
     const label blockStart,
-    const scalarField& source,
+    const solveScalarField& source,
     const FieldField<Field, scalar>& interfaceBouCoeffs_,
     const lduInterfaceFieldPtrsList& interfaces_,
     const direction cmpt,
     const label nSweeps
 )
 {
-    scalar* __restrict__ psiPtr = psi.begin();
+    solveScalar* __restrict__ psiPtr = psi.begin();
 
     const label nCells = psi.size();
 
-    scalarField bPrime(nCells);
-    scalar* __restrict__ bPrimePtr = bPrime.begin();
+    solveScalarField bPrime(nCells);
+    solveScalar* __restrict__ bPrimePtr = bPrime.begin();
 
     const scalar* const __restrict__ diagPtr = matrix_.diag().begin();
     const scalar* const __restrict__ upperPtr =
@@ -136,7 +137,6 @@ void Foam::nonBlockingGaussSeidelSmoother::smooth
     // To compensate for this, it is necessary to turn the
     // sign of the contribution.
 
-
     for (label sweep=0; sweep<nSweeps; sweep++)
     {
         bPrime = source;
@@ -151,7 +151,7 @@ void Foam::nonBlockingGaussSeidelSmoother::smooth
             cmpt
         );
 
-        scalar curPsi;
+        solveScalar curPsi;
         label fStart;
         label fEnd = ownStartPtr[0];
 
@@ -223,10 +223,10 @@ void Foam::nonBlockingGaussSeidelSmoother::smooth
 }
 
 
-void Foam::nonBlockingGaussSeidelSmoother::smooth
+void Foam::nonBlockingGaussSeidelSmoother::scalarSmooth
 (
-    scalarField& psi,
-    const scalarField& source,
+    solveScalarField& psi,
+    const solveScalarField& source,
     const direction cmpt,
     const label nSweeps
 ) const
@@ -246,4 +246,22 @@ void Foam::nonBlockingGaussSeidelSmoother::smooth
 }
 
 
+void Foam::nonBlockingGaussSeidelSmoother::smooth
+(
+    solveScalarField& psi,
+    const scalarField& source,
+    const direction cmpt,
+    const label nSweeps
+) const
+{
+    scalarSmooth
+    (
+        psi,
+        ConstPrecisionAdaptor<solveScalar, scalar>(source),
+        cmpt,
+        nSweeps
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/nonBlockingGaussSeidel/nonBlockingGaussSeidelSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/nonBlockingGaussSeidel/nonBlockingGaussSeidelSmoother.H
index 580518be081f896a0a06ebf1dfce7436fcf25476..b6edc00dc4b2a9a5f030de9a80992697e7939a6b 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/nonBlockingGaussSeidel/nonBlockingGaussSeidelSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/nonBlockingGaussSeidel/nonBlockingGaussSeidelSmoother.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -93,10 +93,10 @@ public:
         static void smooth
         (
             const word& fieldName,
-            scalarField& psi,
+            solveScalarField& psi,
             const lduMatrix& matrix,
             const label blockStart,
-            const scalarField& source,
+            const solveScalarField& source,
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
             const direction cmpt,
@@ -106,11 +106,20 @@ public:
         //- Smooth the solution for a given number of sweeps
         virtual void smooth
         (
-            scalarField& psi,
+            solveScalarField& psi,
             const scalarField& Source,
             const direction cmpt,
             const label nSweeps
         ) const;
+
+        //- Smooth the solution for a given number of sweeps
+        virtual void scalarSmooth
+        (
+            solveScalarField& psi,
+            const solveScalarField& source,
+            const direction cmpt,
+            const label nSweeps
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/symGaussSeidel/symGaussSeidelSmoother.C b/src/OpenFOAM/matrices/lduMatrix/smoothers/symGaussSeidel/symGaussSeidelSmoother.C
index 6bfd97cdc0bb80f2403980c06628ce9e13a3fff1..c0c44868d95b9167144841d1ab8d87e76900fbdb 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/symGaussSeidel/symGaussSeidelSmoother.C
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/symGaussSeidel/symGaussSeidelSmoother.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2012-2015 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "symGaussSeidelSmoother.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -68,21 +69,21 @@ Foam::symGaussSeidelSmoother::symGaussSeidelSmoother
 void Foam::symGaussSeidelSmoother::smooth
 (
     const word& fieldName_,
-    scalarField& psi,
+    solveScalarField& psi,
     const lduMatrix& matrix_,
-    const scalarField& source,
+    const solveScalarField& source,
     const FieldField<Field, scalar>& interfaceBouCoeffs_,
     const lduInterfaceFieldPtrsList& interfaces_,
     const direction cmpt,
     const label nSweeps
 )
 {
-    scalar* __restrict__ psiPtr = psi.begin();
+    solveScalar* __restrict__ psiPtr = psi.begin();
 
     const label nCells = psi.size();
 
-    scalarField bPrime(nCells);
-    scalar* __restrict__ bPrimePtr = bPrime.begin();
+    solveScalarField bPrime(nCells);
+    solveScalar* __restrict__ bPrimePtr = bPrime.begin();
 
     const scalar* const __restrict__ diagPtr = matrix_.diag().begin();
     const scalar* const __restrict__ upperPtr =
@@ -133,7 +134,7 @@ void Foam::symGaussSeidelSmoother::smooth
             cmpt
         );
 
-        scalar psii;
+        solveScalar psii;
         label fStart;
         label fEnd = ownStartPtr[0];
 
@@ -196,10 +197,10 @@ void Foam::symGaussSeidelSmoother::smooth
 }
 
 
-void Foam::symGaussSeidelSmoother::smooth
+void Foam::symGaussSeidelSmoother::scalarSmooth
 (
-    scalarField& psi,
-    const scalarField& source,
+    solveScalarField& psi,
+    const solveScalarField& source,
     const direction cmpt,
     const label nSweeps
 ) const
@@ -218,4 +219,22 @@ void Foam::symGaussSeidelSmoother::smooth
 }
 
 
+void Foam::symGaussSeidelSmoother::smooth
+(
+    solveScalarField& psi,
+    const scalarField& source,
+    const direction cmpt,
+    const label nSweeps
+) const
+{
+    scalarSmooth
+    (
+        psi,
+        ConstPrecisionAdaptor<solveScalar, scalar>(source),
+        cmpt,
+        nSweeps
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/symGaussSeidel/symGaussSeidelSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/symGaussSeidel/symGaussSeidelSmoother.H
index a18f87728e6f63df43e593b3d79c8b3659f86bef..92ecaa37b7fb4558516a0acadcb0fd6f863215a3 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/symGaussSeidel/symGaussSeidelSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/symGaussSeidel/symGaussSeidelSmoother.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2012 OpenFOAM Foundation
@@ -81,9 +81,9 @@ public:
         static void smooth
         (
             const word& fieldName,
-            scalarField& psi,
+            solveScalarField& psi,
             const lduMatrix& matrix,
-            const scalarField& source,
+            const solveScalarField& source,
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
             const direction cmpt,
@@ -94,11 +94,20 @@ public:
         //- Smooth the solution for a given number of sweeps
         virtual void smooth
         (
-            scalarField& psi,
+            solveScalarField& psi,
             const scalarField& Source,
             const direction cmpt,
             const label nSweeps
         ) const;
+
+        //- Smooth the solution for a given number of sweeps
+        virtual void scalarSmooth
+        (
+            solveScalarField& psi,
+            const solveScalarField& source,
+            const direction cmpt,
+            const label nSweeps
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H
index e746cb4ff546d5dc07ba090b2bb835289f672004..3736926650aa077a59494f1a9334848ff15a29cc 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -230,8 +230,8 @@ class GAMGSolver
         //- Interpolate the correction after injected prolongation
         void interpolate
         (
-            scalarField& psi,
-            scalarField& Apsi,
+            solveScalarField& psi,
+            solveScalarField& Apsi,
             const lduMatrix& m,
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
@@ -242,13 +242,13 @@ class GAMGSolver
         //  re-normalise
         void interpolate
         (
-            scalarField& psi,
-            scalarField& Apsi,
+            solveScalarField& psi,
+            solveScalarField& Apsi,
             const lduMatrix& m,
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
             const labelList& restrictAddressing,
-            const scalarField& psiC,
+            const solveScalarField& psiC,
             const direction cmpt
         ) const;
 
@@ -259,23 +259,23 @@ class GAMGSolver
         //  scaling factor.
         void scale
         (
-            scalarField& field,
-            scalarField& Acf,
+            solveScalarField& field,
+            solveScalarField& Acf,
             const lduMatrix& A,
             const FieldField<Field, scalar>& interfaceLevelBouCoeffs,
             const lduInterfaceFieldPtrsList& interfaceLevel,
-            const scalarField& source,
+            const solveScalarField& source,
             const direction cmpt
         ) const;
 
         //- Initialise the data structures for the V-cycle
         void initVcycle
         (
-            PtrList<scalarField>& coarseCorrFields,
-            PtrList<scalarField>& coarseSources,
+            PtrList<solveScalarField>& coarseCorrFields,
+            PtrList<solveScalarField>& coarseSources,
             PtrList<lduMatrix::smoother>& smoothers,
-            scalarField& scratch1,
-            scalarField& scratch2
+            solveScalarField& scratch1,
+            solveScalarField& scratch2
         ) const;
 
 
@@ -283,17 +283,17 @@ class GAMGSolver
         void Vcycle
         (
             const PtrList<lduMatrix::smoother>& smoothers,
-            scalarField& psi,
+            solveScalarField& psi,
             const scalarField& source,
-            scalarField& Apsi,
-            scalarField& finestCorrection,
-            scalarField& finestResidual,
+            solveScalarField& Apsi,
+            solveScalarField& finestCorrection,
+            solveScalarField& finestResidual,
 
-            scalarField& scratch1,
-            scalarField& scratch2,
+            solveScalarField& scratch1,
+            solveScalarField& scratch2,
 
-            PtrList<scalarField>& coarseCorrFields,
-            PtrList<scalarField>& coarseSources,
+            PtrList<solveScalarField>& coarseCorrFields,
+            PtrList<solveScalarField>& coarseSources,
             const direction cmpt=0
         ) const;
 
@@ -316,8 +316,8 @@ class GAMGSolver
         //- Solve the coarsest level with either an iterative or direct solver
         void solveCoarsestLevel
         (
-            scalarField& coarsestCorrField,
-            const scalarField& coarsestSource
+            solveScalarField& coarsestCorrField,
+            const solveScalarField& coarsestSource
         ) const;
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverInterpolate.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverInterpolate.C
index c8772f75a9c3192247d66bcc44495707e6115d45..3ea9443d2d41693d20caf32020e59b48aa923563 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverInterpolate.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverInterpolate.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2013-2015 OpenFOAM Foundation
@@ -31,15 +31,15 @@ License
 
 void Foam::GAMGSolver::interpolate
 (
-    scalarField& psi,
-    scalarField& Apsi,
+    solveScalarField& psi,
+    solveScalarField& Apsi,
     const lduMatrix& m,
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
     const direction cmpt
 ) const
 {
-    scalar* __restrict__ psiPtr = psi.begin();
+    solveScalar* __restrict__ psiPtr = psi.begin();
 
     const label* const __restrict__ uPtr = m.lduAddr().upperAddr().begin();
     const label* const __restrict__ lPtr = m.lduAddr().lowerAddr().begin();
@@ -49,7 +49,7 @@ void Foam::GAMGSolver::interpolate
     const scalar* const __restrict__ lowerPtr = m.lower().begin();
 
     Apsi = 0;
-    scalar* __restrict__ ApsiPtr = Apsi.begin();
+    solveScalar* __restrict__ ApsiPtr = Apsi.begin();
 
     m.initMatrixInterfaces
     (
@@ -88,13 +88,13 @@ void Foam::GAMGSolver::interpolate
 
 void Foam::GAMGSolver::interpolate
 (
-    scalarField& psi,
-    scalarField& Apsi,
+    solveScalarField& psi,
+    solveScalarField& Apsi,
     const lduMatrix& m,
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
     const labelList& restrictAddressing,
-    const scalarField& psiC,
+    const solveScalarField& psiC,
     const direction cmpt
 ) const
 {
@@ -109,17 +109,17 @@ void Foam::GAMGSolver::interpolate
     );
 
     const label nCells = m.diag().size();
-    scalar* __restrict__ psiPtr = psi.begin();
+    solveScalar* __restrict__ psiPtr = psi.begin();
     const scalar* const __restrict__ diagPtr = m.diag().begin();
-    const scalar* const __restrict__ psiCPtr = psiC.begin();
+    const solveScalar* const __restrict__ psiCPtr = psiC.begin();
 
 
     const label nCCells = psiC.size();
-    scalarField corrC(nCCells, 0);
-    scalar* __restrict__ corrCPtr = corrC.begin();
+    solveScalarField corrC(nCCells, 0);
+    solveScalar* __restrict__ corrCPtr = corrC.begin();
 
-    scalarField diagC(nCCells, 0);
-    scalar* __restrict__ diagCPtr = diagC.begin();
+    solveScalarField diagC(nCCells, 0);
+    solveScalar* __restrict__ diagCPtr = diagC.begin();
 
     for (label celli=0; celli<nCells; celli++)
     {
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverScale.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverScale.C
index 637cf3d34361c129fb16d27f3a100cbf6e33bda7..5df93c9e0af79e73e73a20893a3e650cebdd798a 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverScale.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverScale.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -32,12 +32,12 @@ License
 
 void Foam::GAMGSolver::scale
 (
-    scalarField& field,
-    scalarField& Acf,
+    solveScalarField& field,
+    solveScalarField& Acf,
     const lduMatrix& A,
     const FieldField<Field, scalar>& interfaceLevelBouCoeffs,
     const lduInterfaceFieldPtrsList& interfaceLevel,
-    const scalarField& source,
+    const solveScalarField& source,
     const direction cmpt
 ) const
 {
@@ -52,13 +52,13 @@ void Foam::GAMGSolver::scale
 
 
     const label nCells = field.size();
-    scalar* __restrict__ fieldPtr = field.begin();
-    const scalar* const __restrict__ sourcePtr = source.begin();
-    const scalar* const __restrict__ AcfPtr = Acf.begin();
+    solveScalar* __restrict__ fieldPtr = field.begin();
+    const solveScalar* const __restrict__ sourcePtr = source.begin();
+    const solveScalar* const __restrict__ AcfPtr = Acf.begin();
 
 
-    scalar scalingFactorNum = 0.0;
-    scalar scalingFactorDenom = 0.0;
+    solveScalar scalingFactorNum = 0.0;
+    solveScalar scalingFactorDenom = 0.0;
 
     for (label i=0; i<nCells; i++)
     {
@@ -66,10 +66,12 @@ void Foam::GAMGSolver::scale
         scalingFactorDenom += AcfPtr[i]*fieldPtr[i];
     }
 
-    vector2D scalingVector(scalingFactorNum, scalingFactorDenom);
-    A.mesh().reduce(scalingVector, sumOp<vector2D>());
+    Vector2D<solveScalar> scalingVector(scalingFactorNum, scalingFactorDenom);
+    A.mesh().reduce(scalingVector, sumOp<Vector2D<solveScalar>>());
 
-    const scalar sf = scalingVector.x()/stabilise(scalingVector.y(), VSMALL);
+    const solveScalar sf =
+        scalingVector.x()
+       /stabilise(scalingVector.y(), pTraits<solveScalar>::vsmall);
 
     if (debug >= 2)
     {
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C
index 8f67c9a6d4ee5616bdee14acb3dda7f42b542b3c..0184d34ca080c03888f0af841f4d5db970c0b46c 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -29,29 +29,36 @@ License
 #include "PCG.H"
 #include "PBiCGStab.H"
 #include "SubField.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 Foam::solverPerformance Foam::GAMGSolver::solve
 (
-    scalarField& psi,
+    scalarField& psi_s,
     const scalarField& source,
     const direction cmpt
 ) const
 {
+    PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
+    solveScalarField& psi = tpsi.constCast();
+
+    ConstPrecisionAdaptor<solveScalar, scalar> tsource(source);
+
     // Setup class containing solver performance data
     solverPerformance solverPerf(typeName, fieldName_);
 
     // Calculate A.psi used to calculate the initial residual
-    scalarField Apsi(psi.size());
+    solveScalarField Apsi(psi.size());
     matrix_.Amul(Apsi, psi, interfaceBouCoeffs_, interfaces_, cmpt);
 
     // Create the storage for the finestCorrection which may be used as a
     // temporary in normFactor
-    scalarField finestCorrection(psi.size());
+    solveScalarField finestCorrection(psi.size());
 
     // Calculate normalisation factor
-    scalar normFactor = this->normFactor(psi, source, Apsi, finestCorrection);
+    solveScalar normFactor =
+        this->normFactor(psi, tsource(), Apsi, finestCorrection);
 
     if (debug >= 2)
     {
@@ -59,9 +66,14 @@ Foam::solverPerformance Foam::GAMGSolver::solve
     }
 
     // Calculate initial finest-grid residual field
-    scalarField finestResidual(source - Apsi);
+    solveScalarField finestResidual(tsource() - Apsi);
 
-    matrix().setResidualField(finestResidual, fieldName_, true);
+    matrix().setResidualField
+    (
+        ConstPrecisionAdaptor<scalar, solveScalar>(finestResidual)(),
+        fieldName_,
+        true
+    );
 
     // Calculate normalised residual for convergence test
     solverPerf.initialResidual() = gSumMag
@@ -80,18 +92,18 @@ Foam::solverPerformance Foam::GAMGSolver::solve
     )
     {
         // Create coarse grid correction fields
-        PtrList<scalarField> coarseCorrFields;
+        PtrList<solveScalarField> coarseCorrFields;
 
         // Create coarse grid sources
-        PtrList<scalarField> coarseSources;
+        PtrList<solveScalarField> coarseSources;
 
         // Create the smoothers for all levels
         PtrList<lduMatrix::smoother> smoothers;
 
         // Scratch fields if processor-agglomerated coarse level meshes
         // are bigger than original. Usually not needed
-        scalarField scratch1;
-        scalarField scratch2;
+        solveScalarField scratch1;
+        solveScalarField scratch2;
 
         // Initialise the above data structures
         initVcycle
@@ -124,7 +136,7 @@ Foam::solverPerformance Foam::GAMGSolver::solve
 
             // Calculate finest level residual field
             matrix_.Amul(Apsi, psi, interfaceBouCoeffs_, interfaces_, cmpt);
-            finestResidual = source;
+            finestResidual = tsource();
             finestResidual -= Apsi;
 
             solverPerf.finalResidual() = gSumMag
@@ -147,7 +159,12 @@ Foam::solverPerformance Foam::GAMGSolver::solve
         );
     }
 
-    matrix().setResidualField(finestResidual, fieldName_, false);
+    matrix().setResidualField
+    (
+        ConstPrecisionAdaptor<scalar, solveScalar>(finestResidual)(),
+        fieldName_,
+        false
+    );
 
     return solverPerf;
 }
@@ -156,17 +173,17 @@ Foam::solverPerformance Foam::GAMGSolver::solve
 void Foam::GAMGSolver::Vcycle
 (
     const PtrList<lduMatrix::smoother>& smoothers,
-    scalarField& psi,
+    solveScalarField& psi,
     const scalarField& source,
-    scalarField& Apsi,
-    scalarField& finestCorrection,
-    scalarField& finestResidual,
+    solveScalarField& Apsi,
+    solveScalarField& finestCorrection,
+    solveScalarField& finestResidual,
 
-    scalarField& scratch1,
-    scalarField& scratch2,
+    solveScalarField& scratch1,
+    solveScalarField& scratch2,
 
-    PtrList<scalarField>& coarseCorrFields,
-    PtrList<scalarField>& coarseSources,
+    PtrList<solveScalarField>& coarseCorrFields,
+    PtrList<solveScalarField>& coarseSources,
     const direction cmpt
 ) const
 {
@@ -194,10 +211,10 @@ void Foam::GAMGSolver::Vcycle
             {
                 coarseCorrFields[leveli] = 0.0;
 
-                smoothers[leveli + 1].smooth
+                smoothers[leveli + 1].scalarSmooth
                 (
                     coarseCorrFields[leveli],
-                    coarseSources[leveli],
+                    coarseSources[leveli],  //coarseSource,
                     cmpt,
                     min
                     (
@@ -206,7 +223,7 @@ void Foam::GAMGSolver::Vcycle
                     )
                 );
 
-                scalarField::subField ACf
+                solveScalarField::subField ACf
                 (
                     scratch1,
                     coarseCorrFields[leveli].size()
@@ -219,9 +236,9 @@ void Foam::GAMGSolver::Vcycle
                     scale
                     (
                         coarseCorrFields[leveli],
-                        const_cast<scalarField&>
+                        const_cast<solveScalarField&>
                         (
-                            ACf.operator const scalarField&()
+                            ACf.operator const solveScalarField&()
                         ),
                         matrixLevels_[leveli],
                         interfaceLevelsBouCoeffs_[leveli],
@@ -234,9 +251,9 @@ void Foam::GAMGSolver::Vcycle
                 // Correct the residual with the new solution
                 matrixLevels_[leveli].Amul
                 (
-                    const_cast<scalarField&>
+                    const_cast<solveScalarField&>
                     (
-                        ACf.operator const scalarField&()
+                        ACf.operator const solveScalarField&()
                     ),
                     coarseCorrFields[leveli],
                     interfaceLevelsBouCoeffs_[leveli],
@@ -282,7 +299,7 @@ void Foam::GAMGSolver::Vcycle
     // Smoothing and prolongation of the coarse correction fields
     // (going to finer levels)
 
-    scalarField dummyField(0);
+    solveScalarField dummyField(0);
 
     for (label leveli = coarsestLevel - 1; leveli >= 0; leveli--)
     {
@@ -291,7 +308,7 @@ void Foam::GAMGSolver::Vcycle
             // Create a field for the pre-smoothed correction field
             // as a sub-field of the finestCorrection which is not
             // currently being used
-            scalarField::subField preSmoothedCoarseCorrField
+            solveScalarField::subField preSmoothedCoarseCorrField
             (
                 scratch2,
                 coarseCorrFields[leveli].size()
@@ -318,13 +335,16 @@ void Foam::GAMGSolver::Vcycle
 
 
             // Create A.psi for this coarse level as a sub-field of Apsi
-            scalarField::subField ACf
+            solveScalarField::subField ACf
             (
                scratch1,
                 coarseCorrFields[leveli].size()
             );
-            scalarField& ACfRef =
-                const_cast<scalarField&>(ACf.operator const scalarField&());
+            solveScalarField& ACfRef =
+                const_cast
+                <
+                    solveScalarField&
+                >(ACf.operator const solveScalarField&());
 
             if (interpolateCorrection_) //&& leveli < coarsestLevel - 2)
             {
@@ -383,10 +403,10 @@ void Foam::GAMGSolver::Vcycle
                 coarseCorrFields[leveli] += preSmoothedCoarseCorrField;
             }
 
-            smoothers[leveli + 1].smooth
+            smoothers[leveli + 1].scalarSmooth
             (
                 coarseCorrFields[leveli],
-                coarseSources[leveli],
+                coarseSources[leveli],  //coarseSource,
                 cmpt,
                 min
                 (
@@ -453,11 +473,11 @@ void Foam::GAMGSolver::Vcycle
 
 void Foam::GAMGSolver::initVcycle
 (
-    PtrList<scalarField>& coarseCorrFields,
-    PtrList<scalarField>& coarseSources,
+    PtrList<solveScalarField>& coarseCorrFields,
+    PtrList<solveScalarField>& coarseSources,
     PtrList<lduMatrix::smoother>& smoothers,
-    scalarField& scratch1,
-    scalarField& scratch2
+    solveScalarField& scratch1,
+    solveScalarField& scratch2
 ) const
 {
     label maxSize = matrix_.diag().size();
@@ -487,7 +507,7 @@ void Foam::GAMGSolver::initVcycle
         {
             label nCoarseCells = agglomeration_.nCells(leveli);
 
-            coarseSources.set(leveli, new scalarField(nCoarseCells));
+            coarseSources.set(leveli, new solveScalarField(nCoarseCells));
         }
 
         if (matrixLevels_.set(leveli))
@@ -498,7 +518,7 @@ void Foam::GAMGSolver::initVcycle
 
             maxSize = max(maxSize, nCoarseCells);
 
-            coarseCorrFields.set(leveli, new scalarField(nCoarseCells));
+            coarseCorrFields.set(leveli, new solveScalarField(nCoarseCells));
 
             smoothers.set
             (
@@ -555,8 +575,8 @@ Foam::dictionary Foam::GAMGSolver::PBiCGStabSolverDict
 
 void Foam::GAMGSolver::solveCoarsestLevel
 (
-    scalarField& coarsestCorrField,
-    const scalarField& coarsestSource
+    solveScalarField& coarsestCorrField,
+    const solveScalarField& coarsestSource
 ) const
 {
     const label coarsestLevel = matrixLevels_.size() - 1;
@@ -565,7 +585,18 @@ void Foam::GAMGSolver::solveCoarsestLevel
 
     if (directSolveCoarsest_)
     {
-        coarsestLUMatrixPtr_->solve(coarsestCorrField, coarsestSource);
+        PrecisionAdaptor<scalar, solveScalar> tcorrField
+        (
+            coarsestCorrField
+        );
+        coarsestLUMatrixPtr_->solve
+        (
+            tcorrField.constCast(),
+            ConstPrecisionAdaptor<scalar, solveScalar>
+            (
+                coarsestSource
+            )()
+        );
     }
     //else if
     //(
@@ -681,7 +712,7 @@ void Foam::GAMGSolver::solveCoarsestLevel
                 interfaceLevelsIntCoeffs_[coarsestLevel],
                 interfaceLevels_[coarsestLevel],
                 PBiCGStabSolverDict(tolerance_, relTol_)
-            ).solve
+            ).scalarSolve
             (
                 coarsestCorrField,
                 coarsestSource
@@ -697,7 +728,7 @@ void Foam::GAMGSolver::solveCoarsestLevel
                 interfaceLevelsIntCoeffs_[coarsestLevel],
                 interfaceLevels_[coarsestLevel],
                 PCGsolverDict(tolerance_, relTol_)
-            ).solve
+            ).scalarSolve
             (
                 coarsestCorrField,
                 coarsestSource
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C
index e091061153fb145628c9c1446c923d9bab816c0b..57f0f7e58c695d999ece7a4d8ed206eb34e79133 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -110,16 +110,16 @@ Foam::cyclicGAMGInterfaceField::~cyclicGAMGInterfaceField()
 
 void Foam::cyclicGAMGInterfaceField::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
 ) const
 {
     // Get neighbouring field
-    scalarField pnf
+    solveScalarField pnf
     (
         cyclicInterface_.neighbPatch().interfaceInternalField(psiInternal)
     );
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.H
index cf61db8ced486fd3fe012129559c0a2e099ea4bf..6cfa522af5f7286a444b1afc154bb683e28bd870 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -147,9 +147,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C
index 577284304c4d3ebcb9435877b280ba29092b4b55..c08448ecf338b40259f65102f1741f361255eda4 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -94,9 +94,9 @@ Foam::processorGAMGInterfaceField::~processorGAMGInterfaceField()
 
 void Foam::processorGAMGInterfaceField::initInterfaceMatrixUpdate
 (
-    scalarField&,
+    solveScalarField&,
     const bool,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField&,
     const direction,
     const Pstream::commsTypes commsType
@@ -145,9 +145,9 @@ void Foam::processorGAMGInterfaceField::initInterfaceMatrixUpdate
 
 void Foam::processorGAMGInterfaceField::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField&,
+    const solveScalarField&,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
@@ -187,9 +187,13 @@ void Foam::processorGAMGInterfaceField::updateInterfaceMatrix
     }
     else
     {
-        scalarField pnf
+        solveScalarField pnf
         (
-            procInterface_.compressedReceive<scalar>(commsType, coeffs.size())
+            procInterface_.compressedReceive<solveScalar>
+            (
+                commsType,
+                coeffs.size()
+            )
         );
         transformCoupleField(pnf, cmpt);
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H
index aefd80bde4973b283e47cd4d8d3baf8ba17e617c..9f30216a016905a4bf316906e40edbca14d187f7 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2014 OpenFOAM Foundation
@@ -76,10 +76,10 @@ class processorGAMGInterfaceField
             mutable label outstandingRecvRequest_;
 
             //- Scalar send buffer
-            mutable Field<scalar> scalarSendBuf_;
+            mutable solveScalarField scalarSendBuf_;
 
             //- Scalar receive buffer
-            mutable Field<scalar> scalarReceiveBuf_;
+            mutable solveScalarField scalarReceiveBuf_;
 
 
 
@@ -139,9 +139,9 @@ public:
             //- Initialise neighbour matrix update
             virtual void initInterfaceMatrixUpdate
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
@@ -150,9 +150,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C
index ccedc43c73d42866b49fdd8b12fb4d5ee5b51356..9545b9cf893f8e3e82ced5b3d968d04cceafbff9 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "PBiCG.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -66,11 +67,14 @@ Foam::PBiCG::PBiCG
 
 Foam::solverPerformance Foam::PBiCG::solve
 (
-    scalarField& psi,
+    scalarField& psi_s,
     const scalarField& source,
     const direction cmpt
 ) const
 {
+    PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
+    solveScalarField& psi = tpsi.constCast();
+
     // --- Setup class containing solver performance data
     solverPerformance solverPerf
     (
@@ -80,25 +84,31 @@ Foam::solverPerformance Foam::PBiCG::solve
 
     const label nCells = psi.size();
 
-    scalar* __restrict__ psiPtr = psi.begin();
+    solveScalar* __restrict__ psiPtr = psi.begin();
 
-    scalarField pA(nCells);
-    scalar* __restrict__ pAPtr = pA.begin();
+    solveScalarField pA(nCells);
+    solveScalar* __restrict__ pAPtr = pA.begin();
 
-    scalarField wA(nCells);
-    scalar* __restrict__ wAPtr = wA.begin();
+    solveScalarField wA(nCells);
+    solveScalar* __restrict__ wAPtr = wA.begin();
 
     // --- Calculate A.psi
     matrix_.Amul(wA, psi, interfaceBouCoeffs_, interfaces_, cmpt);
 
     // --- Calculate initial residual field
-    scalarField rA(source - wA);
-    scalar* __restrict__ rAPtr = rA.begin();
+    ConstPrecisionAdaptor<solveScalar, scalar> tsource(source);
+    solveScalarField rA(tsource() - wA);
+    solveScalar* __restrict__ rAPtr = rA.begin();
 
-    matrix().setResidualField(rA, fieldName_, true);
+    matrix().setResidualField
+    (
+        ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),
+        fieldName_,
+        false
+    );
 
     // --- Calculate normalisation factor
-    const scalar normFactor = this->normFactor(psi, source, wA, pA);
+    const solveScalar normFactor = this->normFactor(psi, tsource(), wA, pA);
 
     if (lduMatrix::debug >= 2)
     {
@@ -118,21 +128,21 @@ Foam::solverPerformance Foam::PBiCG::solve
      || !solverPerf.checkConvergence(tolerance_, relTol_)
     )
     {
-        scalarField pT(nCells, 0);
-        scalar* __restrict__ pTPtr = pT.begin();
+        solveScalarField pT(nCells, 0);
+        solveScalar* __restrict__ pTPtr = pT.begin();
 
-        scalarField wT(nCells);
-        scalar* __restrict__ wTPtr = wT.begin();
+        solveScalarField wT(nCells);
+        solveScalar* __restrict__ wTPtr = wT.begin();
 
         // --- Calculate T.psi
         matrix_.Tmul(wT, psi, interfaceIntCoeffs_, interfaces_, cmpt);
 
         // --- Calculate initial transpose residual field
-        scalarField rT(source - wT);
-        scalar* __restrict__ rTPtr = rT.begin();
+        solveScalarField rT(tsource() - wT);
+        solveScalar* __restrict__ rTPtr = rT.begin();
 
         // --- Initial value not used
-        scalar wArT = 0;
+        solveScalar wArT = 0;
 
         // --- Select and construct the preconditioner
         autoPtr<lduMatrix::preconditioner> preconPtr =
@@ -146,7 +156,7 @@ Foam::solverPerformance Foam::PBiCG::solve
         do
         {
             // --- Store previous wArT
-            const scalar wArTold = wArT;
+            const solveScalar wArTold = wArT;
 
             // --- Precondition residuals
             preconPtr->precondition(wA, rA, cmpt);
@@ -165,7 +175,7 @@ Foam::solverPerformance Foam::PBiCG::solve
             }
             else
             {
-                const scalar beta = wArT/wArTold;
+                const solveScalar beta = wArT/wArTold;
 
                 for (label cell=0; cell<nCells; cell++)
                 {
@@ -179,7 +189,7 @@ Foam::solverPerformance Foam::PBiCG::solve
             matrix_.Amul(wA, pA, interfaceBouCoeffs_, interfaces_, cmpt);
             matrix_.Tmul(wT, pT, interfaceIntCoeffs_, interfaces_, cmpt);
 
-            const scalar wApT = gSumProd(wA, pT, matrix().mesh().comm());
+            const solveScalar wApT = gSumProd(wA, pT, matrix().mesh().comm());
 
             // --- Test for singularity
             if (solverPerf.checkSingularity(mag(wApT)/normFactor))
@@ -190,7 +200,7 @@ Foam::solverPerformance Foam::PBiCG::solve
 
             // --- Update solution and residual:
 
-            const scalar alpha = wArT/wApT;
+            const solveScalar alpha = wArT/wApT;
 
             for (label cell=0; cell<nCells; cell++)
             {
@@ -222,7 +232,12 @@ Foam::solverPerformance Foam::PBiCG::solve
             << exit(FatalError);
     }
 
-    matrix().setResidualField(rA, fieldName_, false);
+    matrix().setResidualField
+    (
+        ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),
+        fieldName_,
+        false
+    );
 
     return solverPerf;
 }
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C
index 1e343565fb7ce81d4126db542fe2ee3b768e2389..7ec60707c1bf4d26c394f46bf02f7e3e5fbe78e5 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "PBiCGStab.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -67,10 +68,10 @@ Foam::PBiCGStab::PBiCGStab
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-Foam::solverPerformance Foam::PBiCGStab::solve
+Foam::solverPerformance Foam::PBiCGStab::scalarSolve
 (
-    scalarField& psi,
-    const scalarField& source,
+    solveScalarField& psi,
+    const solveScalarField& source,
     const direction cmpt
 ) const
 {
@@ -83,25 +84,30 @@ Foam::solverPerformance Foam::PBiCGStab::solve
 
     const label nCells = psi.size();
 
-    scalar* __restrict__ psiPtr = psi.begin();
+    solveScalar* __restrict__ psiPtr = psi.begin();
 
-    scalarField pA(nCells);
-    scalar* __restrict__ pAPtr = pA.begin();
+    solveScalarField pA(nCells);
+    solveScalar* __restrict__ pAPtr = pA.begin();
 
-    scalarField yA(nCells);
-    scalar* __restrict__ yAPtr = yA.begin();
+    solveScalarField yA(nCells);
+    solveScalar* __restrict__ yAPtr = yA.begin();
 
     // --- Calculate A.psi
     matrix_.Amul(yA, psi, interfaceBouCoeffs_, interfaces_, cmpt);
 
     // --- Calculate initial residual field
-    scalarField rA(source - yA);
-    scalar* __restrict__ rAPtr = rA.begin();
+    solveScalarField rA(source - yA);
+    solveScalar* __restrict__ rAPtr = rA.begin();
 
-    matrix().setResidualField(rA, fieldName_, true);
+    matrix().setResidualField
+    (
+        ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),
+        fieldName_,
+        true
+    );
 
     // --- Calculate normalisation factor
-    const scalar normFactor = this->normFactor(psi, source, yA, pA);
+    const solveScalar normFactor = this->normFactor(psi, source, yA, pA);
 
     if (lduMatrix::debug >= 2)
     {
@@ -121,25 +127,25 @@ Foam::solverPerformance Foam::PBiCGStab::solve
      || !solverPerf.checkConvergence(tolerance_, relTol_)
     )
     {
-        scalarField AyA(nCells);
-        scalar* __restrict__ AyAPtr = AyA.begin();
+        solveScalarField AyA(nCells);
+        solveScalar* __restrict__ AyAPtr = AyA.begin();
 
-        scalarField sA(nCells);
-        scalar* __restrict__ sAPtr = sA.begin();
+        solveScalarField sA(nCells);
+        solveScalar* __restrict__ sAPtr = sA.begin();
 
-        scalarField zA(nCells);
-        scalar* __restrict__ zAPtr = zA.begin();
+        solveScalarField zA(nCells);
+        solveScalar* __restrict__ zAPtr = zA.begin();
 
-        scalarField tA(nCells);
-        scalar* __restrict__ tAPtr = tA.begin();
+        solveScalarField tA(nCells);
+        solveScalar* __restrict__ tAPtr = tA.begin();
 
         // --- Store initial residual
-        const scalarField rA0(rA);
+        const solveScalarField rA0(rA);
 
         // --- Initial values not used
-        scalar rA0rA = 0;
-        scalar alpha = 0;
-        scalar omega = 0;
+        solveScalar rA0rA = 0;
+        solveScalar alpha = 0;
+        solveScalar omega = 0;
 
         // --- Select and construct the preconditioner
         autoPtr<lduMatrix::preconditioner> preconPtr =
@@ -153,7 +159,7 @@ Foam::solverPerformance Foam::PBiCGStab::solve
         do
         {
             // --- Store previous rA0rA
-            const scalar rA0rAold = rA0rA;
+            const solveScalar rA0rAold = rA0rA;
 
             rA0rA = gSumProd(rA0, rA, matrix().mesh().comm());
 
@@ -179,7 +185,7 @@ Foam::solverPerformance Foam::PBiCGStab::solve
                     break;
                 }
 
-                const scalar beta = (rA0rA/rA0rAold)*(alpha/omega);
+                const solveScalar beta = (rA0rA/rA0rAold)*(alpha/omega);
 
                 for (label cell=0; cell<nCells; cell++)
                 {
@@ -194,7 +200,8 @@ Foam::solverPerformance Foam::PBiCGStab::solve
             // --- Calculate AyA
             matrix_.Amul(AyA, yA, interfaceBouCoeffs_, interfaces_, cmpt);
 
-            const scalar rA0AyA = gSumProd(rA0, AyA, matrix().mesh().comm());
+            const solveScalar rA0AyA =
+                gSumProd(rA0, AyA, matrix().mesh().comm());
 
             alpha = rA0rA/rA0AyA;
 
@@ -230,7 +237,7 @@ Foam::solverPerformance Foam::PBiCGStab::solve
             // --- Calculate tA
             matrix_.Amul(tA, zA, interfaceBouCoeffs_, interfaces_, cmpt);
 
-            const scalar tAtA = gSumSqr(tA, matrix().mesh().comm());
+            const solveScalar tAtA = gSumSqr(tA, matrix().mesh().comm());
 
             // --- Calculate omega from tA and sA
             //     (cheaper than using zA with preconditioned tA)
@@ -256,10 +263,34 @@ Foam::solverPerformance Foam::PBiCGStab::solve
         );
     }
 
-    matrix().setResidualField(rA, fieldName_, false);
+    matrix().setResidualField
+    (
+        ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),
+        fieldName_,
+        false
+    );
 
     return solverPerf;
 }
 
 
+Foam::solverPerformance Foam::PBiCGStab::solve
+(
+    scalarField& psi_s,
+    const scalarField& source,
+    const direction cmpt
+) const
+{
+    PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
+    solveScalarField& psi = tpsi.constCast();
+
+    return scalarSolve
+    (
+        psi,
+        ConstPrecisionAdaptor<solveScalar, scalar>(source)(),
+        cmpt
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.H b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.H
index 0ea17bfb4643b5a664b70795cf3c425f9f379c23..6c4771e9727bc2be85835d5e4583a7cef0cd1500 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.H
@@ -104,6 +104,14 @@ public:
 
     // Member Functions
 
+        //- Solve the matrix with this solver
+        virtual solverPerformance scalarSolve
+        (
+            solveScalarField& psi,
+            const solveScalarField& source,
+            const direction cmpt = 0
+        ) const;
+
         //- Solve the matrix with this solver
         virtual solverPerformance solve
         (
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C
index c6ed93e1c28cbe97832a4f145ebe49c3564c56cc..5c408d02dae6147db25c9cbaa04d60d6c2d5d6f2 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "PCG.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -64,10 +65,10 @@ Foam::PCG::PCG
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-Foam::solverPerformance Foam::PCG::solve
+Foam::solverPerformance Foam::PCG::scalarSolve
 (
-    scalarField& psi,
-    const scalarField& source,
+    solveScalarField& psi,
+    const solveScalarField& source,
     const direction cmpt
 ) const
 {
@@ -80,28 +81,33 @@ Foam::solverPerformance Foam::PCG::solve
 
     label nCells = psi.size();
 
-    scalar* __restrict__ psiPtr = psi.begin();
+    solveScalar* __restrict__ psiPtr = psi.begin();
 
-    scalarField pA(nCells);
-    scalar* __restrict__ pAPtr = pA.begin();
+    solveScalarField pA(nCells);
+    solveScalar* __restrict__ pAPtr = pA.begin();
 
-    scalarField wA(nCells);
-    scalar* __restrict__ wAPtr = wA.begin();
+    solveScalarField wA(nCells);
+    solveScalar* __restrict__ wAPtr = wA.begin();
 
-    scalar wArA = solverPerf.great_;
-    scalar wArAold = wArA;
+    solveScalar wArA = solverPerf.great_;
+    solveScalar wArAold = wArA;
 
     // --- Calculate A.psi
     matrix_.Amul(wA, psi, interfaceBouCoeffs_, interfaces_, cmpt);
 
     // --- Calculate initial residual field
-    scalarField rA(source - wA);
-    scalar* __restrict__ rAPtr = rA.begin();
+    solveScalarField rA(source - wA);
+    solveScalar* __restrict__ rAPtr = rA.begin();
 
-    matrix().setResidualField(rA, fieldName_, true);
+    matrix().setResidualField
+    (
+        ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),
+        fieldName_,
+        false
+    );
 
     // --- Calculate normalisation factor
-    scalar normFactor = this->normFactor(psi, source, wA, pA);
+    solveScalar normFactor = this->normFactor(psi, source, wA, pA);
 
     if (lduMatrix::debug >= 2)
     {
@@ -150,7 +156,7 @@ Foam::solverPerformance Foam::PCG::solve
             }
             else
             {
-                scalar beta = wArA/wArAold;
+                solveScalar beta = wArA/wArAold;
 
                 for (label cell=0; cell<nCells; cell++)
                 {
@@ -162,8 +168,7 @@ Foam::solverPerformance Foam::PCG::solve
             // --- Update preconditioned residual
             matrix_.Amul(wA, pA, interfaceBouCoeffs_, interfaces_, cmpt);
 
-            scalar wApA = gSumProd(wA, pA, matrix().mesh().comm());
-
+            solveScalar wApA = gSumProd(wA, pA, matrix().mesh().comm());
 
             // --- Test for singularity
             if (solverPerf.checkSingularity(mag(wApA)/normFactor)) break;
@@ -171,7 +176,7 @@ Foam::solverPerformance Foam::PCG::solve
 
             // --- Update solution and residual:
 
-            scalar alpha = wArA/wApA;
+            solveScalar alpha = wArA/wApA;
 
             for (label cell=0; cell<nCells; cell++)
             {
@@ -193,10 +198,33 @@ Foam::solverPerformance Foam::PCG::solve
         );
     }
 
-    matrix().setResidualField(rA, fieldName_, false);
+    matrix().setResidualField
+    (
+        ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),
+        fieldName_,
+        false
+    );
 
     return solverPerf;
 }
 
 
+
+Foam::solverPerformance Foam::PCG::solve
+(
+    scalarField& psi_s,
+    const scalarField& source,
+    const direction cmpt
+) const
+{
+    PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
+    return scalarSolve
+    (
+        tpsi.constCast(),
+        ConstPrecisionAdaptor<solveScalar, scalar>(source)(),
+        cmpt
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.H b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.H
index 3b077ae2c453b8fdc04c1077cc15d067d89e64e7..b09067ce46c0b1e229ee364e25646ef04b8cf825 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.H
@@ -92,6 +92,14 @@ public:
 
     // Member Functions
 
+        //- Solve the matrix with this solver
+        virtual solverPerformance scalarSolve
+        (
+            solveScalarField& psi,
+            const solveScalarField& source,
+            const direction cmpt=0
+        ) const;
+
         //- Solve the matrix with this solver
         virtual solverPerformance solve
         (
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
index 43977e444111bfb2bfbccc212c797995e791e92b..47e11f4fdf32d686f5cff2a6a1a3ea1b83899078 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2014 OpenFOAM Foundation
@@ -27,6 +27,7 @@ License
 
 #include "smoothSolver.H"
 #include "profiling.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -79,11 +80,14 @@ void Foam::smoothSolver::readControls()
 
 Foam::solverPerformance Foam::smoothSolver::solve
 (
-    scalarField& psi,
+    scalarField& psi_s,
     const scalarField& source,
     const direction cmpt
 ) const
 {
+    PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
+    solveScalarField& psi = tpsi.constCast();
+
     // Setup class containing solver performance data
     solverPerformance solverPerf(typeName, fieldName_);
 
@@ -114,22 +118,29 @@ Foam::solverPerformance Foam::smoothSolver::solve
     }
     else
     {
-        scalar normFactor = 0;
-        scalarField residual;
+        solveScalar normFactor = 0;
+        solveScalarField residual;
+
+        ConstPrecisionAdaptor<solveScalar, scalar> tsource(source);
 
         {
-            scalarField Apsi(psi.size());
-            scalarField temp(psi.size());
+            solveScalarField Apsi(psi.size());
+            solveScalarField temp(psi.size());
 
             // Calculate A.psi
             matrix_.Amul(Apsi, psi, interfaceBouCoeffs_, interfaces_, cmpt);
 
             // Calculate normalisation factor
-            normFactor = this->normFactor(psi, source, Apsi, temp);
+            normFactor = this->normFactor(psi, tsource(), Apsi, temp);
 
-            residual = source - Apsi;
+            residual = tsource() - Apsi;
 
-            matrix().setResidualField(residual, fieldName_, true);
+            matrix().setResidualField
+            (
+                ConstPrecisionAdaptor<scalar, solveScalar>(residual)(),
+                fieldName_,
+                false
+            );
 
             // Calculate residual magnitude
             solverPerf.initialResidual() =
@@ -197,7 +208,12 @@ Foam::solverPerformance Foam::smoothSolver::solve
             );
         }
 
-        matrix().setResidualField(residual, fieldName_, false);
+        matrix().setResidualField
+        (
+            ConstPrecisionAdaptor<scalar, solveScalar>(residual)(),
+            fieldName_,
+            false
+        );
     }
 
     return solverPerf;
diff --git a/src/OpenFOAM/primitives/Scalar/Scalar.H b/src/OpenFOAM/primitives/Scalar/Scalar.H
index 0d171b29f06854b81a0dcedea4a0d55d91fd2d8b..7caea028a0697118af94c48dc45c087a753ac54b 100644
--- a/src/OpenFOAM/primitives/Scalar/Scalar.H
+++ b/src/OpenFOAM/primitives/Scalar/Scalar.H
@@ -52,10 +52,14 @@ public:
     //- Component type
     typedef Scalar cmptType;
 
+    //- Magnitude type
+    typedef Scalar magType;
+
     //- Equivalent type of labels used for valid component indexing
     typedef label labelType;
 
 
+
     // Member constants
 
         //- Dimensionality of space
diff --git a/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H b/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H
index 5fbb29aed0b6eee33b80c2f5f290e960c0bbf579..738da8248c25d9dc2ca86d9014155025bfece18f 100644
--- a/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H
+++ b/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H
@@ -88,6 +88,9 @@ public:
     //- Component type
     typedef Cmpt cmptType;
 
+    //- Magnitude type
+    typedef Cmpt magType;
+
 
     // Static Constants
 
diff --git a/src/OpenFOAM/primitives/VectorSpace/products.H b/src/OpenFOAM/primitives/VectorSpace/products.H
index b8c7a2180cb8a383587d65c1c8d918c0db016b30..8e7de125084ddc86933c1df16891f60cdf12628c 100644
--- a/src/OpenFOAM/primitives/VectorSpace/products.H
+++ b/src/OpenFOAM/primitives/VectorSpace/products.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -44,13 +44,13 @@ namespace Foam
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 //- Abstract template class to provide the form resulting from
-//  the inner-product of two forms
+//- the inner-product of two forms
 template<class Cmpt, class Form1, class Form2>
 class typeOfInnerProduct
 {};
 
 //- Abstract template class to provide the form resulting from
-//  the outer-product of two forms
+//- the outer-product of two forms
 template<class Cmpt, class Form1, class Form2>
 class typeOfOuterProduct
 {};
@@ -71,6 +71,16 @@ class symmTypeOfRank
 {};
 
 
+//- The magnitude type for given argument.
+template<class arg1>
+class typeOfMag
+{
+public:
+
+    typedef typename pTraits<typename pTraits<arg1>::cmptType>::magType type;
+};
+
+
 template<class arg1, class arg2>
 class typeOfSum
 {
@@ -93,6 +103,16 @@ public:
 };
 
 
+//- Outer-product of identical types
+template<class arg1>
+class outerProduct1
+:
+    public outerProduct<arg1, arg1>
+{
+public:
+};
+
+
 template<class arg1, class arg2>
 class crossProduct
 {
diff --git a/src/OpenFOAM/primitives/bools/bool/bool.H b/src/OpenFOAM/primitives/bools/bool/bool.H
index 6874ca3be5cac705011618c42a1064f6a530ad08..c8cae6dc31da232ac6409891976a2db75a967886 100644
--- a/src/OpenFOAM/primitives/bools/bool/bool.H
+++ b/src/OpenFOAM/primitives/bools/bool/bool.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -74,6 +74,10 @@ public:
     //- Component type
     typedef bool cmptType;
 
+    //- Magnitude type
+    typedef bool magType;
+
+
     // Member constants
 
         //- Dimensionality of space
diff --git a/src/OpenFOAM/primitives/complex/complex.H b/src/OpenFOAM/primitives/complex/complex.H
index ab1231745677b112a633edc9e03c58d59bce0e9e..4702d9f7dab3fda1265afa3b5722d08ddc23f492 100644
--- a/src/OpenFOAM/primitives/complex/complex.H
+++ b/src/OpenFOAM/primitives/complex/complex.H
@@ -252,6 +252,9 @@ public:
     //- Component type
     typedef complex cmptType;
 
+    //- Magnitude type
+    typedef scalar magType;
+
     //- Equivalent type of labels used for valid component indexing
     typedef label labelType;
 
diff --git a/src/OpenFOAM/primitives/ints/int32/int32.H b/src/OpenFOAM/primitives/ints/int32/int32.H
index 5c4c22f020d97000eafa2a45571b3b5042d83fd3..a681ded96d7bac18e16c90bcf8a480d1c8711b42 100644
--- a/src/OpenFOAM/primitives/ints/int32/int32.H
+++ b/src/OpenFOAM/primitives/ints/int32/int32.H
@@ -138,6 +138,9 @@ public:
     //- Component type
     typedef int32_t cmptType;
 
+    //- Magnitude type
+    typedef int32_t magType;
+
 
     // Member constants
 
diff --git a/src/OpenFOAM/primitives/ints/int64/int64.H b/src/OpenFOAM/primitives/ints/int64/int64.H
index b0e075b6346658ce7f4c0c5ad851172e883b3018..095aa0aa213e346f57f953d744897794fddbb83a 100644
--- a/src/OpenFOAM/primitives/ints/int64/int64.H
+++ b/src/OpenFOAM/primitives/ints/int64/int64.H
@@ -139,6 +139,9 @@ public:
     //- Component type
     typedef int64_t cmptType;
 
+    //- Magnitude type
+    typedef int64_t magType;
+
 
     // Member constants
 
diff --git a/src/OpenFOAM/primitives/quaternion/quaternion.H b/src/OpenFOAM/primitives/quaternion/quaternion.H
index 42040e0c252729774181b7ab52517ee1398351b0..4e3ecc5fcc3a0731d382aa4ff8815bcdb6a8d049 100644
--- a/src/OpenFOAM/primitives/quaternion/quaternion.H
+++ b/src/OpenFOAM/primitives/quaternion/quaternion.H
@@ -96,6 +96,9 @@ public:
         //- Component type
         typedef scalar cmptType;
 
+        //- Magnitude type
+        typedef scalar magType;
+
         //- Euler-angle rotation order
         enum eulerOrder : unsigned char
         {
diff --git a/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H b/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H
index 6c78dfccc9d3a58434e40222bbf936b8654b895c..8dfff8927ef4656932e6f8522f02759435f4636d 100644
--- a/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H
+++ b/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H
@@ -132,6 +132,7 @@ public:
         //- The value type the MinMax represents
         typedef T value_type;
 
+        //- Component type
         typedef typename pTraits<T>::cmptType cmptType;
 
 
diff --git a/src/finiteArea/faMatrices/faMatrix/faMatrixSolve.C b/src/finiteArea/faMatrices/faMatrix/faMatrixSolve.C
index 574227b89e0e774a950ecc69400299c526861cfc..82703d19edad356ecedaffd07640ca04ebb11b03 100644
--- a/src/finiteArea/faMatrices/faMatrix/faMatrixSolve.C
+++ b/src/finiteArea/faMatrices/faMatrix/faMatrixSolve.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 Wikki Ltd
@@ -28,6 +28,10 @@ Description
 
 \*---------------------------------------------------------------------------*/
 
+#include "PrecisionAdaptor.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
 template<class Type>
 void Foam::faMatrix<Type>::setComponentReference
 (
@@ -96,25 +100,30 @@ Foam::SolverPerformance<Type> Foam::faMatrix<Type>::solve
         // Use the initMatrixInterfaces and updateMatrixInterfaces to correct
         // bouCoeffsCmpt for the explicit part of the coupled boundary
         // conditions
-        initMatrixInterfaces
-        (
-            true,
-            bouCoeffsCmpt,
-            interfaces,
-            psiCmpt,
-            sourceCmpt,
-            cmpt
-        );
+        {
+            PrecisionAdaptor<solveScalar, scalar> sourceCmpt_ss(sourceCmpt);
+            ConstPrecisionAdaptor<solveScalar, scalar> psiCmpt_ss(psiCmpt);
 
-        updateMatrixInterfaces
-        (
-            true,
-            bouCoeffsCmpt,
-            interfaces,
-            psiCmpt,
-            sourceCmpt,
-            cmpt
-        );
+            initMatrixInterfaces
+            (
+                true,
+                bouCoeffsCmpt,
+                interfaces,
+                psiCmpt_ss(),
+                sourceCmpt_ss.ref(),
+                cmpt
+            );
+
+            updateMatrixInterfaces
+            (
+                true,
+                bouCoeffsCmpt,
+                interfaces,
+                psiCmpt_ss(),
+                sourceCmpt_ss.ref(),
+                cmpt
+            );
+        }
 
         solverPerformance solverPerf;
 
diff --git a/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C b/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C
index df469cc1e12ad81d598ed7a8d6167d48d11181b2..b7eefba11724b9f669430b6ba6c668d12bd533a1 100644
--- a/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C
+++ b/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 Wikki Ltd
@@ -30,6 +30,7 @@ Description
 
 #include "faScalarMatrix.H"
 #include "zeroGradientFaPatchFields.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -101,21 +102,27 @@ Foam::tmp<Foam::scalarField> Foam::faMatrix<Foam::scalar>::residual() const
     scalarField boundaryDiag(psi_.size(), Zero);
     addBoundaryDiag(boundaryDiag, 0);
 
-    tmp<scalarField> tres
+    const scalarField& psif = psi_.internalField();
+    ConstPrecisionAdaptor<solveScalar, scalar> tpsi(psif);
+    const solveScalarField& psi = tpsi();
+
+    tmp<solveScalarField> tres
     (
         lduMatrix::residual
         (
-            psi_.internalField(),
-            source_ - boundaryDiag*psi_.internalField(),
+            psi,
+            source_ - boundaryDiag*psif,
             boundaryCoeffs_,
             psi_.boundaryField().scalarInterfaces(),
             0
         )
     );
 
-    addBoundarySource(tres.ref());
+    ConstPrecisionAdaptor<scalar, solveScalar> tres_s(tres);
+
+    addBoundarySource(tres_s.ref());
 
-    return tres;
+    return tres_s;
 }
 
 
diff --git a/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.H b/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.H
index 511e98e7364693f0b29facc2549c8d52ee286347..8fd6cbfe97804dfacc1975ef44f109d7c63fc769 100644
--- a/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.H
+++ b/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 Wikki Ltd
@@ -183,16 +183,16 @@ public:
             //- Transform given patch component field
             virtual void transformCoupleField
             (
-                scalarField& f,
+                solveScalarField& f,
                 const direction cmpt
             ) const = 0;
 
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction,
                 const Pstream::commsTypes commsType
diff --git a/src/finiteArea/fields/faPatchFields/constraint/cyclic/cyclicFaPatchField.C b/src/finiteArea/fields/faPatchFields/constraint/cyclic/cyclicFaPatchField.C
index 14fa7dcd3c34bbe53b74a363fcfa27186f371b03..13d685a1e6624ce60cf49321f998bac87a26208f 100644
--- a/src/finiteArea/fields/faPatchFields/constraint/cyclic/cyclicFaPatchField.C
+++ b/src/finiteArea/fields/faPatchFields/constraint/cyclic/cyclicFaPatchField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 Wikki Ltd
@@ -161,15 +161,15 @@ Foam::cyclicFaPatchField<Type>::patchNeighbourField() const
 template<class Type>
 void Foam::cyclicFaPatchField<Type>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
 ) const
 {
-    scalarField pnf(this->size());
+    solveScalarField pnf(this->size());
 
     label sizeby2 = this->size()/2;
     const labelUList& faceCells = cyclicPatch_.faceCells();
diff --git a/src/finiteArea/fields/faPatchFields/constraint/cyclic/cyclicFaPatchField.H b/src/finiteArea/fields/faPatchFields/constraint/cyclic/cyclicFaPatchField.H
index b8185a5c0f3b9641de1a6a42226a372b2692d9fe..3b265bcdd3221d380c2b110a3934e7b65095dc92 100644
--- a/src/finiteArea/fields/faPatchFields/constraint/cyclic/cyclicFaPatchField.H
+++ b/src/finiteArea/fields/faPatchFields/constraint/cyclic/cyclicFaPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 Wikki Ltd
@@ -166,7 +166,7 @@ public:
             //- Transform neighbour field
             virtual void transformCoupleField
             (
-                scalarField& f,
+                solveScalarField& f,
                 const direction cmpt
             ) const
             {
@@ -176,9 +176,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.C b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.C
index 9db7f49ac5df61d2b2a28e0c7943794a948ff436..4d5e13ec1b974fc4365d90a16fab745c7db528b4 100644
--- a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.C
+++ b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 Wikki Ltd
@@ -189,9 +189,9 @@ Foam::tmp<Foam::Field<Type>> Foam::processorFaPatchField<Type>::snGrad() const
 template<class Type>
 void Foam::processorFaPatchField<Type>::initInterfaceMatrixUpdate
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction,
     const Pstream::commsTypes commsType
@@ -208,17 +208,17 @@ void Foam::processorFaPatchField<Type>::initInterfaceMatrixUpdate
 template<class Type>
 void Foam::processorFaPatchField<Type>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField&,
+    const solveScalarField&,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
 ) const
 {
-    scalarField pnf
+    solveScalarField pnf
     (
-        procPatch_.receive<scalar>(commsType, this->size())()
+        procPatch_.receive<solveScalar>(commsType, this->size())()
     );
 
     // Transform according to the transformation tensor
diff --git a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H
index b516620e60b32c458f2fc9afa35ccb6c512b5b2c..4df002aa1035b33e55712898aeaa52a3b5c0f778 100644
--- a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H
+++ b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 Wikki Ltd
@@ -180,7 +180,7 @@ public:
             //- Transform neighbour field
             virtual void transformCoupleField
             (
-                scalarField& f,
+                solveScalarField& f,
                 const direction cmpt
             ) const
             {
@@ -190,9 +190,9 @@ public:
             //- Initialise neighbour matrix update
             virtual void initInterfaceMatrixUpdate
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
@@ -201,9 +201,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchScalarField.C b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchScalarField.C
index 6f52b046a0b3c20f5452535887160677535bb1e1..d26df7ce02623950aaca12e1813a39a72c414db1 100644
--- a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchScalarField.C
+++ b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchScalarField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 Wikki Ltd
@@ -32,7 +32,7 @@ License
 template<>
 void Foam::processorFaPatchField<Foam::scalar>::transformCoupleField
 (
-    scalarField& f,
+    solveScalarField& f,
     const direction cmpt
 ) const
 {}
@@ -41,9 +41,9 @@ void Foam::processorFaPatchField<Foam::scalar>::transformCoupleField
 template<>
 void Foam::processorFaPatchField<Foam::scalar>::initInterfaceMatrixUpdate
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction,
     const Pstream::commsTypes commsType
@@ -60,17 +60,17 @@ void Foam::processorFaPatchField<Foam::scalar>::initInterfaceMatrixUpdate
 template<>
 void Foam::processorFaPatchField<Foam::scalar>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField&,
+    const solveScalarField&,
     const scalarField& coeffs,
     const direction,
     const Pstream::commsTypes commsType
 ) const
 {
-    scalarField pnf
+    solveScalarField pnf
     (
-        procPatch_.receive<scalar>(commsType, this->size())()
+        procPatch_.receive<solveScalar>(commsType, this->size())()
     );
 
     const labelUList& edgeFaces = patch().edgeFaces();
diff --git a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchScalarField.H b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchScalarField.H
index 4db957540c5a81d0b969bd1a8e7ef9a47610e227..e737506c83311422c40eb3a36ca477eb1e1a8b46 100644
--- a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchScalarField.H
+++ b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchScalarField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016-2017 Wikki Ltd
@@ -40,7 +40,7 @@ namespace Foam
 template<>
 void processorFaPatchField<scalar>::transformCoupleField
 (
-    scalarField& f,
+    solveScalarField& f,
     const direction cmpt
 ) const;
 
@@ -48,9 +48,9 @@ void processorFaPatchField<scalar>::transformCoupleField
 template<>
 void processorFaPatchField<scalar>::initInterfaceMatrixUpdate
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField&,
+    const solveScalarField&,
     const scalarField& coeffs,
     const direction,
     const Pstream::commsTypes commsType
@@ -60,9 +60,9 @@ void processorFaPatchField<scalar>::initInterfaceMatrixUpdate
 template<>
 void processorFaPatchField<scalar>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField&,
+    const solveScalarField&,
     const scalarField& coeffs,
     const direction,
     const Pstream::commsTypes commsType
diff --git a/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.H
index 7433719f940ce90609a85ccac4eba8192a2a2219..d8a0db2290ea21efcf7f1a6bc5297a38ec897a73 100644
--- a/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -208,9 +208,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction,
                 const Pstream::commsTypes commsType
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.C
index d64cd279979ebe4581f4e1d30c01d892fcd796ee..a0b15e4b2488a7a82fb5ba6984fc4cbf3b562702 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -172,9 +172,9 @@ Foam::cyclicFvPatchField<Type>::neighbourPatchField() const
 template<class Type>
 void Foam::cyclicFvPatchField<Type>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
@@ -183,7 +183,7 @@ void Foam::cyclicFvPatchField<Type>::updateInterfaceMatrix
     const labelUList& nbrFaceCells =
         cyclicPatch().cyclicPatch().neighbPatch().faceCells();
 
-    scalarField pnf(psiInternal, nbrFaceCells);
+    solveScalarField pnf(psiInternal, nbrFaceCells);
 
     // Transform according to the transformation tensors
     transformCoupleField(pnf, cmpt);
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.H
index 98dd908a914b9544d90826392de449633fafb18c..ff89da85b9762fa79b0dc5d75a73cd63c5c43878 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -179,9 +179,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C
index 5df465010991e96034c3f90b0f97c1e90c69ca6f..b1cbe8409d3ae012afb81c59eb8774c7d8760fac 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2013-2017 OpenFOAM Foundation
@@ -215,9 +215,9 @@ Foam::cyclicACMIFvPatchField<Type>::nonOverlapPatchField() const
 template<class Type>
 void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
@@ -230,7 +230,7 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
     const labelUList& nbrFaceCellsCoupled =
         cpp.neighbPatch().faceCells();
 
-    scalarField pnf(psiInternal, nbrFaceCellsCoupled);
+    solveScalarField pnf(psiInternal, nbrFaceCellsCoupled);
 
     // Transform according to the transformation tensors
     transformCoupleField(pnf, cmpt);
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H
index 97fbc8621e6ef6358cc83c4fa66c1f30141bfffd..f81705f91753ed676b9fe793668f79c99207b175 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2013-2016 OpenFOAM Foundation
@@ -203,9 +203,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C
index cb61899215209ace345f3a895ecf8b05e21b3b40..06755dd19a6c31562d81dfd16f0a424552ebd427 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -178,9 +178,9 @@ Foam::cyclicAMIFvPatchField<Type>::neighbourPatchField() const
 template<class Type>
 void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
@@ -189,14 +189,14 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
     const labelUList& nbrFaceCells =
         cyclicAMIPatch_.cyclicAMIPatch().neighbPatch().faceCells();
 
-    scalarField pnf(psiInternal, nbrFaceCells);
+    solveScalarField pnf(psiInternal, nbrFaceCells);
 
     // Transform according to the transformation tensors
     transformCoupleField(pnf, cmpt);
 
     if (cyclicAMIPatch_.applyLowWeightCorrection())
     {
-        scalarField pif(psiInternal, cyclicAMIPatch_.faceCells());
+        solveScalarField pif(psiInternal, cyclicAMIPatch_.faceCells());
         pnf = cyclicAMIPatch_.interpolate(pnf, pif);
     }
     else
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H
index 50f7c4f4ce7ebe28a39e35925260af648fadcbeb..c584ad99d18d081b215ec7b353b78d09ba17436d 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -184,9 +184,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.C
index 45b2dc2fd38d2f1378e919e7a48adf928127ff21..3fdb0cc95b4dad69e604e62fd84124688b51fa0c 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -133,9 +133,9 @@ Foam::jumpCyclicFvPatchField<Type>::patchNeighbourField() const
 template<class Type>
 void Foam::jumpCyclicFvPatchField<Type>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.H
index 0f197da28887dec8be0b54da1a9fc3ffa2134bc9..0be0b84a507311a3c9f3c2b03d47ab3973bb77c6 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2018-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -129,9 +129,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
@@ -152,9 +152,9 @@ public:
 template<>
 void jumpCyclicFvPatchField<scalar>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
@@ -164,9 +164,9 @@ void jumpCyclicFvPatchField<scalar>::updateInterfaceMatrix
 template<>
 void jumpCyclicFvPatchField<vector>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchFields.C b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchFields.C
index e1ba118ba9de0bcd25fd1e962de7502afca26652..8c7474850c9697f418cd4932dc931c5c98a18ccf 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchFields.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchFields.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2018-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -41,21 +41,25 @@ namespace Foam
 template<>
 void Foam::jumpCyclicFvPatchField<Foam::scalar>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
 ) const
 {
-    scalarField pnf(this->size());
+    solveScalarField pnf(this->size());
 
     const labelUList& nbrFaceCells =
         this->cyclicPatch().neighbFvPatch().faceCells();
 
     // only apply jump to original field
-    if (&psiInternal == &this->primitiveField())
+    if
+    (
+        reinterpret_cast<const void*>(&psiInternal)
+     == reinterpret_cast<const void*>(&this->primitiveField())
+    )
     {
         Field<scalar> jf(this->jump());
 
@@ -88,15 +92,15 @@ void Foam::jumpCyclicFvPatchField<Foam::scalar>::updateInterfaceMatrix
 template<>
 void Foam::jumpCyclicFvPatchField<Foam::vector>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
 ) const
 {
-    scalarField pnf(this->size());
+    solveScalarField pnf(this->size());
 
     const labelUList& nbrFaceCells =
         this->cyclicPatch().neighbFvPatch().faceCells();
@@ -104,7 +108,11 @@ void Foam::jumpCyclicFvPatchField<Foam::vector>::updateInterfaceMatrix
     const Field<vector>& iField = this->primitiveField();
 
     // only apply jump to original field
-    if (&psiInternal == &(iField.component(cmpt).ref()))
+    if
+    (
+        reinterpret_cast<const void*>(&psiInternal)
+     == reinterpret_cast<const void*>(&(iField.component(cmpt).ref()))
+    )
     {
         Field<vector> jf(this->jump());
 
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchField.C
index 182db1b9d25a34c47371a345bb0624756d19e924..15063306399a58a499aad921b6e87a79ebf6164b 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2012-2017 OpenFOAM Foundation
@@ -135,9 +135,9 @@ Foam::jumpCyclicAMIFvPatchField<Type>::patchNeighbourField() const
 template<class Type>
 void Foam::jumpCyclicAMIFvPatchField<Type>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchField.H
index 440b9978bee61b11c9c14d328f1bf97eb6d9ec33..8249c7744ed2644f61ddb4cb38b4c4d694425204 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2012-2016 OpenFOAM Foundation
@@ -132,9 +132,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
@@ -156,9 +156,9 @@ public:
 template<>
 void jumpCyclicAMIFvPatchField<scalar>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchFields.C b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchFields.C
index 018342789e2e426ea0ca82e9a5f77f60a225e033..8284ca4f332ddf3e93d24c5421a361a8216fa366 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchFields.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclicAMI/jumpCyclicAMIFvPatchFields.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2012-2016 OpenFOAM Foundation
@@ -43,9 +43,9 @@ makePatchFieldTypeNames(jumpCyclicAMI);
 template<>
 void Foam::jumpCyclicAMIFvPatchField<scalar>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
@@ -54,12 +54,16 @@ void Foam::jumpCyclicAMIFvPatchField<scalar>::updateInterfaceMatrix
     const labelUList& nbrFaceCells =
         this->cyclicAMIPatch().cyclicAMIPatch().neighbPatch().faceCells();
 
-    scalarField pnf(psiInternal, nbrFaceCells);
+    solveScalarField pnf(psiInternal, nbrFaceCells);
 
     pnf = this->cyclicAMIPatch().interpolate(pnf);
 
     // only apply jump to original field
-    if (&psiInternal == &this->primitiveField())
+    if
+    (
+        reinterpret_cast<const void*>(&psiInternal)
+     == reinterpret_cast<const void*>(&this->primitiveField())
+    )
     {
         Field<scalar> jf(this->jump());
 
@@ -68,7 +72,11 @@ void Foam::jumpCyclicAMIFvPatchField<scalar>::updateInterfaceMatrix
             jf *= -1.0;
         }
 
-        pnf -= jf;
+        //pnf -= jf;
+        forAll(pnf, i)
+        {
+            pnf[i] -= jf[i];
+        }
     }
 
     // Transform according to the transformation tensors
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C
index e27ca978f4cc63c2079488b935e00dd9eed67c6c..e95e54ee7ad26effba116e7b5e4b51c16e29b4f0 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C
@@ -310,9 +310,9 @@ Foam::processorFvPatchField<Type>::snGrad
 template<class Type>
 void Foam::processorFvPatchField<Type>::initInterfaceMatrixUpdate
 (
-    scalarField&,
+    solveScalarField&,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField&,
     const direction,
     const Pstream::commsTypes commsType
@@ -371,9 +371,9 @@ void Foam::processorFvPatchField<Type>::initInterfaceMatrixUpdate
 template<class Type>
 void Foam::processorFvPatchField<Type>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField&,
+    const solveScalarField&,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
@@ -415,9 +415,13 @@ void Foam::processorFvPatchField<Type>::updateInterfaceMatrix
     }
     else
     {
-        scalarField pnf
+        solveScalarField pnf
         (
-            procPatch_.compressedReceive<scalar>(commsType, this->size())()
+            procPatch_.compressedReceive<solveScalar>
+            (
+                commsType,
+                this->size()
+            )()
         );
 
         if (!std::is_arithmetic<Type>::value)
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H
index 178b70307213b8405c3fc2c1d14ea5dce7621f93..23a8948c0bfbf84432cebef103b082c68412e3cf 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -88,10 +88,11 @@ class processorFvPatchField
             mutable label outstandingRecvRequest_;
 
             //- Scalar send buffer
-            mutable Field<scalar> scalarSendBuf_;
+            mutable solveScalarField scalarSendBuf_;
 
             //- Scalar receive buffer
-            mutable Field<scalar> scalarReceiveBuf_;
+            mutable solveScalarField scalarReceiveBuf_;
+
 
 public:
 
@@ -210,9 +211,9 @@ public:
             //- Initialise neighbour matrix update
             virtual void initInterfaceMatrixUpdate
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
@@ -221,9 +222,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H
index 23110fb7323a7f38e03f23682ccadb89de531fd8..5d8124bba9e017011b601845bb266b38caede630 100644
--- a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -49,6 +49,7 @@ SourceFiles
 #include "fvPatch.H"
 #include "DimensionedField.H"
 #include "fieldTypes.H"
+#include "scalarField.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
index 28489daee3f5376b824ea4ba1f2eeda17ead667d..dec7e4b1f32b27a33b55ad008b7728a5974d86a8 100644
--- a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
+++ b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -28,6 +28,7 @@ License
 #include "LduMatrix.H"
 #include "diagTensorField.H"
 #include "profiling.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -173,25 +174,30 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated
         // Use the initMatrixInterfaces and updateMatrixInterfaces to correct
         // bouCoeffsCmpt for the explicit part of the coupled boundary
         // conditions
-        initMatrixInterfaces
-        (
-            true,
-            bouCoeffsCmpt,
-            interfaces,
-            psiCmpt,
-            sourceCmpt,
-            cmpt
-        );
+        {
+            PrecisionAdaptor<solveScalar, scalar> sourceCmpt_ss(sourceCmpt);
+            ConstPrecisionAdaptor<solveScalar, scalar> psiCmpt_ss(psiCmpt);
 
-        updateMatrixInterfaces
-        (
-            true,
-            bouCoeffsCmpt,
-            interfaces,
-            psiCmpt,
-            sourceCmpt,
-            cmpt
-        );
+            initMatrixInterfaces
+            (
+                true,
+                bouCoeffsCmpt,
+                interfaces,
+                psiCmpt_ss(),
+                sourceCmpt_ss.constCast(),
+                cmpt
+            );
+
+            updateMatrixInterfaces
+            (
+                true,
+                bouCoeffsCmpt,
+                interfaces,
+                psiCmpt_ss(),
+                sourceCmpt_ss.constCast(),
+                cmpt
+            );
+        }
 
         solverPerformance solverPerf;
 
diff --git a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
index 8df051b3fcf00d8135765d9422a12f8e25d17446..1d15cbb78718ec495c8fe892292856ed6b5f98df 100644
--- a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
+++ b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -28,6 +28,7 @@ License
 #include "fvScalarMatrix.H"
 #include "extrapolatedCalculatedFvPatchFields.H"
 #include "profiling.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -199,21 +200,24 @@ Foam::tmp<Foam::scalarField> Foam::fvMatrix<Foam::scalar>::residual() const
     scalarField boundaryDiag(psi_.size(), Zero);
     addBoundaryDiag(boundaryDiag, 0);
 
-    tmp<scalarField> tres
+    const scalarField& psif = psi_.primitiveField();
+    ConstPrecisionAdaptor<solveScalar, scalar> tpsi(psif);
+    const solveScalarField& psi = tpsi();
+
+    tmp<solveScalarField> tres
     (
         lduMatrix::residual
         (
-            psi_.primitiveField(),
-            source_ - boundaryDiag*psi_.primitiveField(),
+            psi,
+            source_ - boundaryDiag*psif,
             boundaryCoeffs_,
             psi_.boundaryField().scalarInterfaces(),
             0
         )
     );
-
-    addBoundarySource(tres.ref());
-
-    return tres;
+    ConstPrecisionAdaptor<scalar, solveScalar> tres_s(tres);
+    addBoundarySource(tres_s.constCast());
+    return tres_s;
 }
 
 
diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C
index d85391f85d87bfa47189a38e694cae34d58a3f62..42bd8162db585bd8dd07be027108f3ea0a621bf9 100644
--- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C
+++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2013 OpenFOAM Foundation
@@ -94,16 +94,16 @@ Foam::cyclicACMIGAMGInterfaceField::~cyclicACMIGAMGInterfaceField()
 
 void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
 ) const
 {
     // Get neighbouring field
-    scalarField pnf
+    solveScalarField pnf
     (
         cyclicACMIInterface_.neighbPatch().interfaceInternalField(psiInternal)
     );
diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H
index 54619b13cbd89eb0fb62cf5edb63afd29145685b..c4c5b764ce36a9f8dd177b55a2876cd1d807f028 100644
--- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H
+++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2013 OpenFOAM Foundation
@@ -124,9 +124,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C
index 4846c224849229b6a91c0c85b23d884eac2358e3..a7216ade3545407cfa8a3873597e91b8fd790b2a 100644
--- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C
+++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -94,16 +94,16 @@ Foam::cyclicAMIGAMGInterfaceField::~cyclicAMIGAMGInterfaceField()
 
 void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
 ) const
 {
     // Get neighbouring field
-    scalarField pnf
+    solveScalarField pnf
     (
         cyclicAMIInterface_.neighbPatch().interfaceInternalField(psiInternal)
     );
diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H
index 87eef60af7bdce02626c6b5a1d73c4cf0e970f98..2bd73e53b025adfc6b9eb859a3781badc84c46e2 100644
--- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H
+++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -123,9 +123,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.C
index 414cd4653956e9cbbf0aa9b305af7008cbdfe055..5333f7ded60de99895f0317bc5bc004ffd47370b 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.C
+++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2013 OpenFOAM Foundation
@@ -46,7 +46,7 @@ Foam::cyclicACMILduInterfaceField::~cyclicACMILduInterfaceField()
 
 void Foam::cyclicACMILduInterfaceField::transformCoupleField
 (
-    scalarField& f,
+    solveScalarField& f,
     const direction cmpt
 ) const
 {
diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.H
index 1b3b8f200e9e829f4e173bdd427ecb43974f6fa4..006329f078062fcb3642bcd8ea0c56c1103342b7 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.H
+++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2013 OpenFOAM Foundation
@@ -79,7 +79,7 @@ public:
         //- Transform given patch internal field
         void transformCoupleField
         (
-            scalarField& psiInternal,
+            solveScalarField& psiInternal,
             const direction cmpt
         ) const;
 };
diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C
index f414d508ff6d1c8bb85028f7a0a8feff80149ec2..7acdea3dc68d0a231f06494265cf99a6df53c2f6 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C
+++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -46,7 +46,7 @@ Foam::cyclicAMILduInterfaceField::~cyclicAMILduInterfaceField()
 
 void Foam::cyclicAMILduInterfaceField::transformCoupleField
 (
-    scalarField& f,
+    solveScalarField& f,
     const direction cmpt
 ) const
 {
diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H
index c8aefbb03013ff95727b37c3f3b3600dc07805cb..8f40541b9bbca446b10f14f03211a6d09cb55ef4 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H
+++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -92,7 +92,7 @@ public:
         //- Transform given patch internal field
         void transformCoupleField
         (
-            scalarField& psiInternal,
+            solveScalarField& psiInternal,
             const direction cmpt
         ) const;
 };
diff --git a/src/meshTools/regionCoupled/GAMG/interfaceFields/regionCoupledGAMGInterfaceField/regionCoupledGAMGInterfaceField.H b/src/meshTools/regionCoupled/GAMG/interfaceFields/regionCoupledGAMGInterfaceField/regionCoupledGAMGInterfaceField.H
index e27633cc0761d59b785513c4ecd0b9ddf8e52311..13031281d8b650d5d06fcf6924e5b51dbe1c9510 100644
--- a/src/meshTools/regionCoupled/GAMG/interfaceFields/regionCoupledGAMGInterfaceField/regionCoupledGAMGInterfaceField.H
+++ b/src/meshTools/regionCoupled/GAMG/interfaceFields/regionCoupledGAMGInterfaceField/regionCoupledGAMGInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -113,9 +113,9 @@ public:
             //- Interface matrix update
             virtual void updateInterfaceMatrix
             (
-                scalarField&,
+                solveScalarField&,
                 const bool add,
-                const scalarField&,
+                const solveScalarField&,
                 const scalarField&,
                 const direction,
                 const Pstream::commsTypes commsType
diff --git a/src/meshTools/regionCoupled/GAMG/interfaceFields/regionCoupledGAMGInterfaceField/regionCoupledWallGAMGInterfaceField.H b/src/meshTools/regionCoupled/GAMG/interfaceFields/regionCoupledGAMGInterfaceField/regionCoupledWallGAMGInterfaceField.H
index a137af8ffab435be38aa30359b41cf3c0647e50c..310bd53ea56aa4023dd6b9763334f17a6afbb642 100644
--- a/src/meshTools/regionCoupled/GAMG/interfaceFields/regionCoupledGAMGInterfaceField/regionCoupledWallGAMGInterfaceField.H
+++ b/src/meshTools/regionCoupled/GAMG/interfaceFields/regionCoupledGAMGInterfaceField/regionCoupledWallGAMGInterfaceField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -114,9 +114,9 @@ public:
             //- Interface matrix update
             virtual void updateInterfaceMatrix
             (
-                scalarField&,
+                solveScalarField&,
                 const bool add,
-                const scalarField&,
+                const solveScalarField&,
                 const scalarField&,
                 const direction,
                 const Pstream::commsTypes commsType
diff --git a/src/overset/Make/files b/src/overset/Make/files
index e3ba8d7f42fcd66f24df8c2586629f95ee2b8049..70acd1f108dd0965fdeadec3bfe439f16bc770c2 100644
--- a/src/overset/Make/files
+++ b/src/overset/Make/files
@@ -19,14 +19,6 @@ oversetPolyPatch/oversetFvsPatchFields.C
 oversetPolyPatch/oversetPointPatch.C
 oversetPolyPatch/oversetPointPatchFields.C
 
-/*
-oversetPolyPatch/semiImplicitOversetFvPatchFields.C
-oversetPolyPatch/oversetLduInterface.C
-oversetPolyPatch/oversetGAMGInterface.C
-oversetPolyPatch/oversetGAMGInterfaceField.C
-oversetPolyPatch/semiImplicitOversetGAMGInterfaceField.C
-*/
-
 oversetAdjustPhi/oversetAdjustPhi.C
 
 regionsToCell/regionsToCell.C
diff --git a/src/overset/lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterfaceField.C b/src/overset/lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterfaceField.C
index e24cd5c43bac940c1a90a9a9d134f74967fcc895..43545c4248f40d5425bb8f0ae1069bbea23db476 100644
--- a/src/overset/lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterfaceField.C
+++ b/src/overset/lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterfaceField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2004-2010, 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -84,20 +84,13 @@ calculatedProcessorGAMGInterfaceField
 {}
 
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::calculatedProcessorGAMGInterfaceField::
-~calculatedProcessorGAMGInterfaceField()
-{}
-
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 void Foam::calculatedProcessorGAMGInterfaceField::initInterfaceMatrixUpdate
 (
-    scalarField&,
-    const bool,
-    const scalarField& psiInternal,
+    solveScalarField&,
+    const bool add,
+    const solveScalarField& psiInternal,
     const scalarField&,
     const direction,
     const Pstream::commsTypes commsType
@@ -147,9 +140,9 @@ void Foam::calculatedProcessorGAMGInterfaceField::initInterfaceMatrixUpdate
 
 void Foam::calculatedProcessorGAMGInterfaceField::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField&,
+    const solveScalarField&,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
@@ -189,9 +182,13 @@ void Foam::calculatedProcessorGAMGInterfaceField::updateInterfaceMatrix
     }
     else
     {
-        scalarField pnf
+        solveScalarField pnf
         (
-            procInterface_.compressedReceive<scalar>(commsType, coeffs.size())
+            procInterface_.compressedReceive<solveScalar>
+            (
+                commsType,
+                this->size()
+            )()
         );
         transformCoupleField(pnf, cmpt);
 
diff --git a/src/overset/lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterfaceField.H b/src/overset/lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterfaceField.H
index b93f91edfdec6d478f794c71f66f274484a8a67f..d759fc301b97aa078c2af2941a36495a62f722d0 100644
--- a/src/overset/lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterfaceField.H
+++ b/src/overset/lduPrimitiveProcessorInterface/GAMG/calculatedProcessorGAMGInterfaceField.H
@@ -74,10 +74,10 @@ class calculatedProcessorGAMGInterfaceField
             mutable label outstandingRecvRequest_;
 
             //- Scalar send buffer
-            mutable Field<scalar> scalarSendBuf_;
+            mutable solveScalarField scalarSendBuf_;
 
             //- Scalar receive buffer
-            mutable Field<scalar> scalarReceiveBuf_;
+            mutable solveScalarField scalarReceiveBuf_;
 
 
 
@@ -118,7 +118,7 @@ public:
 
 
     //- Destructor
-    virtual ~calculatedProcessorGAMGInterfaceField();
+    virtual ~calculatedProcessorGAMGInterfaceField() = default;
 
 
     // Member Functions
@@ -137,9 +137,9 @@ public:
             //- Initialise neighbour matrix update
             virtual void initInterfaceMatrixUpdate
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
@@ -148,9 +148,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/overset/lduPrimitiveProcessorInterface/calculatedProcessorFvPatchField.C b/src/overset/lduPrimitiveProcessorInterface/calculatedProcessorFvPatchField.C
index 413f4ee0d90ea811febeb3d4ed163e8ca7bb5cea..efcb764a7133cbe48e19b741ef64526eaefca5d6 100644
--- a/src/overset/lduPrimitiveProcessorInterface/calculatedProcessorFvPatchField.C
+++ b/src/overset/lduPrimitiveProcessorInterface/calculatedProcessorFvPatchField.C
@@ -213,9 +213,9 @@ void Foam::calculatedProcessorFvPatchField<Type>::evaluate
 template<class Type>
 void Foam::calculatedProcessorFvPatchField<Type>::initInterfaceMatrixUpdate
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
@@ -268,14 +268,13 @@ void Foam::calculatedProcessorFvPatchField<Type>::initInterfaceMatrixUpdate
 }
 
 
-
 template<class Type>
 void Foam::calculatedProcessorFvPatchField<Type>::addToInternalField
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
     const scalarField& coeffs,
-    const scalarField& vals
+    const solveScalarField& vals
 ) const
 {
     const labelUList& faceCells = this->procInterface_.faceCells();
@@ -300,9 +299,9 @@ void Foam::calculatedProcessorFvPatchField<Type>::addToInternalField
 template<class Type>
 void Foam::calculatedProcessorFvPatchField<Type>::updateInterfaceMatrix
 (
-    scalarField& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes commsType
diff --git a/src/overset/lduPrimitiveProcessorInterface/calculatedProcessorFvPatchField.H b/src/overset/lduPrimitiveProcessorInterface/calculatedProcessorFvPatchField.H
index 96d23137979cc8c8e56476eb62a9e5997e339f12..a45928603346166e551d2accb0834cca372d315e 100644
--- a/src/overset/lduPrimitiveProcessorInterface/calculatedProcessorFvPatchField.H
+++ b/src/overset/lduPrimitiveProcessorInterface/calculatedProcessorFvPatchField.H
@@ -46,8 +46,6 @@ SourceFiles
 #define calculatedProcessorFvPatchField_H
 
 #include "lduPrimitiveProcessorInterface.H"
-//#include "lduInterfaceField.H"
-//#include "fvPatchField.H"
 #include "coupledFvPatchField.H"
 #include "processorLduInterfaceField.H"
 
@@ -82,10 +80,10 @@ protected:
             mutable Field<Type> receiveBuf_;
 
             //- Scalar send buffer
-            mutable Field<scalar> scalarSendBuf_;
+            mutable solveScalarField scalarSendBuf_;
 
             //- Scalar receive buffer
-            mutable Field<scalar> scalarReceiveBuf_;
+            mutable solveScalarField scalarReceiveBuf_;
 
             //- Outstanding request
             mutable label outstandingSendRequest_;
@@ -99,10 +97,10 @@ protected:
 
         void addToInternalField
         (
-            scalarField& result,
+            solveScalarField& result,
             const bool add,
             const scalarField& coeffs,
-            const scalarField& vals
+            const solveScalarField& vals
         ) const;
 
 
@@ -201,24 +199,17 @@ public:
             {
                 return pTraits<Type>::rank;
             }
- 
+
 
         // Access
 
-            //- Return true if this patch field is coupled. Our field supplies
-            //  coefficients to the fvMatrix so should behave as a
-            //  processorFvPatchField (in addBoundarySource it should not add
-            //  to the source)
+            //- Return true if this patch field is coupled.
+            //  Our field supplies coefficients to the fvMatrix so
+            //  should behave as a processorFvPatchField (in
+            //  addBoundarySource it should not add to the source)
             virtual bool coupled() const
             {
-                if (Pstream::parRun())
-                {
-                    return true;
-                }
-                else
-                {
-                    return false;
-                }
+                return Pstream::parRun();
             }
 
             //- Return neighbour field of internal field
@@ -239,9 +230,9 @@ public:
             //- Initialise neighbour matrix update
             virtual void initInterfaceMatrixUpdate
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
@@ -250,9 +241,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                scalarField& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/overset/oversetPolyPatch/oversetFvPatch.C b/src/overset/oversetPolyPatch/oversetFvPatch.C
index f378ec8a17590e1667fba199ee5febc85299d8e7..f4c6b0b0783e345aa622236ae9c15390f88d47a8 100644
--- a/src/overset/oversetPolyPatch/oversetFvPatch.C
+++ b/src/overset/oversetPolyPatch/oversetFvPatch.C
@@ -39,6 +39,4 @@ namespace Foam
 }
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
 // ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/oversetFvPatchField.C b/src/overset/oversetPolyPatch/oversetFvPatchField.C
index c34e8a3071dd81aba7591cd95cc7011dd54ffef4..a124e2328b83068e40fb6ca28cd705584ce810c6 100644
--- a/src/overset/oversetPolyPatch/oversetFvPatchField.C
+++ b/src/overset/oversetPolyPatch/oversetFvPatchField.C
@@ -216,140 +216,6 @@ void Foam::oversetFvPatchField<Type>::initEvaluate
 }
 
 
-//template<class Type>
-//void Foam::oversetFvPatchField<Type>::initInterfaceMatrixUpdate
-//(
-//    scalarField&,
-//    const bool add,
-//    const scalarField& psiInternal,
-//    const scalarField&,
-//    const direction,
-//    const Pstream::commsTypes commsType
-//) const
-//{
-////    // Add remote values
-////
-////    const oversetFvPatch& ovp = this->oversetPatch_;
-////
-////    if (ovp.master())
-////    {
-////        const fvMesh& mesh = this->patch().boundaryMesh().mesh();
-////
-////        // Try to find out if the solve routine comes from the mesh
-////        // TBD. This should be cleaner.
-////        if (&mesh.lduAddr() == &mesh.fvMesh::lduAddr())
-////        {
-////            return;
-////        }
-////
-////        const mapDistribute& map = ovp.cellInterpolationMap();
-////
-////        // Transfer the current state (similar to processorFvPatchField).
-////        // Note
-////        // use of separate tag to avoid clashes with any outstanding
-////        // processor exchanges
-////        if (this->pBufs_.valid())
-////        {
-////            this->pBufs_().clear();
-////        }
-////        else
-////        {
-////            this->pBufs_.set
-////            (
-////                new PstreamBuffers
-////                (
-////                    Pstream::commsTypes::nonBlocking,
-////                    UPstream::msgType()+1
-////                )
-////            );
-////        }
-////
-////        // Start sending
-////        map.mapDistributeBase::send(this->pBufs_(), psiInternal);
-////    }
-//}
-//
-//
-//template<class Type>
-//void Foam::oversetFvPatchField<Type>::updateInterfaceMatrix
-//(
-//    scalarField& result,
-//    const bool add,
-//    const scalarField& psiInternal,
-//    const scalarField& coeffs,
-//    const direction cmpt,
-//    const Pstream::commsTypes
-//) const
-//{
-////    // Add remote values
-////
-////    const oversetFvPatch& ovp = this->oversetPatch_;
-////
-////    if (ovp.master())
-////    {
-////        const fvMesh& mesh = this->patch().boundaryMesh().mesh();
-////
-////        // Try to find out if the solve routine comes from the mesh
-////        // TBD. This should be cleaner.
-////        if (&mesh.lduAddr() == &mesh.fvMesh::lduAddr())
-////        {
-////            return;
-////        }
-////
-////        const labelListList& stencil = ovp.stencil();
-////
-////        if (stencil.size() != psiInternal.size())
-////        {
-////            FatalErrorInFunction << "psiInternal:" << psiInternal.size()
-////                << " stencil:" << stencil.size() << exit(FatalError);
-////        }
-////
-////        const mapDistribute& map = ovp.cellInterpolationMap();
-////        const List<scalarList>& wghts = ovp.cellInterpolationWeights();
-////        const labelList& cellIDs = ovp.interpolationCells();
-////        const scalarList& factor = ovp.cellInterpolationWeight();
-////        const scalarField& normalisation = ovp.normalisation();
-////
-////        // Since we're inside initEvaluate/evaluate there might be processor
-////        // comms underway. Change the tag we use.
-////        //scalarField work(psiInternal);
-////        //map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
-////
-////        // Receive the outstanding data
-////        scalarField work;
-////        map.receive(this->pBufs_(), work);
-////
-////        forAll(cellIDs, i)
-////        {
-////            label celli = cellIDs[i];
-////
-////            const scalarList& w = wghts[celli];
-////            const labelList& nbrs = stencil[celli];
-////
-////            scalar f = factor[celli];
-////            const scalar norm = normalisation[celli];
-////
-////            // Add the non-local matrix contribution to psi. Note that the
-////            // matrix coefficients are -weights
-////
-////            if (add)
-////            {
-////                f = -1.0*f;
-////            }
-////
-////            forAll(nbrs, nbrI)
-////            {
-////                label slotI = nbrs[nbrI];
-////                if (slotI >= psiInternal.size())
-////                {
-////                    result[celli] += f*norm*w[nbrI]*work[slotI];
-////                }
-////            }
-////        }
-////    }
-//}
-
-
 template<class Type>
 void Foam::oversetFvPatchField<Type>::write(Ostream& os) const
 {
diff --git a/src/overset/oversetPolyPatch/oversetFvPatchField.H b/src/overset/oversetPolyPatch/oversetFvPatchField.H
index f4ba1b013bc4c6a9b7f893eb773512532a99d717..27b6eef0344183ea23a25448d96d1894dabe88f4 100644
--- a/src/overset/oversetPolyPatch/oversetFvPatchField.H
+++ b/src/overset/oversetPolyPatch/oversetFvPatchField.H
@@ -66,9 +66,6 @@ protected:
         //- Master patch ID
         mutable label masterPatchID_;
 
-        //- Send/receive buffer
-        //mutable autoPtr<PstreamBuffers> pBufs_;
-
 
 public:
 
@@ -141,32 +138,6 @@ public:
             //- Initialise the evaluation of the patch field
             virtual void initEvaluate(const Pstream::commsTypes commsType);
 
-//            using LduInterfaceField<Type>::initInterfaceMatrixUpdate;
-//
-//            //- Initialise neighbour matrix update. Add
-//            //- or subtract coupled contributions to matrix
-//            virtual void initInterfaceMatrixUpdate
-//            (
-//                scalarField&,
-//                const bool add,
-//                const scalarField&,
-//                const scalarField&,
-//                const direction,
-//                const Pstream::commsTypes commsType
-//            ) const;
-//
-//            //- Update result field based on interface functionality
-//            virtual void updateInterfaceMatrix
-//            (
-//                scalarField& result,
-//                const bool add,
-//                const scalarField& psiInternal,
-//                const scalarField& coeffs,
-//                const direction cmpt,
-//                const Pstream::commsTypes commsType
-//            ) const;
-
-
         // I-O
 
             //- Write
diff --git a/src/overset/oversetPolyPatch/oversetGAMGInterface.C b/src/overset/oversetPolyPatch/oversetGAMGInterface.C
deleted file mode 100644
index 968da1bc7c5d7e6987d84f1e05237a399806341d..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/oversetGAMGInterface.C
+++ /dev/null
@@ -1,260 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "oversetGAMGInterface.H"
-#include "addToRunTimeSelectionTable.H"
-#include "Map.H"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    defineTypeNameAndDebug(oversetGAMGInterface, 0);
-    addToRunTimeSelectionTable
-    (
-        GAMGInterface,
-        oversetGAMGInterface,
-        lduInterface
-    );
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::oversetGAMGInterface::oversetGAMGInterface
-(
-    const label index,
-    const lduInterfacePtrsList& coarseInterfaces,
-    const lduInterface& fineInterface,
-    const labelField& localRestrictAddressing,
-    const labelField& neighbourRestrictAddressing,
-    const label fineLevelIndex,
-    const label coarseComm
-)
-:
-    GAMGInterface(index, coarseInterfaces),
-    fineOversetInterface_
-    (
-        refCast<const oversetLduInterface>(fineInterface)
-    )
-{
-    Pout<< "Constructing oversetGAMGInterface index:" << index
-        << " from:" << fineOversetInterface_.name()
-        << " size:" << localRestrictAddressing.size()
-        << endl;
-
-    // From coarse face to coarse cell
-    DynamicList<label> dynFaceCells(localRestrictAddressing.size());
-    // From fine face to coarse face
-    DynamicList<label> dynFaceRestrictAddressing(dynFaceCells.size());
-
-
-    // From coarse cell to coarse face
-    Map<label> cellToCoarseFace(dynFaceCells.size());
-
-    // Construct face agglomeration from cell agglomeration
-    forAll(localRestrictAddressing, ffi)
-    {
-        // Get coarse cell
-        label coarseCelli = localRestrictAddressing[ffi];
-
-        // Do we have coarse face for it?
-        const auto iter = cellToCoarseFace.cfind(coarseCelli);
-        if (iter.found())
-        {
-            dynFaceRestrictAddressing.append(iter.val());
-        }
-        else
-        {
-            const label coarseFacei = dynFaceCells.size();
-            cellToCoarseFace.insert(coarseCelli, coarseFacei);
-            dynFaceCells.append(coarseCelli);
-            dynFaceRestrictAddressing.append(coarseFacei);
-        }
-    }
-
-    faceCells_.transfer(dynFaceCells);
-    faceRestrictAddressing_.transfer(dynFaceRestrictAddressing);
-
-    //Pout<< "** Constructed interface:" << name()
-    //    << " of size:" << size() << endl;
-
-
-    // Determine this level's stencil from the fine stencil
-    if (master())
-    {
-        const mapDistribute& fineMap =
-            fineOversetInterface_.cellInterpolationMap();
-        const List<scalarList>& fineWghts =
-            fineOversetInterface_.cellInterpolationWeights();
-        const labelListList& fineStencil = fineOversetInterface_.stencil();
-        const labelList& fineCellIDs =
-            fineOversetInterface_.interpolationCells();
-        const scalarList& fineFactor =
-            fineOversetInterface_.cellInterpolationWeight();
-        const scalarField& fineNorm = fineOversetInterface_.normalisation();
-        const labelList& restrictMap = fineOversetInterface_.restrictMap();
-
-
-        if (localRestrictAddressing.size() && restrictMap.empty())
-        {
-            FatalErrorInFunction
-                << "The restrict addressing has not been saved on interface "
-                << this->name()
-                << ". This gets stored when running internalFieldTransfer"
-                << exit(FatalError);
-        }
-
-
-        // 'Interpolate' the restrict map so locally we know what the remote
-        // cells are going to be.
-
-        label nCoarseCells = max(restrictMap)+1;
-        globalIndex globalNumbering(nCoarseCells);
-
-        labelList globalCoarseIDs(globalNumbering.toGlobal(restrictMap));
-
-        fineMap.distribute(globalCoarseIDs);
-
-        //Pout<< this->name()
-        //    << " index:" << index
-        //    << " size:" << this->size()
-        //    << " restrictMap:" << restrictMap.size()
-        //    << " fineNumInterpolate:" << fineCellIDs.size()
-        //    << " nCoarseCells:" << nCoarseCells
-        //    << endl;
-
-
-
-        // Accumulate the coarse level stencil
-
-        // Number of fine cells contributing to the coarse cell
-        labelList nFineCells(nCoarseCells, Zero);
-
-        stencil_.setSize(nCoarseCells);
-        cellInterpolationWeights_.setSize(nCoarseCells);
-        cellInterpolationWeight_.setSize(nCoarseCells, 0.0);
-        normalisation_.setSize(nCoarseCells, 0.0);
-
-        forAll(fineCellIDs, i)
-        {
-            label fineCelli = fineCellIDs[i];
-            label coarseCelli = restrictMap[fineCelli];
-
-            const scalarList& w = fineWghts[fineCelli];
-            const labelList& nbrs = fineStencil[fineCelli];
-
-            // Accumulate stencil
-
-            labelList& coarseStencil = stencil_[coarseCelli];
-            scalarList& coarseWghts = cellInterpolationWeights_[coarseCelli];
-
-            label sz = coarseStencil.size();
-            coarseStencil.setSize(sz+nbrs.size());
-            coarseWghts.setSize(coarseStencil.size());
-
-            forAll(nbrs, i)
-            {
-                coarseStencil[sz] = globalCoarseIDs[nbrs[i]];
-                coarseWghts[sz] = w[i];
-                sz++;
-            }
-
-            // Accumulate weight
-            cellInterpolationWeight_[coarseCelli] += fineFactor[fineCelli];
-            normalisation_[coarseCelli] += fineNorm[fineCelli];
-            nFineCells[coarseCelli]++;
-        }
-
-        // Normalise weight (0 .. 1). Take average? Volume average? Min? Max?
-        forAll(nFineCells, coarseCelli)
-        {
-            label nAvg = nFineCells[coarseCelli];
-            if (nAvg > 0)
-            {
-                cellInterpolationWeight_[coarseCelli] /= nAvg;
-            }
-        }
-
-
-        // Work the stencil back from global cells into a mapDistribute
-        // + slots
-        List<Map<label>> compactMap;
-        mapPtr_.reset(new mapDistribute(globalNumbering, stencil_, compactMap));
-
-
-        // Determine the interpolationCells
-        label nInterpolate = 0;
-        forAll(stencil_, coarseCelli)
-        {
-            if (stencil_[coarseCelli].size())
-            {
-                nInterpolate++;
-            }
-        }
-
-        //Pout<< this->name() << " nInterpolate:" << nInterpolate << endl;
-
-        interpolationCells_.setSize(nInterpolate);
-        nInterpolate = 0;
-        forAll(stencil_, coarseCelli)
-        {
-            if (stencil_[coarseCelli].size())
-            {
-                interpolationCells_[nInterpolate++] = coarseCelli;
-            }
-        }
-    }
-}
-
-
-// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
-
-Foam::oversetGAMGInterface::~oversetGAMGInterface()
-{}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-Foam::tmp<Foam::labelField> Foam::oversetGAMGInterface::internalFieldTransfer
-(
-    const Pstream::commsTypes,
-    const labelUList& restrictMap
-) const
-{
-    // Store the restrictMap. This routine gets used for
-    // - GAMGAgglomeration      : this is the use we want to intercept.
-    // - GAMGProcAgglomeration  : to find out the cell number on the other side
-    // - MGridGenGAMGAgglomeration: same
-    if (master())
-    {
-        restrictMap_ = restrictMap;
-    }
-
-    return tmp<labelField>::New(restrictMap, faceCells());
-}
-
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/oversetGAMGInterface.H b/src/overset/oversetPolyPatch/oversetGAMGInterface.H
deleted file mode 100644
index c8ddf07cb46a8208f9c41a7fa99e735efee23b21..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/oversetGAMGInterface.H
+++ /dev/null
@@ -1,202 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Class
-    Foam::oversetGAMGInterface
-
-Description
-    GAMG agglomerated overset interface.
-
-SourceFiles
-    oversetGAMGInterface.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef oversetGAMGInterface_H
-#define oversetGAMGInterface_H
-
-#include "GAMGInterface.H"
-#include "oversetLduInterface.H"
-#include "mapDistribute.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-                  Class oversetGAMGInterface Declaration
-\*---------------------------------------------------------------------------*/
-
-class oversetGAMGInterface
-:
-    public GAMGInterface,
-    virtual public oversetLduInterface
-{
-    // Private data
-
-        //- Reference for the oversetLduInterface from which this is
-        //  agglomerated
-        const oversetLduInterface& fineOversetInterface_;
-
-        //- Temporary copy of the fine level restrict map. Cleared upon
-        //  calculating stencils below
-        mutable labelList restrictMap_;
-
-        labelListList stencil_;
-
-        autoPtr<mapDistribute> mapPtr_;
-
-        List<scalarList> cellInterpolationWeights_;
-
-        scalarField normalisation_;
-
-        labelList interpolationCells_;
-
-        scalarList cellInterpolationWeight_;
-
-
-    // Private Member Functions
-
-        //- No copy construct
-        oversetGAMGInterface(const oversetGAMGInterface&) = delete;
-
-        //- No copy assignment
-        void operator=(const oversetGAMGInterface&) = delete;
-
-
-public:
-
-    //- Runtime type information
-    TypeName("overset");
-
-
-    // Constructors
-
-        //- Construct from fine level interface,
-        //  local and neighbour restrict addressing
-        oversetGAMGInterface
-        (
-            const label index,
-            const lduInterfacePtrsList& coarseInterfaces,
-            const lduInterface& fineInterface,
-            const labelField& localRestrictAddressing,
-            const labelField& neighbourRestrictAddressing,
-            const label fineLevelIndex,
-            const label coarseComm
-        );
-
-
-    //- Destructor
-    virtual ~oversetGAMGInterface();
-
-
-    // Member Functions
-
-        // Interface transfer functions
-
-            //- Transfer and return internal field adjacent to the interface
-            virtual tmp<labelField> internalFieldTransfer
-            (
-                const Pstream::commsTypes commsType,
-                const labelUList& iF
-            ) const;
-
-
-        //- Overset interface functions
-
-            //- Name of lduInterface
-            virtual const word& name() const
-            {
-                return fineOversetInterface_.name();
-            }
-
-            //- Am I the master interface
-            virtual bool master() const
-            {
-                return fineOversetInterface_.master();
-            }
-
-            //- GAMG restriction (fine-to-coarse)
-            virtual const labelList& restrictMap() const
-            {
-                return restrictMap_;
-            }
-
-            //- Donor stencil
-            virtual const labelListList& stencil() const
-            {
-                return stencil_;
-            }
-
-            //- Map for obtaining data in stencil order
-            virtual const mapDistribute& cellInterpolationMap() const
-            {
-                return *mapPtr_;
-            }
-
-            //- Weights in stencil order
-            virtual const List<scalarList>& cellInterpolationWeights() const
-            {
-                return cellInterpolationWeights_;
-            }
-
-            //- Normalisation ot matrix; for explicit contributions
-            virtual const scalarField& normalisation() const
-            {
-                return normalisation_;
-            }
-
-            //- Acceptor cells
-            virtual const labelList& interpolationCells() const
-            {
-                return interpolationCells_;
-            }
-
-            //- Underrelaxation for acceptor cells
-            virtual const scalarList& cellInterpolationWeight() const
-            {
-                return cellInterpolationWeight_;
-            }
-
-
-        // I/O
-
-            //- Write to stream
-            virtual void write(Ostream&) const
-            {
-                //TBD.
-                NotImplemented;
-            }
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/oversetGAMGInterfaceField.C b/src/overset/oversetPolyPatch/oversetGAMGInterfaceField.C
deleted file mode 100644
index f6be6ea8e18527b42add02b0cca149ae91e5b6cd..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/oversetGAMGInterfaceField.C
+++ /dev/null
@@ -1,152 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "oversetGAMGInterfaceField.H"
-#include "addToRunTimeSelectionTable.H"
-#include "lduMatrix.H"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    defineTypeNameAndDebug(oversetGAMGInterfaceField, 0);
-    addToRunTimeSelectionTable
-    (
-        GAMGInterfaceField,
-        oversetGAMGInterfaceField,
-        lduInterfaceField
-    );
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::oversetGAMGInterfaceField::oversetGAMGInterfaceField
-(
-    const GAMGInterface& GAMGCp,
-    const lduInterfaceField& fineInterface
-)
-:
-    GAMGInterfaceField(GAMGCp, fineInterface),
-    oversetInterface_(refCast<const oversetGAMGInterface>(GAMGCp))
-{}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::oversetGAMGInterfaceField::~oversetGAMGInterfaceField()
-{}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::oversetGAMGInterfaceField::updateInterfaceMatrix
-(
-    scalarField& result,
-    const bool add,
-    const scalarField& psiInternal,
-    const scalarField& coeffs,
-    const direction cmpt,
-    const Pstream::commsTypes commsType
-) const
-{
-    Pout<< "oversetGAMGInterfaceField::updateInterfaceMatrix: at:"
-    //    << oversetInterface_.name()
-        << " nCells:" << result.size() << endl;
-    //
-//    // Add remote values
-//    if (oversetInterface_.master())
-//    {
-//        const labelListList& stencil = oversetInterface_.stencil();
-//
-//        if (stencil.size() != psiInternal.size())
-//        {
-//            FatalErrorInFunction << "psiInternal:" << psiInternal.size()
-//                << " stencil:" << stencil.size() << exit(FatalError);
-//        }
-//
-//        const mapDistribute& map = oversetInterface_.cellInterpolationMap();
-//        const List<scalarList>& wghts =
-//            oversetInterface_.cellInterpolationWeights();
-//        const labelList& cellIDs = oversetInterface_.interpolationCells();
-//        const scalarList& factor = oversetInterface_.cellInterpolationWeight();
-//        const scalarField& normalisation = oversetInterface_.normalisation();
-//
-//        scalarField work(psiInternal);
-//        map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
-//
-//        forAll(cellIDs, i)
-//        {
-//            label celli = cellIDs[i];
-//
-//            const scalarList& w = wghts[celli];
-//            const labelList& nbrs = stencil[celli];
-//            const scalar f = factor[celli];
-//
-//            bool hasRemote = false;
-//            forAll(nbrs, nbrI)
-//            {
-//                label slotI = nbrs[nbrI];
-//                if (slotI >= psiInternal.size())
-//                {
-//                    hasRemote = true;
-//                    break;
-//                }
-//            }
-//
-//            if (hasRemote)
-//            {
-//                //Pout<< "oversetGAMGInterfaceField : Interpolating " << celli
-//                //    << " from remote values (if any):" << endl;
-//                scalar s(0.0);
-//                forAll(nbrs, nbrI)
-//                {
-//                    label slotI = nbrs[nbrI];
-//                    if (slotI >= psiInternal.size())
-//                    {
-//                        //Pout<< "    remote value " << work[slotI]
-//                        //    << " from slot " << slotI << " with w:" << w[nbrI]
-//                        //    << endl;
-//                        s += w[nbrI]*work[slotI];
-//                    }
-//                }
-//                //Pout<< "oversetGAMGInterfaceField : Interpolated value:"
-//                //    << s << endl;
-//                //scalar oldPsi = result[celli];
-//                if (add)
-//                {
-//                    s = -1.0*s;
-//                }
-//
-//                result[celli] += normalisation[celli]*f*s;
-//                //Pout<< "oversetGAMGInterfaceField : result was:" << oldPsi
-//                //    << " now:" << result[celli] << endl;
-//            }
-//        }
-//    }
-}
-
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/oversetGAMGInterfaceField.H b/src/overset/oversetPolyPatch/oversetGAMGInterfaceField.H
deleted file mode 100644
index 146ae73948af74d08c83b99665648f935d2ce784..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/oversetGAMGInterfaceField.H
+++ /dev/null
@@ -1,128 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Class
-    Foam::oversetGAMGInterfaceField
-
-Description
-    GAMG agglomerated processor interface field.
-
-SourceFiles
-    processorGAMGInterfaceField.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef oversetGAMGInterfaceField_H
-#define oversetGAMGInterfaceField_H
-
-#include "GAMGInterfaceField.H"
-#include "oversetGAMGInterface.H"
-#include "processorLduInterfaceField.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-                  Class oversetGAMGInterfaceField Declaration
-\*---------------------------------------------------------------------------*/
-
-class oversetGAMGInterfaceField
-:
-    public GAMGInterfaceField
-{
-protected:
-
-    // Protected data
-
-        //- Local reference cast into the interface
-        const oversetGAMGInterface& oversetInterface_;
-
-
-private:
-
-    // Private Member Functions
-
-        //- No copy construct
-        oversetGAMGInterfaceField(const oversetGAMGInterfaceField&) = delete;
-
-        //- No copy assignment
-        void operator=(const oversetGAMGInterfaceField&) = delete;
-
-
-public:
-
-    //- Runtime type information
-    TypeName("overset");
-
-
-    // Constructors
-
-        //- Construct from GAMG interface and fine level interface field
-        oversetGAMGInterfaceField
-        (
-            const GAMGInterface& GAMGCp,
-            const lduInterfaceField& fineInterface
-        );
-
-
-    //- Destructor
-    virtual ~oversetGAMGInterfaceField();
-
-
-    // Member Functions
-
-        // Access
-
-            //- Return size
-            label size() const
-            {
-                return oversetInterface_.size();
-            }
-
-
-        // Interface matrix update
-
-            //- Update result field based on interface functionality
-            virtual void updateInterfaceMatrix
-            (
-                scalarField& result,
-                const bool add,
-                const scalarField& psiInternal,
-                const scalarField& coeffs,
-                const direction cmpt,
-                const Pstream::commsTypes commsType
-            ) const;
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/oversetLduInterface.C b/src/overset/oversetPolyPatch/oversetLduInterface.C
deleted file mode 100644
index ec04070196a1ac583f9ab38daf26206a49b63c61..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/oversetLduInterface.C
+++ /dev/null
@@ -1,42 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "oversetLduInterface.H"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-namespace Foam
-{
-defineTypeNameAndDebug(oversetLduInterface, 0);
-}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::oversetLduInterface::~oversetLduInterface()
-{}
-
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/oversetLduInterface.H b/src/overset/oversetPolyPatch/oversetLduInterface.H
deleted file mode 100644
index 537def21642d0195763ec0a05b55a37e4b5be3b4..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/oversetLduInterface.H
+++ /dev/null
@@ -1,111 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Class
-    Foam::oversetLduInterface
-
-Description
-    An abstract base class for overset coupled interfaces
-
-SourceFiles
-    oversetLduInterface.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef oversetLduInterface_H
-#define oversetLduInterface_H
-
-#include "mapDistribute.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-                      Class oversetLduInterface Declaration
-\*---------------------------------------------------------------------------*/
-
-class oversetLduInterface
-{
-
-public:
-
-    //- Runtime type information
-    TypeName("oversetLduInterface");
-
-
-    // Constructors
-
-        //- Construct null
-        oversetLduInterface()
-        {}
-
-
-    //- Destructor
-    virtual ~oversetLduInterface();
-
-
-    // Member Functions
-
-        // Access
-
-            //- Name of interface (for debugging)
-            virtual const word& name() const = 0;
-
-            //- Am I the master interface
-            virtual bool master() const = 0;
-
-            //- GAMG restriction (fine-to-coarse)
-            virtual const labelList& restrictMap() const = 0;
-
-            //- Donor stencil
-            virtual const labelListList& stencil() const = 0;
-
-            //- Map for obtaining data in stencil order
-            virtual const mapDistribute& cellInterpolationMap() const = 0;
-
-            //- Weights in stencil order
-            virtual const List<scalarList>&
-            cellInterpolationWeights() const = 0;
-
-            //- Normalisation of matrix; for explicit contributions
-            virtual const scalarField& normalisation() const = 0;
-
-            //- Acceptor cells
-            virtual const labelList& interpolationCells() const = 0;
-
-            //- Underrelaxation for acceptor cells
-            virtual const scalarList& cellInterpolationWeight() const = 0;
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchField.C b/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchField.C
deleted file mode 100644
index f9a5e79d27a1f14395895007543088251b245745..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchField.C
+++ /dev/null
@@ -1,274 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "volFields.H"
-#include "cellCellStencilObject.H"
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-template<class Type>
-Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
-(
-    const fvPatch& p,
-    const DimensionedField<Type, volMesh>& iF
-)
-:
-    //LduInterfaceField<Type>(refCast<const oversetFvPatch>(p)),
-    zeroGradientFvPatchField<Type>(p, iF),
-    oversetPatch_(refCast<const oversetFvPatch>(p))
-{}
-
-
-template<class Type>
-Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
-(
-    const semiImplicitOversetFvPatchField<Type>& ptf,
-    const fvPatch& p,
-    const DimensionedField<Type, volMesh>& iF,
-    const fvPatchFieldMapper& mapper
-)
-:
-    //LduInterfaceField<Type>(refCast<const oversetFvPatch>(p)),
-    zeroGradientFvPatchField<Type>(ptf, p, iF, mapper),
-    oversetPatch_(refCast<const oversetFvPatch>(p))
-{
-    if (!isA<oversetFvPatch>(this->patch()))
-    {
-        FatalErrorInFunction
-            << "    patch type '" << p.type()
-            << "' not constraint type '" << typeName << "'"
-            << "\n    for patch " << p.name()
-            << " of field " << this->internalField().name()
-            << " in file " << this->internalField().objectPath()
-            << exit(FatalIOError);
-    }
-}
-
-
-template<class Type>
-Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
-(
-    const fvPatch& p,
-    const DimensionedField<Type, volMesh>& iF,
-    const dictionary& dict
-)
-:
-    //LduInterfaceField<Type>(refCast<const oversetFvPatch>(p)),
-    zeroGradientFvPatchField<Type>(p, iF, dict),
-    oversetPatch_(refCast<const oversetFvPatch>(p))
-{
-    if (!isA<oversetFvPatch>(p))
-    {
-        FatalIOErrorInFunction(dict)
-            << "    patch type '" << p.type()
-            << "' not constraint type '" << typeName << "'"
-            << "\n    for patch " << p.name()
-            << " of field " << this->internalField().name()
-            << " in file " << this->internalField().objectPath()
-            << exit(FatalIOError);
-    }
-
-    if (!dict.found("value") && this->coupled())
-    {
-        this->evaluate(Pstream::commsTypes::blocking);
-    }
-}
-
-
-template<class Type>
-Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
-(
-    const semiImplicitOversetFvPatchField<Type>& ptf
-)
-:
-    //LduInterfaceField<Type>(ptf.oversetPatch_),
-    zeroGradientFvPatchField<Type>(ptf),
-    oversetPatch_(ptf.oversetPatch_)
-{}
-
-
-template<class Type>
-Foam::semiImplicitOversetFvPatchField<Type>::semiImplicitOversetFvPatchField
-(
-    const semiImplicitOversetFvPatchField<Type>& ptf,
-    const DimensionedField<Type, volMesh>& iF
-)
-:
-    //LduInterfaceField<Type>(ptf.oversetPatch_),
-    zeroGradientFvPatchField<Type>(ptf, iF),
-    oversetPatch_(ptf.oversetPatch_)
-{}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<class Type>
-void Foam::semiImplicitOversetFvPatchField<Type>::evaluate
-(
-    const Pstream::commsTypes
-)
-{
-    if (debug)
-    {
-        Pout<< FUNCTION_NAME << " field " <<  this->internalField().name()
-            << " patch " << this->patch().name() << endl;
-    }
-
-
-    if (!this->updated())
-    {
-        this->updateCoeffs();
-    }
-
-    zeroGradientFvPatchField<Type>::evaluate();
-}
-
-
-template<class Type>
-void Foam::semiImplicitOversetFvPatchField<Type>::initEvaluate
-(
-    const Pstream::commsTypes commsType
-)
-{
-    if (debug)
-    {
-        Pout<< FUNCTION_NAME << " field " <<  this->internalField().name()
-            << " patch " << this->patch().name() << endl;
-    }
-
-    if (this->oversetPatch().master())
-    {
-        // Trigger interpolation
-        const fvMesh& mesh = this->internalField().mesh();
-        //const dictionary& fvSchemes = mesh.schemesDict();
-        const word& fldName = this->internalField().name();
-
-        if (&mesh.lduAddr() != &mesh.fvMesh::lduAddr())
-        {
-            // Running extended addressing so called from within fvMatrix::solve
-            FatalErrorInFunction
-                << "Running extended addressing is not allowed when solving "
-                << fldName
-                << " Please choose a dynamicFvMesh without matrix adaptation"
-                << exit(FatalError);
-        }
-        else
-        {
-            if (debug)
-            {
-                Info<< "Interpolating field " << fldName << endl;
-            }
-
-            // Interpolate without bc update (since would trigger infinite
-            // recursion back to
-            // semiImplicitOversetFvPatchField<Type>::evaluate)
-            // The only problem is bcs that use the new cell values
-            // (e.g. zeroGradient, processor). These need to appear -after-
-            // the 'overset' bc.
-            mesh.interpolate
-            (
-                const_cast<Field<Type>&>
-                (
-                    this->primitiveField()
-                )
-            );
-        }
-    }
-}
-
-
-//template<class Type>
-//void Foam::semiImplicitOversetFvPatchField<Type>::updateInterfaceMatrix
-//(
-//    scalarField& result,
-//    const bool add,
-//    const scalarField& psiInternal,
-//    const scalarField& coeffs,
-//    const direction cmpt,
-//    const Pstream::commsTypes
-//) const
-//{
-//    if (debug)
-//    {
-//        Pout<< FUNCTION_NAME << " field " <<  this->internalField().name()
-//            << " patch " << this->patch().name() << endl;
-//    }
-//
-//    const oversetFvPatch& ovp = this->oversetPatch();
-//
-//    // Set all interpolated cells
-//    if (ovp.master())
-//    {
-//        const cellCellStencilObject& overlap = Stencil::New(*this);
-//        const labelListList& cellStencil = overlap.cellStencil();
-//
-//        if (cellStencil.size() != psiInternal.size())
-//        {
-//            FatalErrorInFunction << "psiInternal:" << psiInternal.size()
-//                << " stencil:" << cellStencil.size() << exit(FatalError);
-//        }
-//
-//        const mapDistribute& map = overlap.cellInterpolationMap();
-//        const List<scalarList>& wghts = overlap.cellInterpolationWeights();
-//        const labelList& cellIDs = overlap.interpolationCells();
-//        //const scalarList& factor = overlap.cellInterpolationWeight();
-//
-//        // Since we're inside initEvaluate/evaluate there might be processor
-//        // comms underway. Change the tag we use.
-//        scalarField work(psiInternal);
-//        map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
-//
-//        forAll(cellIDs, i)
-//        {
-//            label celli = cellIDs[i];
-//
-//            const scalarList& w = wghts[celli];
-//            const labelList& nbrs = cellStencil[celli];
-//
-//            //scalar f = factor[celli];
-//
-//            scalar s(0.0);
-//            forAll(nbrs, nbrI)
-//            {
-//                s += w[nbrI]*work[nbrs[nbrI]];
-//            }
-//
-//            //Pout<< "cell:" << celli << " interpolated value:" << s << endl;
-//            result[celli] = s;  //(1.0-f)*result[celli] + f*s;
-//        }
-//    }
-//}
-
-
-template<class Type>
-void Foam::semiImplicitOversetFvPatchField<Type>::write(Ostream& os) const
-{
-    zeroGradientFvPatchField<Type>::write(os);
-    // Make sure to write the value for ease of postprocessing.
-    this->writeEntry("value", os);
-}
-
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchField.H b/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchField.H
deleted file mode 100644
index 78c51cbd4bc44393dda00358a26ac0146d6a8101..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchField.H
+++ /dev/null
@@ -1,207 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Class
-    Foam::semiImplicitOversetFvPatchField
-
-Group
-    grpCoupledBoundaryConditions
-
-Description
-    Boundary condition for use on overset patches. Implements update of
-    interpolated cells inside the linear solvers.
-
-SeeAlso
-
-SourceFiles
-    semiImplicitOversetFvPatchField.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef semiImplicitOversetFvPatchField_H
-#define semiImplicitOversetFvPatchField_H
-
-#include "oversetFvPatch.H"
-#include "zeroGradientFvPatchField.H"
-#include "LduInterfaceField.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-                 Class semiImplicitOversetFvPatchField Declaration
-\*---------------------------------------------------------------------------*/
-
-template<class Type>
-class semiImplicitOversetFvPatchField
-:
-    //public LduInterfaceField<Type>,
-    public zeroGradientFvPatchField<Type>
-{
-protected:
-
-    // Protected data
-
-        //- Local reference cast into the overset patch
-        const oversetFvPatch& oversetPatch_;
-
-        //- Master patch ID
-        mutable label masterPatchID_;
-
-
-public:
-
-    //- Runtime type information
-    TypeName("semiImplicitOverset");
-
-
-    // Constructors
-
-        //- Construct from patch and internal field
-        semiImplicitOversetFvPatchField
-        (
-            const fvPatch&,
-            const DimensionedField<Type, volMesh>&
-        );
-
-        //- Construct from patch, internal field and dictionary
-        semiImplicitOversetFvPatchField
-        (
-            const fvPatch&,
-            const DimensionedField<Type, volMesh>&,
-            const dictionary&
-        );
-
-        //- Construct by mapping given semiImplicitOversetFvPatchField onto a
-        //  new patch
-        semiImplicitOversetFvPatchField
-        (
-            const semiImplicitOversetFvPatchField<Type>&,
-            const fvPatch&,
-            const DimensionedField<Type, volMesh>&,
-            const fvPatchFieldMapper&
-        );
-
-        //- Construct as copy
-        semiImplicitOversetFvPatchField
-        (
-            const semiImplicitOversetFvPatchField<Type>&
-        );
-
-        //- Construct and return a clone
-        virtual tmp<fvPatchField<Type>> clone() const
-        {
-            return tmp<fvPatchField<Type>>
-            (
-                new semiImplicitOversetFvPatchField<Type>(*this)
-            );
-        }
-
-        //- Construct as copy setting internal field reference
-        semiImplicitOversetFvPatchField
-        (
-            const semiImplicitOversetFvPatchField<Type>&,
-            const DimensionedField<Type, volMesh>&
-        );
-
-        //- Construct and return a clone setting internal field reference
-        virtual tmp<fvPatchField<Type>> clone
-        (
-            const DimensionedField<Type, volMesh>& iF
-        ) const
-        {
-            return tmp<fvPatchField<Type>>
-            (
-                new semiImplicitOversetFvPatchField<Type>(*this, iF)
-            );
-        }
-
-
-    // Member functions
-
-        // Access
-
-            //- Return local reference cast into the cyclic AMI patch
-            const oversetFvPatch& oversetPatch() const
-            {
-                return oversetPatch_;
-            }
-
-
-        // Evaluation functions
-
-            //- Evaluate the patch field
-            virtual void evaluate(const Pstream::commsTypes commsType);
-
-             //- Initialise the evaluation of the patch field
-            virtual void initEvaluate(const Pstream::commsTypes commsType);
-
-//            //- Update result field based on interface functionality
-//            virtual void updateInterfaceMatrix
-//            (
-//                scalarField& result,
-//                const bool add,
-//                const scalarField& psiInternal,
-//                const scalarField& coeffs,
-//                const direction cmpt,
-//                const Pstream::commsTypes commsType
-//            ) const;
-//
-//            //- Update result field based on interface functionality
-//            virtual void updateInterfaceMatrix
-//            (
-//                Field<Type>&,
-//                const bool add,
-//                const Field<Type>&,
-//                const scalarField&,
-//                const Pstream::commsTypes commsType
-//            ) const
-//            {
-//                NotImplemented;
-//            }
-
-
-        // I-O
-
-            //- Write
-            virtual void write(Ostream& os) const;
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#ifdef NoRepository
-#   include "semiImplicitOversetFvPatchField.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchFields.C b/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchFields.C
deleted file mode 100644
index 1471e28ca46542c307ab22d146e6d41d8d69a798..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchFields.C
+++ /dev/null
@@ -1,43 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "semiImplicitOversetFvPatchFields.H"
-#include "addToRunTimeSelectionTable.H"
-#include "volFields.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-makePatchFields(semiImplicitOverset);
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchFields.H b/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchFields.H
deleted file mode 100644
index e943538791499b24b75237ad34ccebef975c66fb..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/semiImplicitOversetFvPatchFields.H
+++ /dev/null
@@ -1,49 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef semiImplicitOversetFvPatchFields_H
-#define semiImplicitOversetFvPatchFields_H
-
-#include "semiImplicitOversetFvPatchField.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-makePatchTypeFieldTypedefs(semiImplicitOverset);
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/semiImplicitOversetGAMGInterfaceField.C b/src/overset/oversetPolyPatch/semiImplicitOversetGAMGInterfaceField.C
deleted file mode 100644
index 10da619f8b32a40aca53b85f3d27ebaf09d3c174..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/semiImplicitOversetGAMGInterfaceField.C
+++ /dev/null
@@ -1,124 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "semiImplicitOversetGAMGInterfaceField.H"
-#include "addToRunTimeSelectionTable.H"
-#include "lduMatrix.H"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    defineTypeNameAndDebug(semiImplicitOversetGAMGInterfaceField, 0);
-    addToRunTimeSelectionTable
-    (
-        GAMGInterfaceField,
-        semiImplicitOversetGAMGInterfaceField,
-        lduInterfaceField
-    );
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::semiImplicitOversetGAMGInterfaceField::
-semiImplicitOversetGAMGInterfaceField
-(
-    const GAMGInterface& GAMGCp,
-    const lduInterfaceField& fineInterface
-)
-:
-    oversetGAMGInterfaceField(GAMGCp, fineInterface)
-{}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::semiImplicitOversetGAMGInterfaceField::
-~semiImplicitOversetGAMGInterfaceField()
-{}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::semiImplicitOversetGAMGInterfaceField::updateInterfaceMatrix
-(
-    scalarField& result,
-    const bool add,
-    const scalarField& psiInternal,
-    const scalarField& coeffs,
-    const direction cmpt,
-    const Pstream::commsTypes commsType
-) const
-{
-DebugVar("Here");
-
-    // Add remote values
-    if (oversetInterface_.master())
-    {
-        const labelListList& stencil = oversetInterface_.stencil();
-
-        if (stencil.size() != psiInternal.size())
-        {
-            FatalErrorInFunction << "psiInternal:" << psiInternal.size()
-                << " stencil:" << stencil.size() << exit(FatalError);
-        }
-
-        const mapDistribute& map = oversetInterface_.cellInterpolationMap();
-        const List<scalarList>& wghts =
-            oversetInterface_.cellInterpolationWeights();
-        const labelList& cellIDs = oversetInterface_.interpolationCells();
-        const scalarList& factor = oversetInterface_.cellInterpolationWeight();
-        const scalarField& normalisation = oversetInterface_.normalisation();
-
-        scalarField work(psiInternal);
-        map.mapDistributeBase::distribute(work, UPstream::msgType()+1);
-
-        forAll(cellIDs, i)
-        {
-            label celli = cellIDs[i];
-
-            const scalarList& w = wghts[celli];
-            const labelList& nbrs = stencil[celli];
-            const scalar f = factor[celli];
-
-            scalar s(0.0);
-            forAll(nbrs, nbrI)
-            {
-                label slotI = nbrs[nbrI];
-                s += w[nbrI]*work[slotI];
-            }
-            if (add)
-            {
-                s = -1.0*s;
-            }
-
-            result[celli] += normalisation[celli]*f*s;
-        }
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/src/overset/oversetPolyPatch/semiImplicitOversetGAMGInterfaceField.H b/src/overset/oversetPolyPatch/semiImplicitOversetGAMGInterfaceField.H
deleted file mode 100644
index ea24871b655ed3264f427df5aff85fe005265749..0000000000000000000000000000000000000000
--- a/src/overset/oversetPolyPatch/semiImplicitOversetGAMGInterfaceField.H
+++ /dev/null
@@ -1,108 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Class
-    Foam::semiImplicitOversetGAMGInterfaceField
-
-Description
-    GAMG agglomerated processor interface field.
-
-SourceFiles
-    processorGAMGInterfaceField.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef semiImplicitOversetGAMGInterfaceField_H
-#define semiImplicitOversetGAMGInterfaceField_H
-
-#include "oversetGAMGInterfaceField.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-              Class semiImplicitOversetGAMGInterfaceField Declaration
-\*---------------------------------------------------------------------------*/
-
-class semiImplicitOversetGAMGInterfaceField
-:
-    public oversetGAMGInterfaceField
-{
-    // Private Member Functions
-
-        //- No copy construct
-        semiImplicitOversetGAMGInterfaceField
-        (
-            const semiImplicitOversetGAMGInterfaceField&
-        ) = delete;
-
-        //- No copy assignment
-        void operator=(const semiImplicitOversetGAMGInterfaceField&) = delete;
-
-
-public:
-
-    //- Runtime type information
-    TypeName("semiImplicitOverset");
-
-
-    // Constructors
-
-        //- Construct from GAMG interface and fine level interface field
-        semiImplicitOversetGAMGInterfaceField
-        (
-            const GAMGInterface& GAMGCp,
-            const lduInterfaceField& fineInterface
-        );
-
-
-    //- Destructor
-    virtual ~semiImplicitOversetGAMGInterfaceField();
-
-
-    // Member Functions
-
-        //- Update result field based on interface functionality
-        virtual void updateInterfaceMatrix
-        (
-            scalarField& result,
-            const bool add,
-            const scalarField& psiInternal,
-            const scalarField& coeffs,
-            const direction cmpt,
-            const Pstream::commsTypes commsType
-        ) const;
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/regionCoupled/derivedFvPatchFields/energyRegionCoupled/energyRegionCoupledFvPatchScalarField.C b/src/regionCoupled/derivedFvPatchFields/energyRegionCoupled/energyRegionCoupledFvPatchScalarField.C
index b792f9d2d0a891119aacb41dec3cdeebcd7f6ad1..3d4ad1f217d7a304d44d15e2b07161650c7828ec 100644
--- a/src/regionCoupled/derivedFvPatchFields/energyRegionCoupled/energyRegionCoupledFvPatchScalarField.C
+++ b/src/regionCoupled/derivedFvPatchFields/energyRegionCoupled/energyRegionCoupledFvPatchScalarField.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2012-2016 OpenFOAM Foundation
@@ -29,6 +29,7 @@ License
 #include "energyRegionCoupledFvPatchScalarField.H"
 #include "Time.H"
 #include "turbulentFluidThermoModel.H"
+#include "PrecisionAdaptor.H"
 
 // * * * * * * * * * * * * * Static Member Data  * * * * * * * * * * * * * * //
 
@@ -392,9 +393,9 @@ patchInternalTemperatureField() const
 
 void Foam::energyRegionCoupledFvPatchScalarField::updateInterfaceMatrix
 (
-    Field<scalar>& result,
+    solveScalarField& result,
     const bool add,
-    const scalarField& psiInternal,
+    const solveScalarField& psiInternal,
     const scalarField& coeffs,
     const direction cmpt,
     const Pstream::commsTypes
@@ -404,7 +405,11 @@ void Foam::energyRegionCoupledFvPatchScalarField::updateInterfaceMatrix
 
     scalarField myHE(this->size());
 
-    if (&psiInternal == &primitiveField())
+    if
+    (
+        reinterpret_cast<const void*>(&psiInternal)
+     == reinterpret_cast<const void*>(&primitiveField())
+    )
     {
         label patchi = this->patch().index();
         const scalarField& pp =  thermoPtr_->p().boundaryField()[patchi];
@@ -422,8 +427,10 @@ void Foam::energyRegionCoupledFvPatchScalarField::updateInterfaceMatrix
         }
     }
 
+    ConstPrecisionAdaptor<solveScalar, scalar> tHE(myHE);
+
     // Multiply the field by coefficients and add into the result
-    this->addToInternalField(result, !add, coeffs, myHE);
+    this->addToInternalField(result, !add, coeffs, tHE());
 }
 
 
diff --git a/src/regionCoupled/derivedFvPatchFields/energyRegionCoupled/energyRegionCoupledFvPatchScalarField.H b/src/regionCoupled/derivedFvPatchFields/energyRegionCoupled/energyRegionCoupledFvPatchScalarField.H
index d9870281454229ae5700a378bcfeb2f205ecebd0..98d3726c48b8129f7d7182bb9e98f1e5b566a536 100644
--- a/src/regionCoupled/derivedFvPatchFields/energyRegionCoupled/energyRegionCoupledFvPatchScalarField.H
+++ b/src/regionCoupled/derivedFvPatchFields/energyRegionCoupled/energyRegionCoupledFvPatchScalarField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2012-2016 OpenFOAM Foundation
@@ -222,9 +222,9 @@ public:
             //- Update result field based on interface functionality
             virtual void updateInterfaceMatrix
             (
-                Field<scalar>& result,
+                solveScalarField& result,
                 const bool add,
-                const scalarField& psiInternal,
+                const solveScalarField& psiInternal,
                 const scalarField& coeffs,
                 const direction cmpt,
                 const Pstream::commsTypes commsType
diff --git a/src/thermophysicalModels/chemistryModel/chemistryModel/TDACChemistryModel/tabulation/ISAT/binaryTree/binaryTree.C b/src/thermophysicalModels/chemistryModel/chemistryModel/TDACChemistryModel/tabulation/ISAT/binaryTree/binaryTree.C
index f93df6a2256b1d275cb9c3d2ae9881b33862ca3e..8ec2aa8e6e6db83d7c6c1c3f9ae5a999cbec8050 100644
--- a/src/thermophysicalModels/chemistryModel/chemistryModel/TDACChemistryModel/tabulation/ISAT/binaryTree/binaryTree.C
+++ b/src/thermophysicalModels/chemistryModel/chemistryModel/TDACChemistryModel/tabulation/ISAT/binaryTree/binaryTree.C
@@ -658,7 +658,7 @@ void Foam::binaryTree<CompType, ThermoType>::balance()
         chemPoints[chemPointi++] = x;
         x = treeSuccessor(x);
     }
-    mean /= size_;
+    mean /= scalar(size_);
 
     //3) compute the variance for each space direction
     List<scalar> variance(n, Zero);