diff --git a/src/dummyThirdParty/ptscotchDecomp/dummyPtscotchDecomp.C b/src/dummyThirdParty/ptscotchDecomp/dummyPtscotchDecomp.C
index 1155a1728c016a9c6ed5941e16285e94aebe3c79..63b23ce1cbbc19da10d30be36dcb4c9c1af9e2b3 100644
--- a/src/dummyThirdParty/ptscotchDecomp/dummyPtscotchDecomp.C
+++ b/src/dummyThirdParty/ptscotchDecomp/dummyPtscotchDecomp.C
@@ -54,12 +54,6 @@ namespace Foam
 }
 
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::ptscotchDecomp::graphPath(const polyMesh& unused) const {}
-void Foam::ptscotchDecomp::check(const int retVal, const char* str) {}
-
-
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
 Foam::label Foam::ptscotchDecomp::decompose
@@ -77,25 +71,6 @@ Foam::label Foam::ptscotchDecomp::decompose
 }
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-Foam::label Foam::ptscotchDecomp::decompose
-(
-    const label adjncySize,
-    const label adjncy[],
-    const label xadjSize,
-    const label xadj[],
-    const List<scalar>& cWeights,
-    labelList& finalDecomp
-) const
-{
-    FatalErrorInFunction
-        << notImplementedMessage << exit(FatalError);
-
-    return -1;
-}
-
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::ptscotchDecomp::ptscotchDecomp
diff --git a/src/dummyThirdParty/scotchDecomp/dummyScotchDecomp.C b/src/dummyThirdParty/scotchDecomp/dummyScotchDecomp.C
index 535a9fa4815190899d2bad6fd9b355385733a50b..9259f8a85d1881f60805b0eb2ce5336de26e3d92 100644
--- a/src/dummyThirdParty/scotchDecomp/dummyScotchDecomp.C
+++ b/src/dummyThirdParty/scotchDecomp/dummyScotchDecomp.C
@@ -53,12 +53,6 @@ namespace Foam
     );
 }
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::scotchDecomp::graphPath(const polyMesh& unused) const {}
-
-void Foam::scotchDecomp::check(const int retVal, const char* str) {}
-
 
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
diff --git a/src/parallel/decompose/decompose/decompositionInformation.C b/src/parallel/decompose/decompose/decompositionInformation.C
index 0324ea602279e51b5ce33086bf896fc86df7679d..444560b47c0aabd1ff173141ccc11d6857c21393 100644
--- a/src/parallel/decompose/decompose/decompositionInformation.C
+++ b/src/parallel/decompose/decompose/decompositionInformation.C
@@ -41,15 +41,15 @@ void Foam::decompositionInformation::populate
     nDomains_ = nDomain;
 
     distrib_.clear();
-    distrib_.setSize(nDomain);
+    distrib_.resize(nDomain);
 
     for (labelList& subdist : distrib_)
     {
         subdist.clear();
-        subdist.setSize(nDomain, Zero);
+        subdist.resize(nDomain, Zero);
     }
 
