diff --git a/src/parallel/decompose/kahipDecomp/kahipDecomp.C b/src/parallel/decompose/kahipDecomp/kahipDecomp.C
index 9ad2b58eef9bcabd6d19e53996a123f4a88c71b7..8cdc367fb8f345013a072ca12530e6eb81fd26d3 100644
--- a/src/parallel/decompose/kahipDecomp/kahipDecomp.C
+++ b/src/parallel/decompose/kahipDecomp/kahipDecomp.C
@@ -26,6 +26,7 @@ License
 #include "kahipDecomp.H"
 #include "addToRunTimeSelectionTable.H"
 #include "Time.H"
+#include "PrecisionAdaptor.H"
 
 #include "kaHIP_interface.h"
 
@@ -33,6 +34,9 @@ License
 #include <map>
 #include <vector>
 
+// Provide a clear error message if we have a severe size mismatch
+// Allow widening, but not narrowing
+
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 namespace Foam
@@ -217,59 +221,30 @@ Foam::label Foam::kahipDecomp::decomposeSerial
     // Output: number of cut edges
     int edgeCut = 0;
 
-    #if WM_LABEL_SIZE == 32
-
-    // Input:
-    int* xadjPtr   = const_cast<int*>(xadj.begin());
-    int* adjncyPtr = const_cast<int*>(adjncy.begin());
+    // Addressing
+    ConstPrecisionAdaptor<int, label, List> xadj_param(xadj);
+    ConstPrecisionAdaptor<int, label, List> adjncy_param(adjncy);
 
     // Output: cell -> processor addressing
-    decomp.setSize(numCells);
-    int* decompPtr = decomp.begin();
-
-    #elif WM_LABEL_SIZE == 64
-
-    // input (copy)
-    List<int> xadjCopy(xadj.size());
-    List<int> adjncyCopy(adjncy.size());
-
-    forAll(xadj,i)
-    {
-        xadjCopy[i] = xadj[i];
-    }
-    forAll(adjncy,i)
-    {
-        adjncyCopy[i] = adjncy[i];
-    }
+    decomp.resize(numCells);
+    PrecisionAdaptor<int, label, List> decomp_param(decomp);
 
-    int* xadjPtr   = xadjCopy.begin();
-    int* adjncyPtr = adjncyCopy.begin();
-
-    if (decomp.size() != numCells)
-    {
-        decomp.clear();
-    }
-
-    // Output: cell -> processor addressing
-    List<int> decompCopy(numCells);
-    int* decompPtr = decompCopy.begin();
-    #endif
 
 #if 0 // WIP: #ifdef KAFFPA_CPP_INTERFACE
     kaffpa_cpp
     (
         &numCells,          // num vertices in graph
         (cellWeights.size() ? cellWeights.begin() : nullptr), // vertex wts
-        xadjPtr,            // indexing into adjncy
+        xadj_param.constCast().data(),          // indexing into adjncy
         nullptr,            // edge wts
-        adjncyPtr,          // neighbour info
+        adjncy_param.constCast().data(),        // neighbour info
         &nParts,            // nparts
         &imbalance,         // amount of imbalance allowed
         !verbose,           // suppress output
         seed,               // for random
         int(kahipConfig),
-        &edgeCut,           // [output]
-        decompPtr,          // [output]
+        &edgeCut,                   // [output]
+        decomp_param.ref().data(),  // [output]
         sizingParams
     );
 #else
@@ -277,35 +252,19 @@ Foam::label Foam::kahipDecomp::decomposeSerial
     (
         &numCells,          // num vertices in graph
         (cellWeights.size() ? cellWeights.begin() : nullptr), // vertex wts
-        xadjPtr,            // indexing into adjncy
+        xadj_param.constCast().data(),          // indexing into adjncy
         nullptr,            // edge wts
-        adjncyPtr,          // neighbour info
+        adjncy_param.constCast().data(),        // neighbour info
         &nParts,            // nparts
         &imbalance,         // amount of imbalance allowed
         !verbose,           // suppress output
         seed,               // for random
         int(kahipConfig),
-        &edgeCut,           // [output]
-        decompPtr           // [output]
+        &edgeCut,                   // [output]
+        decomp_param.ref().data()   // [output]
     );
 #endif
 