-    const label nCells = xadj.size()-1;
+    const label nCells = max(0, xadj.size()-1);
     for (label celli = 0; celli < nCells; ++celli)
     {
         const label ownProc = decomp[celli];
@@ -167,7 +167,7 @@ void Foam::decompositionInformation::printSummary(Ostream& os) const
 void Foam::decompositionInformation::printDetails(Ostream& os) const
 {
     os  << "Decomposition details with (proc faces) "
-        "for each processor connection"<< nl << nl;
+        "for each processor connection" << nl << nl;
 
     forAll(distrib_, ownProc)
     {
@@ -195,7 +195,7 @@ void Foam::decompositionInformation::printDetails(Ostream& os) const
         // Second pass with details:
         if (facesCount)
         {
-            Info<< " ";
+            os  << ' ';
 
             forAll(subdist, neiProc)
             {
@@ -203,7 +203,7 @@ void Foam::decompositionInformation::printDetails(Ostream& os) const
 
                 if (n && ownProc != neiProc)
                 {
-                    os  << " (" << neiProc << " " << n << ")";
+                    os  << " (" << neiProc << ' ' << n << ')';
                 }
             }
         }
diff --git a/src/parallel/decompose/kahipDecomp/Make/options b/src/parallel/decompose/kahipDecomp/Make/options
index 29522afef0c4cad3b39cc63d6ffda2e099a9372a..3210de9a2fb388f67c5f0d4cbaaeb6d5837a8348 100644
--- a/src/parallel/decompose/kahipDecomp/Make/options
+++ b/src/parallel/decompose/kahipDecomp/Make/options
@@ -7,5 +7,6 @@ EXE_INC = \
  * openmp link dependency.
  */
 LIB_LIBS = \
-    -ldecompositionMethods \
-    -L$(KAHIP_LIB_DIR) $(LINK_OPENMP) -lkahip
+    -L$(FOAM_LIBBIN) -ldecompositionMethods \
+    -L$(KAHIP_LIB_DIR) $(LINK_OPENMP) \
+    -lkahip$(KAHIP_LIBNAME_SUFFIX)
diff --git a/src/parallel/decompose/kahipDecomp/kahipDecomp.C b/src/parallel/decompose/kahipDecomp/kahipDecomp.C
index e372d68dab8b496deaae1d11bc9e71c98717348c..bc3990d10722332eba12bd16d1e03f5e6483594a 100644
--- a/src/parallel/decompose/kahipDecomp/kahipDecomp.C
+++ b/src/parallel/decompose/kahipDecomp/kahipDecomp.C
@@ -94,37 +94,72 @@ Foam::label Foam::kahipDecomp::decomposeSerial
     }
     #endif
 
-    int numCells = xadj.size()-1;
+    int numCells = max(0, (xadj.size()-1));
 
-    // Cell weights (so on the vertices of the dual)
-    List<int> cellWeights;
+    // Addressing
+    ConstPrecisionAdaptor<int, label, List> adjncy_param(adjncy);
+    ConstPrecisionAdaptor<int, label, List> xadj_param(xadj);
+
+    // Output: cell -> processor addressing
+    decomp.resize(numCells);
+    decomp = 0;
+    PrecisionAdaptor<int, label, List> decomp_param(decomp, false);
+
+    // Avoid potential nullptr issues with zero-sized arrays
+    labelList adjncy_dummy, xadj_dummy, decomp_dummy;
+    if (!numCells)
+    {
+        adjncy_dummy.resize(1, 0);
+        adjncy_param.set(adjncy_dummy);
+
+        xadj_dummy.resize(2, 0);
+        xadj_param.set(xadj_dummy);
+
+        decomp_dummy.resize(1, 0);
+        decomp_param.clear();  // Avoid propagating spurious values
+        decomp_param.set(decomp_dummy);
+    }
+
+
+    // Graph
+    // ~~~~~
 
     // Check for externally provided cellweights and if so initialise weights
+
+    bool hasWeights = !cWeights.empty();
+
     // Note: min, not gMin since routine runs on master only.
-    const scalar minWeights = min(cWeights);
+    const scalar minWeights = hasWeights ? min(cWeights) : scalar(1);
 
-    if (!cWeights.empty())
+    if (minWeights <= 0)
     {
-        if (minWeights <= 0)
-        {
-            WarningInFunction
-                << "Illegal minimum weight " << minWeights
-                << endl;
-        }
+        hasWeights = false;
+        WarningInFunction
+            << "Illegal minimum weight " << minWeights
+            << " ... ignoring"
+            << endl;
+    }
+    else if (hasWeights && (cWeights.size() != numCells))
+    {
+        FatalErrorInFunction
+            << "Number of cell weights " << cWeights.size()
+            << " does not equal number of cells " << numCells
+            << exit(FatalError);
+    }
 
-        if (cWeights.size() != numCells)
-        {
-            FatalErrorInFunction
-                << "Number of cell weights " << cWeights.size()
-                << " does not equal number of cells " << numCells
-                << exit(FatalError);
-        }
+    // Cell weights (so on the vertices of the dual)
+    List<int> cellWeights;
 
+    if (hasWeights)
+    {
         // Convert to integers.
-        cellWeights.setSize(cWeights.size());
+        cellWeights.resize(cWeights.size());
         forAll(cellWeights, i)
         {
-            cellWeights[i] = int(cWeights[i]/minWeights);
+            cellWeights[i] = static_cast<int>
+            (
+                cWeights[i]/minWeights
+            );
         }
     }
 
@@ -215,20 +250,12 @@ Foam::label Foam::kahipDecomp::decomposeSerial
     // Output: number of cut edges
     int edgeCut = 0;
 
-    // Addressing
-    ConstPrecisionAdaptor<int, label, List> xadj_param(xadj);
-    ConstPrecisionAdaptor<int, label, List> adjncy_param(adjncy);
-
-    // Output: cell -> processor addressing
-    decomp.resize(numCells);
-    PrecisionAdaptor<int, label, List> decomp_param(decomp, false);
-
 
 #if 0 // WIP: #ifdef KAFFPA_CPP_INTERFACE
     kaffpa_cpp
     (
         &numCells,          // num vertices in graph
-        (cellWeights.size() ? cellWeights.begin() : nullptr), // vertex wts
+        (cellWeights.empty() ? nullptr : cellWeights.data()), // vertex wts
         xadj_param.constCast().data(),          // indexing into adjncy
         nullptr,            // edge wts
         adjncy_param.constCast().data(),        // neighbour info
@@ -245,7 +272,7 @@ Foam::label Foam::kahipDecomp::decomposeSerial
     kaffpa
     (
         &numCells,          // num vertices in graph
-        (cellWeights.size() ? cellWeights.begin() : nullptr), // vertex wts
+        (cellWeights.empty() ? nullptr : cellWeights.data()), // vertex wts
         xadj_param.constCast().data(),          // indexing into adjncy
         nullptr,            // edge wts
         adjncy_param.constCast().data(),        // neighbour info
diff --git a/src/parallel/decompose/metisDecomp/Make/options b/src/parallel/decompose/metisDecomp/Make/options
index 013a158dc943ff058594d0762b25bb980215c0fd..a6c3421ba0100b5a9bcdc823f1d8b135a762bab6 100644
--- a/src/parallel/decompose/metisDecomp/Make/options
+++ b/src/parallel/decompose/metisDecomp/Make/options
@@ -3,5 +3,6 @@ EXE_INC = \
     -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude
 
 LIB_LIBS = \
-    -ldecompositionMethods \
-    -L$(METIS_LIB_DIR) -lmetis
+    -L$(FOAM_LIBBIN) -ldecompositionMethods \
+    -L$(METIS_LIB_DIR) \
+    -lmetis$(METIS_LIBNAME_SUFFIX)
diff --git a/src/parallel/decompose/metisDecomp/metisDecomp.C b/src/parallel/decompose/metisDecomp/metisDecomp.C
index bacb89ac0e6651665de57e48d53677f742388837..41fc7258c53674f922e5ebdf2ca743ab674cfe95 100644
--- a/src/parallel/decompose/metisDecomp/metisDecomp.C
+++ b/src/parallel/decompose/metisDecomp/metisDecomp.C
@@ -81,7 +81,7 @@ Foam::label Foam::metisDecomp::decomposeSerial
 
     const dictionary* coeffsDictPtr = decompDict_.findDict("metisCoeffs");
 
-    idx_t numCells = xadj.size()-1;
+    idx_t numCells = max(0, (xadj.size()-1));
 
     // Decomposition options
     List<idx_t> options(METIS_NOPTIONS);
@@ -89,7 +89,7 @@ Foam::label Foam::metisDecomp::decomposeSerial
 
     // Processor weights initialised with no size, only used if specified in
     // a file
-    Field<real_t> processorWeights;
+    Field<real_t> procWeights;
 
     // Cell weights (so on the vertices of the dual)
     List<idx_t> cellWeights;
@@ -164,18 +164,17 @@ Foam::label Foam::metisDecomp::decomposeSerial
                 << nl << endl;
         }
 
-        if (coeffDict.readIfPresent("processorWeights", processorWeights))
+        if (coeffDict.readIfPresent("processorWeights", procWeights))
         {
-            processorWeights /= sum(processorWeights);
-
-            if (processorWeights.size() != nDomains_)
+            if (procWeights.size() != nDomains_)
             {
-                FatalErrorInFunction
-                    << "Number of processor weights "
-                    << processorWeights.size()
-                    << " does not equal number of domains " << nDomains_
-                    << exit(FatalError);
+                FatalIOErrorInFunction(coeffDict)
+                    << "processorWeights (" << procWeights.size()
+                    << ") != number of domains (" << nDomains_ << ")" << nl
+                    << exit(FatalIOError);
             }
+
+            procWeights /= sum(procWeights);
         }
     }
 
@@ -190,6 +189,26 @@ Foam::label Foam::metisDecomp::decomposeSerial
     decomp.resize(numCells);
     PrecisionAdaptor<idx_t, label, List> decomp_param(decomp, false);
 
+    // Avoid potential nullptr issues with zero-sized arrays
+    labelList adjncy_dummy, xadj_dummy, decomp_dummy;
+    if (!numCells)
+    {
+        adjncy_dummy.resize(1, 0);
+        adjncy_param.set(adjncy_dummy);
+
+        xadj_dummy.resize(2, 0);
+        xadj_param.set(xadj_dummy);
+
+        decomp_dummy.resize(1, 0);
+        decomp_param.clear();  // Avoid propagating spurious values
+        decomp_param.set(decomp_dummy);
+    }
+
+
+    //
+    // Decompose
+    //
+
     // Output: number of cut edges
     idx_t edgeCut = 0;
 
@@ -205,7 +224,7 @@ Foam::label Foam::metisDecomp::decomposeSerial
             nullptr,                    // vsize: total communication vol
             faceWeights.data(),         // edge wts
             &nProcs,                    // nParts
-            processorWeights.data(),    // tpwgts
+            procWeights.data(),         // tpwgts
             nullptr,                    // ubvec: processor imbalance (default)
             options.data(),
             &edgeCut,
@@ -224,7 +243,7 @@ Foam::label Foam::metisDecomp::decomposeSerial
             nullptr,                    // vsize: total communication vol
             faceWeights.data(),         // edge wts
             &nProcs,                    // nParts
-            processorWeights.data(),    // tpwgts
+            procWeights.data(),         // tpwgts
             nullptr,                    // ubvec: processor imbalance (default)
             options.data(),
             &edgeCut,
diff --git a/src/parallel/decompose/ptscotchDecomp/Make/options b/src/parallel/decompose/ptscotchDecomp/Make/options
index 31071eb9dda1e1aec8c95db9bbfc45e3a4f6ab39..e74f3e797b985bceb0bd3d9fd5de1c09deda676d 100644
--- a/src/parallel/decompose/ptscotchDecomp/Make/options
+++ b/src/parallel/decompose/ptscotchDecomp/Make/options
@@ -18,8 +18,8 @@ LIB_LIBS = \
     -L$(FOAM_LIBBIN) -ldecompositionMethods \
     -L$(PTSCOTCH_LIB_DIR) \
     -L$(SCOTCH_LIB_DIR) \
-    -lscotch \
-    -lptscotch
+    -lscotch$(SCOTCH_LIBNAME_SUFFIX) \
+    -lptscotch$(SCOTCH_LIBNAME_SUFFIX)
 
 /* errexit, except for windows compile (already in library) */
 ifeq (,$(findstring windows,$(WM_OSTYPE)))
diff --git a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C
index b0f3f8dc4585639e415c588acfa1648cdab9dd5d..9f73443ff8e39d599c0fc53d45f167995512046f 100644
--- a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C
+++ b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C
@@ -28,10 +28,11 @@ License
 
 #include "ptscotchDecomp.H"
 #include "addToRunTimeSelectionTable.H"
+#include "floatScalar.H"
 #include "Time.H"
+#include "PrecisionAdaptor.H"
 #include "OFstream.H"
-#include "globalIndex.H"
-#include "SubField.H"
+#include <limits>
 
 // Avoid too many warnings from mpi.h
 #pragma GCC diagnostic ignored "-Wold-style-cast"
@@ -49,11 +50,11 @@ License
     #include <fenv.h>
 #endif
 
-// Provide a clear error message if we have a size mismatch
+// Error if we attempt narrowing
 static_assert
 (
-    sizeof(Foam::label) == sizeof(SCOTCH_Num),
-    "sizeof(Foam::label) == sizeof(SCOTCH_Num), check your scotch headers"
+    sizeof(Foam::label) <= sizeof(SCOTCH_Num),
+    "SCOTCH_Num is too small for Foam::label, check your scotch headers"
 );
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@@ -70,250 +71,73 @@ namespace Foam
 }
 
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
 
-void Foam::ptscotchDecomp::graphPath(const polyMesh& mesh) const
+namespace Foam
 {
-    graphPath_ = mesh.time().path()/mesh.name();
-}
 
-
-void Foam::ptscotchDecomp::check(const int retVal, const char* str)
+// Check and print error message
+static inline void check(const int retVal, const char* what)
 {
     if (retVal)
     {
         FatalErrorInFunction
-            << "Call to scotch routine " << str << " failed.\n"
+            << "Call to scotch routine " << what
+            << " failed (" << retVal << ")\n"
             << exit(FatalError);
     }
 }
 
+// The mesh-relative graph path/name (without extension)
+static inline Foam::fileName getGraphPathBase(const polyMesh& mesh)
+{
+    return mesh.time().path()/mesh.name();
+}
+
 
-////- Does prevention of 0 cell domains and calls ptscotch.
-//Foam::label Foam::ptscotchDecomp::decomposeZeroDomains
-//(
-//    const labelList& initadjncy,
-//    const labelList& initxadj,
-//    const List<scalar>& initcWeights,
-//    labelList& finalDecomp
-//) const
-//{
-//    globalIndex globalCells(initxadj.size()-1);
-//
-//    bool hasZeroDomain = false;
-//    for (const int proci : Pstream::allProcs())
-//    {
-//        if (globalCells.localSize(proci) == 0)
-//        {
-//            hasZeroDomain = true;
-//            break;
-//        }
-//    }
-//
-//    if (!hasZeroDomain)
-//    {
-//        return decompose
-//        (
-//            initadjncy,
-//            initxadj,
-//            initcWeights,
-//            finalDecomp
-//        );
-//    }
-//
-//
-//    if (debug)
-//    {
-//        Info<< "ptscotchDecomp : have graphs with locally 0 cells."
-//            << " trickling down." << endl;
-//    }
-//
-//    // Make sure every domain has at least one cell
-//    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//    // (scotch does not like zero sized domains)
-//    // Trickle cells from processors that have them up to those that
-//    // don't.
-//
-//
-//    // Number of cells to send to the next processor
-//    // (is same as number of cells next processor has to receive)
-//    List<label> nSendCells(Pstream::nProcs(), Zero);
-//
-//    for (label proci = nSendCells.size()-1; proci >=1; proci--)
-//    {
-//        label nLocalCells = globalCells.localSize(proci);
-//        if (nLocalCells-nSendCells[proci] < 1)
-//        {
-//            nSendCells[proci-1] = nSendCells[proci]-nLocalCells+1;
-//        }
-//    }
-//
-//    // First receive (so increasing the sizes of all arrays)
-//
-//    Field<int> xadj(initxadj);
-//    Field<int> adjncy(initadjncy);
-//    scalarField cWeights(initcWeights);
-//
-//    if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
-//    {
-//        // Receive cells from previous processor
-//        IPstream fromPrevProc(Pstream::commsTypes::blocking,
-//            Pstream::myProcNo()-1);
-//
-//        Field<int> prevXadj(fromPrevProc);
-//        Field<int> prevAdjncy(fromPrevProc);
-//        scalarField prevCellWeights(fromPrevProc);
-//
-//        if (prevXadj.size() != nSendCells[Pstream::myProcNo()-1])
-//        {
-//            FatalErrorInFunction
-//                << "Expected from processor " << Pstream::myProcNo()-1
-//                << " connectivity for " << nSendCells[Pstream::myProcNo()-1]
-//                << " nCells but only received " << prevXadj.size()
-//                << abort(FatalError);
-//        }
-//
-//        // Insert adjncy
-//        prepend(prevAdjncy, adjncy);
-//        // Adapt offsets and prepend xadj
-//        xadj += prevAdjncy.size();
-//        prepend(prevXadj, xadj);
-//        // Weights
-//        prepend(prevCellWeights, cWeights);
-//    }
-//
-//
-//    // Send to my next processor
-//
-//    if (nSendCells[Pstream::myProcNo()] > 0)
-//    {
-//        // Send cells to next processor
-//        OPstream toNextProc(Pstream::commsTypes::blocking,
-//            Pstream::myProcNo()+1);
-//
-//        label nCells = nSendCells[Pstream::myProcNo()];
-//        label startCell = xadj.size()-1 - nCells;
-//        label startFace = xadj[startCell];
-//        label nFaces = adjncy.size()-startFace;
-//
-//        // Send for all cell data: last nCells elements
-//        // Send for all face data: last nFaces elements
-//        toNextProc
-//            << Field<int>::subField(xadj, nCells, startCell)-startFace
-//            << Field<int>::subField(adjncy, nFaces, startFace)
-//            <<
-//            (
-//                cWeights.size()
-//              ? static_cast<const scalarField&>
-//                (
-//                    scalarField::subField(cWeights, nCells, startCell)
-//                )
-//              : scalarField(0)
-//            );
-//
-//        // Remove data that has been sent
-//        if (cWeights.size())
-//        {
-//            cWeights.setSize(cWeights.size()-nCells);
-//        }
-//        adjncy.setSize(adjncy.size()-nFaces);
-//        xadj.setSize(xadj.size() - nCells);
-//    }
-//
-//
-//    // Do decomposition as normal. Sets finalDecomp.
-//    label result = decompose(adjncy, xadj, cWeights, finalDecomp);
-//
-//
-//    if (debug)
-//    {
-//        Info<< "ptscotchDecomp : have graphs with locally 0 cells."
-//            << " trickling up." << endl;
-//    }
-//
-//
-//    // If we sent cells across make sure we undo it
-//    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-//    // Receive back from next processor if I sent something
-//    if (nSendCells[Pstream::myProcNo()] > 0)
-//    {
-//        IPstream fromNextProc(Pstream::commsTypes::blocking,
-//            Pstream::myProcNo()+1);
-//
-//        List<label> nextFinalDecomp(fromNextProc);
-//
-//        if (nextFinalDecomp.size() != nSendCells[Pstream::myProcNo()])
-//        {
-//            FatalErrorInFunction
-//                << "Expected from processor " << Pstream::myProcNo()+1
-//                << " decomposition for " << nSendCells[Pstream::myProcNo()]
-//                << " nCells but only received " << nextFinalDecomp.size()
-//                << abort(FatalError);
-//        }
-//
-//        append(nextFinalDecomp, finalDecomp);
-//    }
-//
-//    // Send back to previous processor.
-//    if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
-//    {
-//        OPstream toPrevProc(Pstream::commsTypes::blocking,
-//            Pstream::myProcNo()-1);
-//
-//        label nToPrevious = nSendCells[Pstream::myProcNo()-1];
-//
-//        toPrevProc <<
-//            SubList<label>
-//            (
-//                finalDecomp,
-//                nToPrevious,
-//                finalDecomp.size()-nToPrevious
-//            );
-//
-//        // Remove locally what has been sent
-//        finalDecomp.setSize(finalDecomp.size()-nToPrevious);
-//    }
-//    return result;
-//}
+} // End namespace Foam
 
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
 Foam::label Foam::ptscotchDecomp::decompose
 (
     const labelList& adjncy,
     const labelList& xadj,
     const List<scalar>& cWeights,
-    labelList& finalDecomp
+    labelList& decomp
 ) const
 {
-    List<label> dummyAdjncy;
-    List<label> dummyXadj;
+    const SCOTCH_Num numCells = max(0, (xadj.size()-1));
 
-    return decompose
-    (
-        adjncy.size(),
-        (adjncy.size() ? adjncy.begin() : dummyAdjncy.begin()),
-        xadj.size(),
-        (xadj.size() ? xadj.begin() : dummyXadj.begin()),
-        cWeights,
-        finalDecomp
-    );
-}
+    // Addressing
+    ConstPrecisionAdaptor<SCOTCH_Num, label, List> adjncy_param(adjncy);
+    ConstPrecisionAdaptor<SCOTCH_Num, label, List> xadj_param(xadj);
 
+    // Output: cell -> processor addressing
+    decomp.resize(numCells);
+    decomp = 0;
+    PrecisionAdaptor<SCOTCH_Num, label, List> decomp_param(decomp, false);
 
-Foam::label Foam::ptscotchDecomp::decompose
-(
-    const label adjncySize,
-    const label adjncy[],
-    const label xadjSize,
-    const label xadj[],
-    const List<scalar>& cWeights,
-    labelList& finalDecomp
-) const
-{
-    if (debug)
+    // Avoid potential nullptr issues with zero-sized arrays
+    labelList adjncy_dummy, xadj_dummy, decomp_dummy;
+    if (!numCells)
+    {
+        adjncy_dummy.resize(1, 0);
+        adjncy_param.set(adjncy_dummy);
+
+        xadj_dummy.resize(2, 0);
+        xadj_param.set(xadj_dummy);
+
+        decomp_dummy.resize(1, 0);
+        decomp_param.clear();  // Avoid propagating spurious values
+        decomp_param.set(decomp_dummy);
+    }
+
+
+    if (debug & 2)
     {
-        Pout<< "ptscotchDecomp : entering with xadj:" << xadjSize << endl;
+        Pout<< "ptscotchDecomp : " << numCells << " cells" << endl;
     }
 
     // Dump graph
@@ -327,36 +151,36 @@ Foam::label Foam::ptscotchDecomp::decompose
         Pout<< "Dumping Scotch graph file to " << str.name() << endl
             << "Use this in combination with dgpart." << endl;
 
-        globalIndex globalCells(xadjSize-1);
+        const label numConnect = adjncy.size();
+        const label nTotCells = returnReduce(numCells, sumOp<label>());
+        const label nTotConnect = returnReduce(numConnect, sumOp<label>());
+
+        // Version 2 = Distributed graph file (.dgrf)
+        str << "2" << nl;
 
-        // Distributed graph file (.grf)
-        const label version = 2;
-        str << version << nl;
-        // Number of files (procglbnbr)
-        str << Pstream::nProcs();
-        // My file number (procloc)
-        str << ' ' << Pstream::myProcNo() << nl;
+        // Number of files (procglbnbr), my file number (procloc)
+        str << Pstream::nProcs() << ' ' << Pstream::myProcNo() << nl;
 
-        // Total number of vertices (vertglbnbr)
-        str << globalCells.size();
+        // Total number of vertices (vertglbnbr),
         // Total number of connections (edgeglbnbr)
-        str << ' ' << returnReduce(xadj[xadjSize-1], sumOp<label>()) << nl;
-        // Local number of vertices (vertlocnbr)
-        str << xadjSize-1;
+        str << nTotCells << ' ' << nTotConnect << nl;
+
+        // Local number of vertices (vertlocnbr),
         // Local number of connections (edgelocnbr)
-        str << ' ' << xadj[xadjSize-1] << nl;
+        str << numCells << ' ' << numConnect << nl;
+
         // Numbering starts from 0
-        label baseval = 0;
-        // 100*hasVertlabels+10*hasEdgeWeights+1*hasVertWeighs
-        str << baseval << ' ' << "000" << nl;
-        for (label celli = 0; celli < xadjSize-1; celli++)
+        // 100*hasVertlabels+10*hasEdgeWeights+1*hasVertWeights
+        str << "0 000" << nl;
+
+        for (label celli = 0; celli < numCells; ++celli)
         {
-            const label start = xadj[celli];
+            const label beg = xadj[celli];
             const label end = xadj[celli+1];
 
-            str << end-start; // size
+            str << (end-beg);  // size
 
-            for (label i = start; i < end; i++)
+            for (label i = beg; i < end; ++i)
             {
                 str << ' ' << adjncy[i];
             }
@@ -373,110 +197,120 @@ Foam::label Foam::ptscotchDecomp::decompose
 
     // Default.
     SCOTCH_Strat stradat;
-    check(SCOTCH_stratInit(&stradat), "SCOTCH_stratInit");
+    check
+    (
+        SCOTCH_stratInit(&stradat),
+        "SCOTCH_stratInit"
+    );
 
     string strategy;
     if (coeffsDict_.readIfPresent("strategy", strategy))
     {
-        if (debug)
-        {
-            Info<< "ptscotchDecomp : Using strategy " << strategy << endl;
-        }
+        DebugInfo
+            << "ptscotchDecomp : Using strategy " << strategy << endl;
+
         SCOTCH_stratDgraphMap(&stradat, strategy.c_str());
         //fprintf(stdout, "S\tStrat=");
         //SCOTCH_stratSave(&stradat, stdout);
         //fprintf(stdout, "\n");
     }
 
+
     // Graph
     // ~~~~~
 
-    List<label> velotab;
-
-
     // Check for externally provided cellweights and if so initialise weights
 
-    const scalar minWeights = gMin(cWeights);
-    const scalar maxWeights = gMax(cWeights);
+    bool hasWeights = returnReduce(!cWeights.empty(), orOp<bool>());
 
-    if (maxWeights > minWeights)
-    {
-        if (minWeights <= 0)
-        {
-            WarningInFunction
-                << "Illegal minimum weight " << minWeights
-                << endl;
-        }
+    const scalar minWeights = hasWeights ? gMin(cWeights) : scalar(1);
 
-        if (cWeights.size() != xadjSize-1)
-        {
-            FatalErrorInFunction
-                << "Number of cell weights " << cWeights.size()
-                << " does not equal number of cells " << xadjSize-1
-                << exit(FatalError);
-        }
+    if (minWeights <= 0)
+    {
+        hasWeights = false;
+        WarningInFunction
+            << "Illegal minimum weight " << minWeights
+            << " ... ignoring"
+            << endl;
+    }
+    else if (hasWeights && (cWeights.size() != numCells))
+    {
+        FatalErrorInFunction
+            << "Number of cell weights " << cWeights.size()
+            << " does not equal number of cells " << numCells
+            << exit(FatalError);
     }
 
-    scalar velotabSum = gSum(cWeights)/minWeights;
 
-    scalar rangeScale(1.0);
+    List<SCOTCH_Num> velotab;
 
-    if (Pstream::master())
+    if (hasWeights)
     {
-        if (velotabSum > scalar(labelMax - 1))
+        scalar rangeScale(1);
+
+        const scalar velotabSum = gSum(cWeights)/minWeights;
+
+        const scalar upperRange = static_cast<scalar>
+        (
+            std::numeric_limits<SCOTCH_Num>::max()-1
+        );
+
+        if (velotabSum > upperRange)
         {
             // 0.9 factor of safety to avoid floating point round-off in
             // rangeScale tipping the subsequent sum over the integer limit.
-            rangeScale = 0.9*scalar(labelMax - 1)/velotabSum;
+            rangeScale = 0.9*upperRange/velotabSum;
 
             WarningInFunction
-                << "Sum of weights has overflowed integer: " << velotabSum
-                << ", compressing weight scale by a factor of " << rangeScale
-                << endl;
+                << "Sum of weights overflows SCOTCH_Num: " << velotabSum
+                << ", compressing by factor " << rangeScale << endl;
         }
-    }
 
-    Pstream::scatter(rangeScale);
-
-    if (maxWeights > minWeights)
-    {
         if (cWeights.size())
         {
             // Convert to integers.
-            velotab.setSize(cWeights.size());
+            velotab.resize(cWeights.size());
 
             forAll(velotab, i)
             {
-                velotab[i] = int((cWeights[i]/minWeights - 1)*rangeScale) + 1;
+                velotab[i] = static_cast<SCOTCH_Num>
+                (
+                    ((cWeights[i]/minWeights - 1)*rangeScale) + 1
+                );
             }
         }
         else
         {
-            // Locally zero cells but not globally. Make sure we have
-            // some size so .begin() does not return null pointer. Data
-            // itself is never used.
-            velotab.setSize(1);
-            velotab[0] = 1;
+            // Locally zero cells but not globally.
+            // Provide some size to avoid null pointer.
+            velotab.resize(1, 1);
         }
     }
 
 
-    if (debug)
+    //
+    // Decomposition graph
+    //
+
+    if (debug & 2)
     {
         Pout<< "SCOTCH_dgraphInit" << endl;
     }
     SCOTCH_Dgraph grafdat;
-    check(SCOTCH_dgraphInit(&grafdat, MPI_COMM_WORLD), "SCOTCH_dgraphInit");
-
+    check
+    (
+        SCOTCH_dgraphInit(&grafdat, MPI_COMM_WORLD),
+        "SCOTCH_dgraphInit"
+    );
 
-    if (debug)
+    if (debug & 2)
     {
         Pout<< "SCOTCH_dgraphBuild with:" << nl
-            << "xadjSize-1      : " << xadjSize-1 << nl
-            << "xadj            : " << name(xadj) << nl
-            << "velotab         : " << name(velotab.begin()) << nl
-            << "adjncySize      : " << adjncySize << nl
-            << "adjncy          : " << name(adjncy) << nl
+            << "numCells        : " << numCells << nl
+            << "xadj            : " << name(xadj_param().cdata()) << nl
+            << "velotab         : " << name(velotab.cdata()) << nl
+            << "adjncySize      : " << adjncy_param().size() << nl
+            << "adjncy          : " << name(adjncy_param().cdata()) << nl
             << endl;
     }
 
@@ -484,80 +318,84 @@ Foam::label Foam::ptscotchDecomp::decompose
     (
         SCOTCH_dgraphBuild
         (
-            &grafdat,               // grafdat
-            0,                      // baseval, c-style numbering
-            xadjSize-1,             // vertlocnbr, nCells
-            xadjSize-1,             // vertlocmax
-            const_cast<SCOTCH_Num*>(xadj),
+            &grafdat,               // Graph to build
+            0,                      // Base for indexing (C-style)
+
+            numCells,               // vertlocnbr [== nCells]
+            numCells,               // vertlocmax
+
+            xadj_param.constCast().data(),
                                     // vertloctab, start index per cell into
                                     // adjncy
-            const_cast<SCOTCH_Num*>(xadj+1),// vendloctab, end index  ,,
+            (xadj_param.constCast().data()+1),
+                                    // vendloctab, end index  ,,
 
-            const_cast<SCOTCH_Num*>(velotab.begin()),// veloloctab, vtx weights
-            nullptr,                   // vlblloctab
+            velotab.data(),         // veloloctab, vtx weights
+            nullptr,                // vlblloctab
 
-            adjncySize,             // edgelocnbr, number of arcs
-            adjncySize,             // edgelocsiz
-            const_cast<SCOTCH_Num*>(adjncy),         // edgeloctab
-            nullptr,                   // edgegsttab
-            nullptr                    // edlotab, edge weights
+            adjncy.size(),          // edgelocnbr, number of arcs
+            adjncy.size(),          // edgelocsiz
+            adjncy_param.constCast().data(), // edgeloctab
+            nullptr,                // edgegsttab
+            nullptr                 // edlotab, edge weights
         ),
         "SCOTCH_dgraphBuild"
     );
 
-
-    if (debug)
+    if (debug & 2)
     {
         Pout<< "SCOTCH_dgraphCheck" << endl;
     }
-    check(SCOTCH_dgraphCheck(&grafdat), "SCOTCH_dgraphCheck");
+    check
+    (
+        SCOTCH_dgraphCheck(&grafdat),
+        "SCOTCH_dgraphCheck"
+    );
 
 
     // Architecture
     // ~~~~~~~~~~~~
     // (fully connected network topology since using switch)
 
-    if (debug)
+    if (debug & 2)
     {
         Pout<< "SCOTCH_archInit" << endl;
     }
     SCOTCH_Arch archdat;
-    check(SCOTCH_archInit(&archdat), "SCOTCH_archInit");
+    check
+    (
+        SCOTCH_archInit(&archdat),
+        "SCOTCH_archInit"
+    );
 
-    List<label> processorWeights;
+    List<SCOTCH_Num> procWeights;
     if
     (
-        coeffsDict_.readIfPresent("processorWeights", processorWeights)
-     && processorWeights.size()
+        coeffsDict_.readIfPresent("processorWeights", procWeights)
+     && !procWeights.empty()
     )
     {
-        if (debug)
-        {
-            Info<< "ptscotchDecomp : Using procesor weights "
-                << processorWeights
-                << endl;
-        }
-
-        if (processorWeights.size() != nDomains_)
+        if (procWeights.size() != nDomains_)
         {
             FatalIOErrorInFunction(coeffsDict_)
-                << "processorWeights not the same size"
-                << " as the wanted number of domains " << nDomains_
+                << "processorWeights (" << procWeights.size()
+                << ") != number of domains (" << nDomains_ << ")" << nl
                 << exit(FatalIOError);
         }
 
+        DebugInfo
+            << "ptscotchDecomp : Using procesor weights "
+            << procWeights << endl;
+
         check
         (
-            SCOTCH_archCmpltw
-            (
-                &archdat, nDomains_, processorWeights.begin()
-            ),
+            SCOTCH_archCmpltw(&archdat, nDomains_, procWeights.cdata()),
             "SCOTCH_archCmpltw"
         );
     }
     else
     {
-        if (debug)
+        if (debug & 2)
         {
             Pout<< "SCOTCH_archCmplt" << endl;
         }
@@ -579,12 +417,7 @@ Foam::label Foam::ptscotchDecomp::decompose
     );
     #endif
 
-
-    // Note: always provide allocated storage even if local size 0
-    finalDecomp.setSize(max(1, xadjSize-1));
-    finalDecomp = 0;
-
-    if (debug)
+    if (debug & 2)
     {
         Pout<< "SCOTCH_dgraphMap" << endl;
     }
@@ -595,7 +428,7 @@ Foam::label Foam::ptscotchDecomp::decompose
             &grafdat,
             &archdat,
             &stradat,           // const SCOTCH_Strat *
-            finalDecomp.begin() // parttab
+            decomp_param.ref().data() // parttab
         ),
         "SCOTCH_graphMap"
     );
@@ -604,9 +437,6 @@ Foam::label Foam::ptscotchDecomp::decompose
     feenableexcept(oldExcepts);
     #endif
 
-    // See above note to have size 1. Undo.
-    finalDecomp.setSize(xadjSize-1);
-
     //check
     //(
     //    SCOTCH_dgraphPart
@@ -614,21 +444,19 @@ Foam::label Foam::ptscotchDecomp::decompose
     //        &grafdat,
     //        nDomains_,          // partnbr
     //        &stradat,           // const SCOTCH_Strat *
-    //        finalDecomp.begin() // parttab
+    //        decomp_param.ref().data() // parttab
     //    ),
     //    "SCOTCH_graphPart"
     //);
 
-    if (debug)
+    if (debug & 2)
     {
         Pout<< "SCOTCH_dgraphExit" << endl;
     }
-    // Release storage for graph
-    SCOTCH_dgraphExit(&grafdat);
-    // Release storage for strategy
-    SCOTCH_stratExit(&stradat);
-    // Release storage for network topology
-    SCOTCH_archExit(&archdat);
+
+    SCOTCH_dgraphExit(&grafdat);    // Release storage for graph
+    SCOTCH_stratExit(&stradat);     // Release storage for strategy
+    SCOTCH_archExit(&archdat);      // Release storage for network topology
 
     return 0;
 }