-    #if WM_LABEL_SIZE == 64
-
-    // Drop input copy
-    xadjCopy.clear();
-    adjncyCopy.clear();
-
-    // Copy back to List<label>
-    decomp.setSize(numCells);
-    forAll(decompCopy, i)
-    {
-        decomp[i] = decompCopy[i];
-    }
-
-    decompCopy.clear();
-    #endif
-
     return edgeCut;
 }
 
diff --git a/src/parallel/decompose/metisDecomp/metisDecomp.C b/src/parallel/decompose/metisDecomp/metisDecomp.C
index 422ceb367be7aeef9d64b7eb770dfa1557967918..e08d4ba88051884182449c8c3f9fe6cda4bdb90b 100644
--- a/src/parallel/decompose/metisDecomp/metisDecomp.C
+++ b/src/parallel/decompose/metisDecomp/metisDecomp.C
@@ -190,12 +190,12 @@ Foam::label Foam::metisDecomp::decomposeSerial
     idx_t nProcs = nDomains_;
 
     // Addressing
-    ConstPrecisionAdaptor<idx_t, label, List> xadj_metis(xadj);
-    ConstPrecisionAdaptor<idx_t, label, List> adjncy_metis(adjncy);
+    ConstPrecisionAdaptor<idx_t, label, List> xadj_param(xadj);
+    ConstPrecisionAdaptor<idx_t, label, List> adjncy_param(adjncy);
 
     // Output: cell -> processor addressing
-    PrecisionAdaptor<idx_t, label, List> decomp_metis(decomp);
-    decomp_metis.ref().setSize(numCells);
+    decomp.resize(numCells);
+    PrecisionAdaptor<idx_t, label, List> decomp_param(decomp);
 
     // Output: number of cut edges
     idx_t edgeCut = 0;
@@ -206,8 +206,8 @@ Foam::label Foam::metisDecomp::decomposeSerial
         (
             &numCells,                  // num vertices in graph
             &ncon,                      // num balancing constraints
-            xadj_metis.ref().data(),    // indexing into adjncy
-            adjncy_metis.ref().data(),  // neighbour info
+            xadj_param.constCast().data(),      // indexing into adjncy
+            adjncy_param.constCast().data(),    // neighbour info
             cellWeights.data(),         // vertex wts
             nullptr,                    // vsize: total communication vol
             faceWeights.data(),         // edge wts
@@ -216,7 +216,7 @@ Foam::label Foam::metisDecomp::decomposeSerial
             nullptr,                    // ubvec: processor imbalance (default)
             options.data(),
             &edgeCut,
-            decomp_metis.ref().data()
+            decomp_param.ref().data()
         );
     }
     else
@@ -225,8 +225,8 @@ Foam::label Foam::metisDecomp::decomposeSerial
         (
             &numCells,                  // num vertices in graph
             &ncon,                      // num balancing constraints
-            xadj_metis.ref().data(),    // indexing into adjncy
-            adjncy_metis.ref().data(),  // neighbour info
+            xadj_param.constCast().data(),      // indexing into adjncy
+            adjncy_param.constCast().data(),    // neighbour info
             cellWeights.data(),         // vertex wts
             nullptr,                    // vsize: total communication vol
             faceWeights.data(),         // edge wts
@@ -235,7 +235,7 @@ Foam::label Foam::metisDecomp::decomposeSerial
             nullptr,                    // ubvec: processor imbalance (default)
             options.data(),
             &edgeCut,
-            decomp_metis.ref().data()
+            decomp_param.ref().data()
         );
     }
 
diff --git a/src/parallel/decompose/scotchDecomp/scotchDecomp.C b/src/parallel/decompose/scotchDecomp/scotchDecomp.C
index 6718db79cfaeb4abdfea1d041d8e16513a295955..b4b34fcfb707a5c562b6ff256b3b1fb23883ea45 100644
--- a/src/parallel/decompose/scotchDecomp/scotchDecomp.C
+++ b/src/parallel/decompose/scotchDecomp/scotchDecomp.C
@@ -127,10 +127,10 @@ Foam::label Foam::scotchDecomp::decomposeSerial
         const label numericflag = 10*hasEdgeWeights+hasVertexWeights;
         str << baseval << ' ' << numericflag << nl;
 
-        for (label celli = 0; celli < xadj.size()-1; ++celli)
+        for (label celli = 1; celli < xadj.size(); ++celli)
         {
-            const label start = xadj[celli];
-            const label end = xadj[celli+1];
+            const label start = xadj[celli-1];
+            const label end = xadj[celli];
 
             str << end-start; // size