@@ -657,7 +485,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose
 ) const
 {
     // Where to write graph
-    graphPath(mesh);
+    graphPath_ = getGraphPathBase(mesh);
 
     if (points.size() != mesh.nCells())
     {
@@ -707,7 +535,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose
 ) const
 {
     // Where to write graph
-    graphPath(mesh);
+    graphPath_ = getGraphPathBase(mesh);
 
     if (agglom.size() != mesh.nCells())
     {
diff --git a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.H b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.H
index 26e3d84c36b8db118d2c64c45cc4e643a587798e..6467fd86e06f1388c2a4d5766fd07cc31862dfe6 100644
--- a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.H
+++ b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.H
@@ -81,33 +81,15 @@ class ptscotchDecomp
 
     // Private Member Functions
 
-        //- Set graph path and name (mutable)
-        void graphPath(const polyMesh& mesh) const;
-
-        //- Check and print error message
-        static void check(const int, const char*);
-
         //- Decompose. Handles size 0 arrays
         label decompose
         (
             const labelList& adjncy,
             const labelList& xadj,
             const List<scalar>& cWeights,
-            labelList& finalDecomp
-        ) const;
-
-        //- Low level decompose
-        label decompose
-        (
-            const label adjncySize,
-            const label adjncy[],
-            const label xadjSize,
-            const label xadj[],
-            const List<scalar>& cWeights,
-            labelList& finalDecomp
+            labelList& decomp
         ) const;
 
-
         //- No copy construct
         ptscotchDecomp(const ptscotchDecomp&) = delete;
 
diff --git a/src/parallel/decompose/scotchDecomp/Make/options b/src/parallel/decompose/scotchDecomp/Make/options
index 67239cf898929ad150b6c2d035715b51f220c60a..ba446efa71e8bc7f2657ffce2c3ac73b2216ffa1 100644
--- a/src/parallel/decompose/scotchDecomp/Make/options
+++ b/src/parallel/decompose/scotchDecomp/Make/options
@@ -3,9 +3,9 @@ EXE_INC = \
     -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude
 
 LIB_LIBS = \
-    -ldecompositionMethods \
+    -L$(FOAM_LIBBIN) -ldecompositionMethods \
     -L$(SCOTCH_LIB_DIR) \
-    -lscotch
+    -lscotch$(SCOTCH_LIBNAME_SUFFIX)
 
 /* errexit, except for windows compile (already in library) */
 ifeq (,$(findstring windows,$(WM_OSTYPE)))
diff --git a/src/parallel/decompose/scotchDecomp/scotchDecomp.C b/src/parallel/decompose/scotchDecomp/scotchDecomp.C
index 034b82ba029dfcf9bda534320a6d2458c9afd815..514542e6b32999d8948d0e471452d934bdf02e17 100644
--- a/src/parallel/decompose/scotchDecomp/scotchDecomp.C
+++ b/src/parallel/decompose/scotchDecomp/scotchDecomp.C
@@ -30,7 +30,9 @@ License
 #include "addToRunTimeSelectionTable.H"
 #include "floatScalar.H"
 #include "Time.H"
+#include "PrecisionAdaptor.H"
 #include "OFstream.H"
+#include <limits>
 
 // Probably not needed, but in case we pickup a ptscotch.h ...
 #define MPICH_SKIP_MPICXX
@@ -47,14 +49,13 @@ License
     #include <fenv.h>
 #endif
 
-// Provide a clear error message if we have a size mismatch
+// Error if we attempt narrowing
 static_assert
 (
-    sizeof(Foam::label) == sizeof(SCOTCH_Num),
-    "sizeof(Foam::label) == sizeof(SCOTCH_Num), check your scotch headers"
+    sizeof(Foam::label) <= sizeof(SCOTCH_Num),
+    "SCOTCH_Num is too small for Foam::label, check your scotch headers"
 );
 
-
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 namespace Foam
@@ -69,25 +70,34 @@ namespace Foam
 }
 
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
 
-void Foam::scotchDecomp::graphPath(const polyMesh& mesh) const
+namespace Foam
 {
-    graphPath_ = mesh.time().path()/mesh.name() + ".grf";
-}
 
-
-void Foam::scotchDecomp::check(const int retVal, const char* str)
+// Check and print error message
+static inline void check(const int retVal, const char* what)
 {
     if (retVal)
     {
         FatalErrorInFunction
-            << "Call to scotch routine " << str << " failed.\n"
+            << "Call to scotch routine " << what
+            << " failed (" << retVal << ")\n"
             << exit(FatalError);
     }
 }
 
 
+// The mesh-relative graph path/name (without extension)
+static inline Foam::fileName getGraphPathBase(const polyMesh& mesh)
+{
+    return mesh.time().path()/mesh.name();
+}
+
+
+} // End namespace Foam
+
+
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
 Foam::label Foam::scotchDecomp::decomposeSerial
@@ -98,36 +108,62 @@ Foam::label Foam::scotchDecomp::decomposeSerial
     labelList& decomp
 ) const
 {
+    const SCOTCH_Num numCells = max(0, (xadj.size()-1));
+
+    // Addressing
+    ConstPrecisionAdaptor<SCOTCH_Num, label, List> adjncy_param(adjncy);
+    ConstPrecisionAdaptor<SCOTCH_Num, label, List> xadj_param(xadj);
+
+    // Output: cell -> processor addressing
+    decomp.resize(numCells);
+    decomp = 0;
+    PrecisionAdaptor<SCOTCH_Num, label, List> decomp_param(decomp, false);
+
+    // Avoid potential nullptr issues with zero-sized arrays
+    labelList adjncy_dummy, xadj_dummy, decomp_dummy;
+    if (!numCells)
+    {
+        adjncy_dummy.resize(1, 0);
+        adjncy_param.set(adjncy_dummy);
+
+        xadj_dummy.resize(2, 0);
+        xadj_param.set(xadj_dummy);
+
+        decomp_dummy.resize(1, 0);
+        decomp_param.clear();  // Avoid propagating spurious values
+        decomp_param.set(decomp_dummy);
+    }
+
+
     // Dump graph
     if (coeffsDict_.getOrDefault("writeGraph", false))
     {
-        OFstream str(graphPath_);
+        OFstream str(graphPath_ + ".grf");
 
         Info<< "Dumping Scotch graph file to " << str.name() << nl
             << "Use this in combination with gpart." << endl;
 
-        const label version = 0;
-        str << version << nl;
-        // Number of vertices
-        str << xadj.size()-1 << ' ' << adjncy.size() << nl;
+        const label numConnect = adjncy.size();
 
-        // Numbering starts from 0
-        const label baseval = 0;
+        // Version 0 = Graph file (.grf)
+        str << "0" << nl;
 
-        // Has weights?
-        const label hasEdgeWeights = 0;
-        const label hasVertexWeights = 0;
-        const label numericflag = 10*hasEdgeWeights+hasVertexWeights;
-        str << baseval << ' ' << numericflag << nl;
+        // Number of vertices,
+        // number of edges (connections)
+        str << numCells << ' ' << numConnect << nl;
+
+        // Numbering starts from 0
+        // 100*hasVertlabels+10*hasEdgeWeights+1*hasVertWeights
+        str << "0 000" << nl;
 
-        for (label celli = 1; celli < xadj.size(); ++celli)
+        for (label celli = 0; celli < numCells; ++celli)
         {
-            const label start = xadj[celli-1];
-            const label end = xadj[celli];
+            const label beg = xadj[celli];
+            const label end = xadj[celli+1];
 
-            str << end-start; // size
+            str << (end-beg);  // size
 
-            for (label i = start; i < end; ++i)
+            for (label i = beg; i < end; ++i)
             {
                 str << ' ' << adjncy[i];
             }
@@ -135,6 +171,7 @@ Foam::label Foam::scotchDecomp::decomposeSerial
         }
     }
 
+
     // Make repeatable
     SCOTCH_randomReset();
 
@@ -143,15 +180,17 @@ Foam::label Foam::scotchDecomp::decomposeSerial
 
     // Default.
     SCOTCH_Strat stradat;
-    check(SCOTCH_stratInit(&stradat), "SCOTCH_stratInit");
+    check
+    (
+        SCOTCH_stratInit(&stradat),
+        "SCOTCH_stratInit"
+    );
 
     string strategy;
     if (coeffsDict_.readIfPresent("strategy", strategy))
     {
-        if (debug)
-        {
-            Info<< "scotchDecomp : Using strategy " << strategy << endl;
-        }
+        DebugInfo << "scotchDecomp : Using strategy " << strategy << endl;
+
         SCOTCH_stratGraphMap(&stradat, strategy.c_str());
         //fprintf(stdout, "S\tStrat=");
         //SCOTCH_stratSave(&stradat, stdout);
@@ -162,74 +201,104 @@ Foam::label Foam::scotchDecomp::decomposeSerial
     // Graph
     // ~~~~~
 
-    labelList velotab;
-
     // Check for externally provided cellweights and if so initialise weights
+
+    bool hasWeights = !cWeights.empty();
+
     // Note: min, not gMin since routine runs on master only.
-    const scalar minWeights = min(cWeights);
-    if (!cWeights.empty())
+    const scalar minWeights = hasWeights ? min(cWeights) : scalar(1);
+
+    if (minWeights <= 0)
     {
-        if (minWeights <= 0)
-        {
-            WarningInFunction
-                << "Illegal minimum weight " << minWeights
-                << endl;
-        }
+        hasWeights = false;
+        WarningInFunction
+            << "Illegal minimum weight " << minWeights
+            << " ... ignoring"
+            << endl;
+    }
+    else if (hasWeights && (cWeights.size() != numCells))
+    {
+        FatalErrorInFunction
+            << "Number of cell weights " << cWeights.size()
+            << " does not equal number of cells " << numCells
+            << exit(FatalError);
+    }
 
-        if (cWeights.size() != xadj.size()-1)
-        {
-            FatalErrorInFunction
-                << "Number of cell weights " << cWeights.size()
-                << " does not equal number of cells " << xadj.size()-1
-                << exit(FatalError);
-        }
 
-        scalar velotabSum = sum(cWeights)/minWeights;
+    List<SCOTCH_Num> velotab;
+
+    if (hasWeights)
+    {
+        scalar rangeScale(1);
 
-        scalar rangeScale(1.0);
+        const scalar velotabSum = sum(cWeights)/minWeights;
 
-        if (velotabSum > scalar(labelMax - 1))
+        const scalar upperRange = static_cast<scalar>
+        (
+            std::numeric_limits<SCOTCH_Num>::max()-1
+        );
+
+        if (velotabSum > upperRange)
         {
             // 0.9 factor of safety to avoid floating point round-off in
             // rangeScale tipping the subsequent sum over the integer limit.
-            rangeScale = 0.9*scalar(labelMax - 1)/velotabSum;
+            rangeScale = 0.9*upperRange/velotabSum;
 
             WarningInFunction
-                << "Sum of weights has overflowed integer: " << velotabSum
-                << ", compressing weight scale by a factor of " << rangeScale
-                << endl;
+                << "Sum of weights overflows SCOTCH_Num: " << velotabSum
+                << ", compressing by factor " << rangeScale << endl;
         }
 
-        // Convert to integers.
-        velotab.setSize(cWeights.size());
-
-        forAll(velotab, i)
         {
-            velotab[i] = int((cWeights[i]/minWeights - 1)*rangeScale) + 1;
+            // Convert to integers.
+            velotab.resize(cWeights.size());
+
+            forAll(velotab, i)
+            {
+                velotab[i] = static_cast<SCOTCH_Num>
+                (
+                    ((cWeights[i]/minWeights - 1)*rangeScale) + 1
+                );
+            }
         }
     }
 
 
+    //
+    // Decomposition graph
+    //
+
     SCOTCH_Graph grafdat;
-    check(SCOTCH_graphInit(&grafdat), "SCOTCH_graphInit");
+    check
+    (
+        SCOTCH_graphInit(&grafdat),
+        "SCOTCH_graphInit"
+    );
     check
     (
         SCOTCH_graphBuild
         (
-            &grafdat,
-            0,                      // baseval, c-style numbering
-            xadj.size()-1,          // vertnbr, nCells
-            xadj.begin(),           // verttab, start index per cell into adjncy
-            &xadj[1],               // vendtab, end index  ,,
-            velotab.begin(),        // velotab, vertex weights
-            nullptr,                   // vlbltab
-            adjncy.size(),          // edgenbr, number of arcs
-            adjncy.begin(),         // edgetab
-            nullptr                    // edlotab, edge weights
+            &grafdat,               // Graph to build
+            0,                      // Base for indexing (C-style)
+
+            numCells,               // Number of vertices [== nCells]
+            xadj_param().cdata(),   // verttab, start index per cell into adjncy
+            nullptr,                // vendtab, end index (nullptr == automatic)
+
+            velotab.cdata(),        // velotab, vertex weights
+            nullptr,                // Vertex labels (nullptr == ignore)
+
+            adjncy.size(),          // Number of graph edges
+            adjncy_param().cdata(), // Edge array
+            nullptr                 // Edge weights (nullptr == ignore)
         ),
         "SCOTCH_graphBuild"
     );
-    check(SCOTCH_graphCheck(&grafdat), "SCOTCH_graphCheck");
+    check
+    (
+        SCOTCH_graphCheck(&grafdat),
+        "SCOTCH_graphCheck"
+    );
 
 
     // Architecture
@@ -237,34 +306,34 @@ Foam::label Foam::scotchDecomp::decomposeSerial
     // (fully connected network topology since using switch)
 
     SCOTCH_Arch archdat;
-    check(SCOTCH_archInit(&archdat), "SCOTCH_archInit");
+    check
+    (
+        SCOTCH_archInit(&archdat),
+        "SCOTCH_archInit"
+    );
 
-    labelList processorWeights;
+    List<SCOTCH_Num> procWeights;
     if
     (
-        coeffsDict_.readIfPresent("processorWeights", processorWeights)
-     && processorWeights.size()
+        coeffsDict_.readIfPresent("processorWeights", procWeights)
+     && !procWeights.empty()
     )
     {
-        if (debug)
-        {
-            Info<< "scotchDecomp : Using procesor weights " << processorWeights
-                << endl;
-        }
-        if (processorWeights.size() != nDomains_)
+        if (procWeights.size() != nDomains_)
         {
             FatalIOErrorInFunction(coeffsDict_)
-                << "processorWeights not the same size"
-                << " as the wanted number of domains " << nDomains_
+                << "processorWeights (" << procWeights.size()
+                << ") != number of domains (" << nDomains_ << ")" << nl
                 << exit(FatalIOError);
         }
 
+        DebugInfo
+            << "scotchDecomp : Using procesor weights "
+            << procWeights << endl;
+
         check
         (
-            SCOTCH_archCmpltw
-            (
-                &archdat, nDomains_, processorWeights.begin()
-            ),
+            SCOTCH_archCmpltw(&archdat, nDomains_, procWeights.cdata()),
             "SCOTCH_archCmpltw"
         );
     }
@@ -328,16 +397,14 @@ Foam::label Foam::scotchDecomp::decomposeSerial
     );
     #endif
 
-    decomp.setSize(xadj.size()-1);
-    decomp = 0;
     check
     (
         SCOTCH_graphMap
         (
             &grafdat,
             &archdat,
-            &stradat,       // const SCOTCH_Strat *
-            decomp.begin()  // parttab
+            &stradat,           // const SCOTCH_Strat *
+            decomp_param.ref().data() // parttab
         ),
         "SCOTCH_graphMap"
     );
@@ -346,25 +413,22 @@ Foam::label Foam::scotchDecomp::decomposeSerial
     feenableexcept(oldExcepts);
     #endif
 
-    //decomp.setSize(xadj.size()-1);
+    //decomp.resize(numCells);
     //check
     //(
     //    SCOTCH_graphPart
     //    (
     //        &grafdat,
-    //        nDomains_,      // partnbr
-    //        &stradat,       // const SCOTCH_Strat *
-    //        decomp.begin()  // parttab
+    //        nDomains_,           // partnbr
+    //        &stradat,            // const SCOTCH_Strat *
+    //        decomp_param.ref().data()  // parttab
     //    ),
     //    "SCOTCH_graphPart"
     //);
 
-    // Release storage for graph
-    SCOTCH_graphExit(&grafdat);
-    // Release storage for strategy
-    SCOTCH_stratExit(&stradat);
-    // Release storage for network topology
-    SCOTCH_archExit(&archdat);
+    SCOTCH_graphExit(&grafdat);     // Release storage for graph
+    SCOTCH_stratExit(&stradat);     // Release storage for strategy
+    SCOTCH_archExit(&archdat);      // Release storage for network topology
 
     return 0;
 }
@@ -392,7 +456,7 @@ Foam::labelList Foam::scotchDecomp::decompose
 ) const
 {
     // Where to write graph
-    graphPath(mesh);
+    graphPath_ = getGraphPathBase(mesh);
 
     return metisLikeDecomp::decompose
     (
@@ -412,7 +476,7 @@ Foam::labelList Foam::scotchDecomp::decompose
 ) const
 {
     // Where to write graph
-    graphPath(mesh);
+    graphPath_ = getGraphPathBase(mesh);
 
     return metisLikeDecomp::decompose
     (
diff --git a/src/parallel/decompose/scotchDecomp/scotchDecomp.H b/src/parallel/decompose/scotchDecomp/scotchDecomp.H
index 6b61c5a66a2eb4becdc7ea92ff63081297e1ee91..051a8ecf995b29cebfc730121387b1f6d6db3262 100644
--- a/src/parallel/decompose/scotchDecomp/scotchDecomp.H
+++ b/src/parallel/decompose/scotchDecomp/scotchDecomp.H
@@ -238,15 +238,6 @@ class scotchDecomp
         mutable fileName graphPath_;
 
 
-    // Private Member Functions
-
-        //- Set graph path and name (mutable)
-        void graphPath(const polyMesh& mesh) const;
-
-        //- Check and print error message
-        static void check(const int, const char*);
-
-
 protected:
 
     // Protected Member Functions
diff --git a/wmake/scripts/have_kahip b/wmake/scripts/have_kahip
index 04ccc8643e19361c3c97a1787a9f4e2c9f3a7660..540540b55e231a8924a82cc7002088bf1a985e9d 100644
--- a/wmake/scripts/have_kahip
+++ b/wmake/scripts/have_kahip
@@ -5,7 +5,7 @@
 #   \\  /    A nd           | www.openfoam.com
 #    \\/     M anipulation  |
 #------------------------------------------------------------------------------
-#     Copyright (C) 2018-2020 OpenCFD Ltd.
+#     Copyright (C) 2018-2021 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
 #     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@@ -27,6 +27,7 @@
 #     KAHIP_ARCH_PATH
 #     KAHIP_INC_DIR
 #     KAHIP_LIB_DIR
+#     KAHIP_LIBNAME_SUFFIX [optional]
 #
 #------------------------------------------------------------------------------
 . ${WM_PROJECT_DIR:?}/wmake/scripts/sysFunctions    # General system functions
@@ -37,7 +38,7 @@
 no_kahip()
 {
     unset HAVE_KAHIP KAHIP_ARCH_PATH KAHIP_INC_DIR KAHIP_LIB_DIR
-    unset KAHIP_VERSION
+    unset KAHIP_VERSION KAHIP_LIBNAME_SUFFIX
 }
 
 
@@ -48,6 +49,10 @@ echo_kahip()
     echo "root=\"$KAHIP_ARCH_PATH\""
     echo "include=\"$KAHIP_INC_DIR\""
     echo "library=\"$KAHIP_LIB_DIR\""
+    if [ -n "$KAHIP_LIBNAME_SUFFIX" ]
+    then
+        echo "libsuffix=\"$KAHIP_LIBNAME_SUFFIX\""
+    fi
 }
 
 
@@ -100,9 +105,9 @@ search_kahip()
     # ----------------------------------
 
     # kahip itself is 32-bit int, but our interface handles some
-    # 64-bit conversion (mesh size).
+    # 64-bit conversion.
 
-    echo "kahip (label=32) - $prefix"
+    echo "kahip (int32) - $prefix"
     export HAVE_KAHIP=true
     export KAHIP_ARCH_PATH="$prefix"
     export KAHIP_INC_DIR="${header%/*}"     # Basename
@@ -153,8 +158,10 @@ no_kahip
 
 # Test/query
 case "$1" in
--test)
+-test | -debug-test)
+    [ "$1" = "-debug-test" ] && set -x
     have_kahip
+    [ "$1" = "-debug-test" ] && set +x
     echo_kahip
     ;;
 -query)
diff --git a/wmake/scripts/have_metis b/wmake/scripts/have_metis
index 7b545d9064f6d9beaf3ee2891cb91b3246893178..1b6eb54f3a063d80ee1f242da6b81033c933d832 100644
--- a/wmake/scripts/have_metis
+++ b/wmake/scripts/have_metis
@@ -5,7 +5,7 @@
 #   \\  /    A nd           | www.openfoam.com
 #    \\/     M anipulation  |
 #------------------------------------------------------------------------------
-#     Copyright (C) 2018-2020 OpenCFD Ltd.
+#     Copyright (C) 2018-2021 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
 #     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@@ -27,6 +27,7 @@
 #     METIS_ARCH_PATH
 #     METIS_INC_DIR
 #     METIS_LIB_DIR
+#     METIS_LIBNAME_SUFFIX [optional]
 #
 #------------------------------------------------------------------------------
 . ${WM_PROJECT_DIR:?}/wmake/scripts/sysFunctions    # General system functions
@@ -37,7 +38,7 @@
 no_metis()
 {
     unset HAVE_METIS METIS_ARCH_PATH METIS_INC_DIR METIS_LIB_DIR
-    unset METIS_VERSION
+    unset METIS_VERSION METIS_LIBNAME_SUFFIX
 }
 
 
@@ -48,6 +49,10 @@ echo_metis()
     echo "root=\"$METIS_ARCH_PATH\""
     echo "include=\"$METIS_INC_DIR\""
     echo "library=\"$METIS_LIB_DIR\""
+    if [ -n "$METIS_LIBNAME_SUFFIX" ]
+    then
+        echo "libsuffix=\"$METIS_LIBNAME_SUFFIX\""
+    fi
 }
 
 
@@ -73,7 +78,7 @@ search_metis()
     elif hasAbsdir "$prefix"
     then
         header=$(findFirstFile "$prefix/include/$incName")
-        library=$(findExtLib "$libName")
+        library="-extlib"  # Delay search...
     elif isSystem "$prefix"
     then
         header=$(findSystemInclude -name="$incName")
@@ -89,6 +94,27 @@ search_metis()
         return 2
     }
 
+    # ----------------------------------
+    # Extract IDXTYPEWIDTH from metis.h: regex as per ThirdParty makeMETIS
+    # - ensure consistent size between OpenFOAM and metis header
+
+    local label
+    if [ -f "$header" ]
+    then
+        label=$(sed -ne \
+            's/^.*#define  *IDXTYPEWIDTH  *\([1-9][0-9]\).*/\1/p' \
+            "$header")
+    fi
+    : "${label:=unknown}"  # Safety
+
+    # Transform (32 | 64) -> (int32 | int64)
+    case "$label" in (32|64) label="int${label}" ;; esac
+
+    if [ "$library" = "-extlib" ]
+    then
+        library=$(findExtLib "${libName}-${label}" "$libName")
+    fi
+
     # Library
     [ -n "$library" ] \
     || library=$(findLibrary -prefix="$prefix" -name="$libName") \
@@ -97,23 +123,21 @@ search_metis()
         return 2
     }
 
-    # ----------------------------------
-
-    local label
-
-    # Ensure consistent sizes between OpenFOAM and metis header
-    # Extract IDXTYPEWIDTH from metis.h: regex as per ThirdParty Allwmake
-    label=$(sed -ne \
-        's/^.*#define  *IDXTYPEWIDTH  *\([1-9][0-9]\).*/\1/p' \
-        "$header")
-    : "${label:=unknown}"
+    # Library name suffix (-int32 | -int64)
+    case "${library##*/}" in
+    (*-int32.*) export METIS_LIBNAME_SUFFIX="-int32" ;;
+    (*-int64.*) export METIS_LIBNAME_SUFFIX="-int64" ;;
+    esac
 
     # OK
-    echo "metis (label=$label) - $prefix"
+    echo "metis (${label}) - $prefix"
     export HAVE_METIS=true
     export METIS_ARCH_PATH="$prefix"
     export METIS_INC_DIR="${header%/*}"     # Basename
     export METIS_LIB_DIR="${library%/*}"    # Basename
+
+    ##echo "DEBUG: header=$header" 1>&2
+    ##echo "DEBUG: library=$library" 1>&2
 }
 
 
@@ -160,8 +184,10 @@ no_metis
 
 # Test/query
 case "$1" in
--test)
+-test | -debug-test)
+    [ "$1" = "-debug-test" ] && set -x
     have_metis
+    [ "$1" = "-debug-test" ] && set +x
     echo_metis
     ;;
 -query)
diff --git a/wmake/scripts/have_scotch b/wmake/scripts/have_scotch
index fdae90a59b810c527ff85eb31cf96dab84cdad81..82adee73645f72db6836d71a39934baaedea6bd1 100644
--- a/wmake/scripts/have_scotch
+++ b/wmake/scripts/have_scotch
@@ -5,7 +5,7 @@
 #   \\  /    A nd           | www.openfoam.com
 #    \\/     M anipulation  |
 #------------------------------------------------------------------------------
-#     Copyright (C) 2018-2020 OpenCFD Ltd.
+#     Copyright (C) 2018-2021 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
 #     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@@ -27,6 +27,7 @@
 #     SCOTCH_ARCH_PATH
 #     SCOTCH_INC_DIR
 #     SCOTCH_LIB_DIR
+#     SCOTCH_LIBNAME_SUFFIX [optional]
 #
 # Functions provided [Must call have_scotch first]
 #     have_ptscotch, search_ptscotch
@@ -70,6 +71,10 @@
 # when MPI_ARCH_PATH=/usr/lib64/openmpi
 # and mpicc --showme:compile -> -I/usr/include/openmpi-x86_64
 #
+# NB: for RedHat (8+) /usr/include/scotch.h is a wrapper that includes
+#    /usr/include/scotch-64.h  (LP64 mode)
+# or /usr/include/scotch-32.h  (ILP32 mode)
+# In either case, int is 32 bits
 #
 # openSUSE
 # --------
@@ -90,7 +95,7 @@
 no_scotch()
 {
     unset HAVE_SCOTCH SCOTCH_ARCH_PATH SCOTCH_INC_DIR SCOTCH_LIB_DIR
-    unset SCOTCH_VERSION
+    unset SCOTCH_VERSION SCOTCH_LIBNAME_SUFFIX
     unset HAVE_PTSCOTCH PTSCOTCH_ARCH_PATH PTSCOTCH_INC_DIR PTSCOTCH_LIB_DIR
 }
 
@@ -102,11 +107,19 @@ echo_scotch()
     echo "root=\"$SCOTCH_ARCH_PATH\""
     echo "include=\"$SCOTCH_INC_DIR\""
     echo "library=\"$SCOTCH_LIB_DIR\""
+    if [ -n "$SCOTCH_LIBNAME_SUFFIX" ]
+    then
+        echo "libsuffix=\"$SCOTCH_LIBNAME_SUFFIX\""
+    fi
     echo
     echo "ptscotch=${HAVE_PTSCOTCH:-false}"
     echo "root=\"$PTSCOTCH_ARCH_PATH\""
     echo "include=\"$PTSCOTCH_INC_DIR\""
     echo "library=\"$PTSCOTCH_LIB_DIR\""
+    if [ -n "$SCOTCH_LIBNAME_SUFFIX" ]
+    then
+        echo "libsuffix=\"$SCOTCH_LIBNAME_SUFFIX\""
+    fi
 }
 
 
@@ -137,7 +150,7 @@ search_scotch()
             "$prefix/include/scotch/$incName" \
             "$prefix/include/$incName" \
         )
-        library=$(findExtLib "$libName")
+        library="-extlib"  # Delay search...
     elif isSystem "$prefix"
     then
         header=$(findFirstFile \
@@ -161,6 +174,41 @@ search_scotch()
         return 2
     }
 
+    # ----------------------------------
+    # Extract 'typedef int64_t SCOTCH_Num' etc from header file
+    # - ensure consistent size between OpenFOAM and scotch header
+    # - for some systems, scotch.h includes scotch-64.h (for example).
+
+    local label
+    for hdr in \
+        "$header" \
+        "${header%/*}"/scotch-64.h \
+        "${header%/*}"/scotch-32.h \
+    ;
+    do
+        if [ -f "$hdr" ]
+        then
+            label=$(sed -ne \
+                's/^.*typedef *\([^ ]*\) *SCOTCH_Num.*/\1/p' \
+                "$hdr")
+
+            if [ -n "$label" ]
+            then
+                header="$hdr"  # Appears successful
+                break
+            fi
+        fi
+    done
+    : "${label:=unknown}"  # Safety
+
+    # Transform (int32_t | int64_t) -> (int32 | int64)
+    case "$label" in (int32_t | int64_t) label="${label%_t}" ;; esac
+
+    if [ "$library" = "-extlib" ]
+    then
+        library=$(findExtLib "${libName}-${label}" "$libName")
+    fi
+
     # Library
     [ -n "$library" ] \
     || library=$(findLibrary -prefix="$prefix" -name="$libName" -local="$localDir") \
@@ -171,16 +219,6 @@ search_scotch()
 
     # ----------------------------------
 
-    local label
-
-    # Ensure consistent sizes between OpenFOAM and scotch header
-    # extract 'typedef int64_t SCOTCH_Num' or equivalent
-    label=$(sed -ne \
-        's/^.*typedef *\([^ ]*\) *SCOTCH_Num.*/\1/p' \
-        "$header")
-    : "${label:=unknown}"
-
-
     # No SCOTCH_VERSION set? Try to obtain from header
     # extract #define SCOTCH_VERSION, SCOTCH_RELEASE, SCOTCH_PATCHLEVEL
     [ -n "$SCOTCH_VERSION" ] || \
@@ -197,8 +235,12 @@ search_scotch()
     )
     : "${SCOTCH_VERSION:=scotch}"  # Failsafe value
 
+    # Accept widening of OpenFOAM label to scotch label (SCOTCH_Num)
+    # but reject narrowing here instead of in the code
     case "$WM_LABEL_SIZE:$label" in
-    (32:int32_t | 32:int | 64:int64_t | 64:long)
+    ( 32:int32 | 32:int \
+    | 32:int64 | 32:long \
+    | 64:int64 | 64:long )
         ;;
 
     (*)
@@ -211,13 +253,22 @@ search_scotch()
         ;;
     esac
 
+    # Library name suffix (-int32 | -int64)
+    case "${library##*/}" in
+    (*-int32.*) export SCOTCH_LIBNAME_SUFFIX="-int32" ;;
+    (*-int64.*) export SCOTCH_LIBNAME_SUFFIX="-int64" ;;
+    esac
+
     # OK
-    echo "scotch (label=$label) - $prefix"
+    echo "scotch ($label) - $prefix"
     export HAVE_SCOTCH=true
     export SCOTCH_ARCH_PATH="$prefix"
     export SCOTCH_INC_DIR="${header%/*}"     # Basename
     export SCOTCH_LIB_DIR="${library%/*}"    # Basename
     export SCOTCH_VERSION
+
+    ##echo "DEBUG: header=$header" 1>&2
+    ##echo "DEBUG: library=$library" 1>&2
 }
 
 
@@ -256,7 +307,11 @@ search_ptscotch()
             "$prefix/include/$mpiName/$incName" \
             "$prefix/include/${mpiName}-$(uname -m)/$incName" \
         )
-        library="$(findExtLib $FOAM_MPI/$libName $libName)"
+        library=$(findExtLib \
+            "$FOAM_MPI/$libName${SCOTCH_LIBNAME_SUFFIX}" \
+            "$libName${SCOTCH_LIBNAME_SUFFIX}" \
+            "$FOAM_MPI/$libName${SCOTCH_LIBNAME_SUFFIX}" \
+        )
     elif isSystem "$prefix"
     then
         header=$(findFirstFile \
@@ -302,6 +357,9 @@ search_ptscotch()
     export PTSCOTCH_ARCH_PATH="$prefix"
     export PTSCOTCH_INC_DIR="${header%/*}"     # Basename
     export PTSCOTCH_LIB_DIR="${library%/*}"    # Basename
+
+    ##echo "DEBUG: header=$header" 1>&2
+    ##echo "DEBUG: library=$library" 1>&2
 }
 
 
@@ -366,8 +424,10 @@ no_scotch
 
 # Test/query
 case "$1" in
--test)
+-test | -debug-test)
+    [ "$1" = "-debug-test" ] && set -x
     have_scotch && have_ptscotch
+    [ "$1" = "-debug-test" ] && set +x
     echo_scotch
     ;;
 -query)