diff --git a/applications/test/00-machine-sizes/Test-machine-sizes.cpp b/applications/test/00-machine-sizes/Test-machine-sizes.cpp
index 917782dfde1f3f0228e9ebff3acf2ae632abea05..e66fa7e57c33fe0951f8a7d9abee80d96419f771 100644
--- a/applications/test/00-machine-sizes/Test-machine-sizes.cpp
+++ b/applications/test/00-machine-sizes/Test-machine-sizes.cpp
@@ -51,17 +51,20 @@ Description
 //- Mapping of some fundamental and aggregate types to MPI data types
 enum class dataTypes : int
 {
-    // Builtin Types [8]:
-    DataTypes_begin,    //!< Begin builtin types (internal use)
-    type_byte = DataTypes_begin,  // also for char, unsigned char
+    // Fundamental Types [10]:
+    Basic_begin,
+    type_byte = Basic_begin,
+    type_int16,
     type_int32,
     type_int64,
+    type_uint16,
     type_uint32,
     type_uint64,
     type_float,
     type_double,
     type_long_double,
-    invalid
+    invalid,
+    Basic_end = invalid
 };
 
 
@@ -69,20 +72,19 @@ enum class dataTypes : int
 
 // Partial copy from UPstreamTraits.H
 
-//- A supported UPstream data type (intrinsic or user-defined)
+//- UPstream data type corresponding to an intrinsic (MPI) type
 template<class T>
-struct UPstream_base_dataType : std::false_type
+struct UPstream_mpi_dataType : std::false_type
 {
     static constexpr auto datatype_id = dataTypes::invalid;
 };
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// Specializations of the above,
-// each to match the elements of UPstream::dataTypes
 
+// Specializations to match elements of UPstream::dataTypes
 #undef  defineUPstreamDataTraits
 #define defineUPstreamDataTraits(TypeId, Type)                                \
-    template<> struct UPstream_base_dataType<Type> : std::true_type           \
+    template<> struct UPstream_mpi_dataType<Type> : std::true_type            \
     {                                                                         \
         static constexpr auto datatype_id = dataTypes::TypeId;                \
     };
@@ -90,8 +92,10 @@ struct UPstream_base_dataType : std::false_type
 
 defineUPstreamDataTraits(type_byte,   char);
 defineUPstreamDataTraits(type_byte,   unsigned char);
+defineUPstreamDataTraits(type_int16,  int16_t);
 defineUPstreamDataTraits(type_int32,  int32_t);
 defineUPstreamDataTraits(type_int64,  int64_t);
+defineUPstreamDataTraits(type_uint16, uint16_t);
 defineUPstreamDataTraits(type_uint32, uint32_t);
 defineUPstreamDataTraits(type_uint64, uint64_t);
 defineUPstreamDataTraits(type_float,  float);
@@ -109,8 +113,8 @@ struct UPstream_alias_dataType
 :
     std::bool_constant
     <
-        // Base type (no alias needed)
-        UPstream_base_dataType<std::remove_cv_t<T>>::value ||
+        // Basic MPI type
+        UPstream_mpi_dataType<std::remove_cv_t<T>>::value ||
         (
             // Or some int 32/64 type to re-map
             std::is_integral_v<T>
@@ -118,15 +122,11 @@ struct UPstream_alias_dataType
         )
     >
 {
-    // Is it using the base type? (no alias needed)
-    static constexpr bool is_base =
-        UPstream_base_dataType<std::remove_cv_t<T>>::value;
-
     using base = std::conditional_t
     <
-        UPstream_base_dataType<std::remove_cv_t<T>>::value,  // is_base
-        std::remove_cv_t<T>,
-        std::conditional_t
+        UPstream_mpi_dataType<std::remove_cv_t<T>>::value,
+        std::remove_cv_t<T>,  // <- using mpi type (no alias)
+        std::conditional_t    // <- using alias
         <
             (
                 std::is_integral_v<T>
@@ -138,12 +138,32 @@ struct UPstream_alias_dataType
                 std::conditional_t<std::is_signed_v<T>, int32_t, uint32_t>,
                 std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>
             >,
-            char  // Fallback value (assuming it is contiguous)
+            char  // Fallback is a byte (eg, arbitrary contiguous data)
         >
     >;
 
     static constexpr auto datatype_id =
-        UPstream_base_dataType<base>::datatype_id;
+        UPstream_mpi_dataType<base>::datatype_id;
+};
+
+
+// Handle int8_t/uint8_t as aliases since 'signed char' etc may be
+// ambiguous
+
+//- Map \c int8_t to UPstream::dataTypes::type_byte
+template<>
+struct UPstream_alias_dataType<int8_t> : std::true_type
+{
+    using base = char;
+    static constexpr auto datatype_id = dataTypes::type_byte;
+};
+
+//- Map \c uint8_t to UPstream::dataTypes::type_byte
+template<>
+struct UPstream_alias_dataType<uint8_t> : std::true_type
+{
+    using base = unsigned char;
+    static constexpr auto datatype_id = dataTypes::type_byte;
 };
 
 
@@ -172,26 +192,31 @@ void print(const char* name, bool showLimits = true)
     }
 
     // A declared or deduced MPI type, or aliased
-    std::cout
-        << " is_mpi=" << UPstream_base_dataType<T>::value
-        << " (" << int(UPstream_base_dataType<T>::datatype_id) << ")";
+    if constexpr (UPstream_mpi_dataType<T>::value)
+    {
+        std::cout
+            << " is_mpi=("
+            << int(UPstream_mpi_dataType<T>::datatype_id) << ')';
+    }
+    else
+    {
+        std::cout << " is_mpi=(null)";
+    }
 
-    if (UPstream_alias_dataType<T>::value)
+    // Any aliases?
+    if constexpr (UPstream_alias_dataType<T>::value)
     {
-        if (UPstream_alias_dataType<T>::is_base)
+        if constexpr (UPstream_mpi_dataType<T>::value)
         {
-            std::cout<< " is_base";
+            std::cout << " alias=base";
         }
         else
         {
-            std::cout<< " is_alias ("
-                << int(UPstream_alias_dataType<T>::datatype_id) << ")";
+            std::cout
+                << " alias=("
+                << int(UPstream_alias_dataType<T>::datatype_id) << ')';
         }
     }
-    else
-    {
-        std::cout<< " no_alias";
-    }
 
     std::cout<< '\n';
 }
@@ -217,6 +242,7 @@ int main(int argc, char *argv[])
 
     std::cout << '\n';
     print<char>("char");
+    print<signed char>("signed char");
     print<unsigned char>("unsigned char");
     print<short>("short");
     print<int>("int");
diff --git a/applications/test/UPstreamTraits/Test-UPstreamTraits.cxx b/applications/test/UPstreamTraits/Test-UPstreamTraits.cxx
index 9c747c61fa7fd2821a039ac161cda0875daaf75c..d8cb032749dabba3e6d0b56fdea9620e1a785313 100644
--- a/applications/test/UPstreamTraits/Test-UPstreamTraits.cxx
+++ b/applications/test/UPstreamTraits/Test-UPstreamTraits.cxx
@@ -37,35 +37,40 @@ Description
 #include "vector.H"
 #include "tensor.H"
 #include "uLabel.H"
+#include "MinMax.H"
 #include "Switch.H"
 #include "IOstreams.H"
 #include "UPstream.H"
 
+#include <functional>
 #include <type_traits>
 
-using namespace Foam;
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-// Just for debugging
-const List<std::string> dataType_names
-({
-    "byte",
-    "int32",
-    "int64",
-    "uint32",
-    "uint64",
-    "float",
-    "double",
-    "long_double",
+namespace Foam
+{
+
+// Add in some extras from functional
+
+//- Map std::plus to \c UPstream::opCodes::op_sum
+template<>
+struct UPstream_opType<std::plus<void>> : std::true_type
+{
+    static constexpr auto opcode_id = UPstream::opCodes::op_sum;
+};
+
+
+//- Map 'signed char' to UPstream::dataTypes::type_byte
+//  Caution with: may be identical to int8_t mapping!!
+#if 0
+template<>
+struct UPstream_alias_dataType<signed char> : std::true_type
+{
+    using base = char;
+    static constexpr auto datatype_id = UPstream::dataTypes::type_byte;
+};
+#endif
 
-    "float(2)",
-    "double(2)",
-    "float(3)",
-    "double(3)",
-    "float(6)",
-    "double(6)",
-    "float(9)",
-    "double(9)"
-});
 
 //- Test for pTraits typeName member : default is false
 template<class T, class = void>
@@ -82,24 +87,93 @@ struct check_has_typeName
     std::true_type
 {};
 
+} // End namespace Foam
 
-// Possible future change...
-// //- A supported UPstream data type (intrinsic or user-defined)
-// template<>
-// struct UPstream_base_dataType<complex> : std::true_type
-// {
-//     static constexpr auto datatype_id = []()
-//     {
-//         if constexpr (sizeof(complex) == 2*sizeof(float))
-//             return UPstream::dataTypes::type_2float;
-//         else
-//             return UPstream::dataTypes::type_2double;
-//     }();
-// };
 
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-template<class T>
-void printTypeName(const bool showSize = false)
+// Just for debugging
+static const Foam::List<std::string> dataType_names
+({
+    "byte",
+    "int16",
+    "int32",
+    "int64",
+    "uint16",
+    "uint32",
+    "uint64",
+    "float",
+    "double",
+    "long_double",
+
+    "float[3]",
+    "double[3]",
+    "float[6]",
+    "double[6]",
+    "float[9]",
+    "double[9]"
+});
+
+// Just for debugging
+static const Foam::List<std::string> opType_names
+({
+    "op_min",
+    "op_max",
+    "op_sum",
+    "op_prod",
+    "op_bool_and",
+    "op_bool_or",
+    "op_bool_xor",
+    "op_bit_and",
+    "op_bit_or",
+    "op_bit_xor",
+    "op_replace",
+    "op_no_op"
+});
+
+
+using namespace Foam;
+
+void printDataTypeId(UPstream::dataTypes datatype_id)
+{
+    if (datatype_id != UPstream::dataTypes::invalid)
+    {
+        const int index = int(datatype_id);
+        if (index < dataType_names.size())
+        {
+            Info<< dataType_names[index];
+        }
+        else
+        {
+            Info<< '(' << index << ')';
+        }
+    }
+}
+
+
+void printOpCodeId(UPstream::opCodes opcode_id)
+{
+    if (opcode_id != UPstream::opCodes::invalid)
+    {
+        const int index = int(opcode_id);
+        if (index < opType_names.size())
+        {
+            Info<< ':' << opType_names[index].c_str();
+        }
+        else
+        {
+            Info<< '(' << index << ')';
+        }
+    }
+    else
+    {
+        Info<< "(null)";
+    }
+}
+
+
+template<class T, bool showSize = false>
+void printTypeName()
 {
     // Both float and double have pTraits typeName = "scalar"!
     if constexpr (std::is_same_v<float, std::remove_cv_t<T>>)
@@ -118,12 +192,13 @@ void printTypeName(const bool showSize = false)
     {
         Info<< typeid(T).name();
     }
-    if (showSize)
+    if constexpr (showSize)
     {
         Info<< " (" << sizeof(T) << " bytes)";
     }
 }
 
+
 template<class Type, bool UseTypeName = true>
 void printPstreamTraits(const std::string_view name = std::string_view())
 {
@@ -133,55 +208,111 @@ void printPstreamTraits(const std::string_view name = std::string_view())
     {
         Info<< name << ' ';
     }
+
     if constexpr (UseTypeName)
     {
-        printTypeName<Type>(true);
+        printTypeName<Type, true>();
     }
     else
     {
-        Info<< typeid(Type).name();
-        Info<< " (" << sizeof(Type) << " bytes)";
+        Info<< typeid(Type).name() << " (" << sizeof(Type) << " bytes)";
+    }
+
+    {
+        using cmpt = typename Foam::pTraits_cmptType<Type>::type;
+
+        if constexpr (!std::is_same_v<Type, cmpt>)
+        {
+            Info<< ", cmpt:";
+
+            if constexpr (UseTypeName)
+            {
+                printTypeName<cmpt, true>();
+            }
+            else
+            {
+                Info<< typeid(cmpt).name() << " (" << sizeof(cmpt) << " bytes)";
+            }
+        }
     }
 
-    Info<< ", cmpt:";
-    printTypeName<typename Foam::pTraits_cmptType<Type>::type>(true);
 
     Info<< nl
         << "  is_contiguous:"
-        << is_contiguous<Type>::value
-        << ", is base:"
-        << UPstream_base_dataType<Type>::value
-        << ", is cmpt:"
-        << UPstream_dataType<Type>::value << nl;
-
-    Info<< "is base:"
-        << UPstream_base_dataType<Type>::value
-        << " (type:" << int(UPstream_base_dataType<Type>::datatype_id)
-        << ")  is alias:" << UPstream_alias_dataType<Type>::value
-        << " (type:" << int(UPstream_alias_dataType<Type>::datatype_id)
-        << ")" << nl;
+        << is_contiguous<Type>::value;
 
+    if constexpr (UPstream_mpi_dataType<Type>::value)
+    {
+        Info<< ", is_mpi=("
+            << int(UPstream_mpi_dataType<Type>::datatype_id) << ')';
+    }
+    else
+    {
+        std::cout << ", is_mpi=(null)";
+    }
+    if constexpr (UPstream_user_dataType<Type>::value)
+    {
+        Info<< ", is_user=("
+            << int(UPstream_user_dataType<Type>::datatype_id) << ')';
+    }
+    else
+    {
+        std::cout << ", is_user=(null)";
+    }
+    if constexpr (UPstream_any_dataType<Type>::value)
+    {
+        Info<< ", is_any=("
+            << int(UPstream_any_dataType<Type>::datatype_id) << ')';
+    }
+    else
+    {
+        std::cout << ", is_any=(null)";
+    }
 
+    // Any aliases?
+    if constexpr
+    (
+        UPstream_alias_dataType<Type>::value
+     && !UPstream_mpi_dataType<Type>::value
+    )
     {
-        int index = int(UPstream_base_dataType<Type>::datatype_id);
-        Info<< "datatype: " << index;
+        Info<< ", alias=("
+            << int(UPstream_alias_dataType<Type>::datatype_id) << ')';
+    }
 
-        if (index < dataType_names.size())
-        {
-            Info<< ' ' << dataType_names[index];
-        }
-        Info<< nl;
+    Info<< " base-type:" << int(UPstream_basic_dataType<Type>::datatype_id)
+        << " data-type:" << int(UPstream_dataType<Type>::datatype_id)
+        << nl;
+
+    if constexpr (UPstream_basic_dataType<Type>::value)
+    {
+        Info<< " base-type=";
+        printDataTypeId(UPstream_basic_dataType<Type>::datatype_id);
+    }
+    else if constexpr (UPstream_dataType<Type>::value)
+    {
+        Info<< " data-type=";
+        printDataTypeId(UPstream_dataType<Type>::datatype_id);
     }
 
     {
         // Use element or component type (or byte-wise) for data type
         using base = typename UPstream_dataType<Type>::base;
-        constexpr auto datatype = UPstream_dataType<Type>::datatype_id;
 
-        Info<< "datatype => ";
-        printTypeName<base>();
-        Info<< " (" << sizeof(Type)/sizeof(base) << " elems)" << nl
-            << "datatype: " << static_cast<int>(datatype) << nl;
+        Info<< " : ";
+        if constexpr (UseTypeName)
+        {
+            printTypeName<base, true>();
+        }
+        else
+        {
+            Info<< typeid(base).name() << " (" << sizeof(base) << " bytes)";
+        }
+
+        Info<< " cmpt-type=";
+        printDataTypeId(UPstream_dataType<Type>::datatype_id);
+        Info<< " count=" << UPstream_dataType<Type>::size(1);
+        Info<< nl;
     }
 }
 
@@ -190,15 +321,44 @@ template<class BinaryOp>
 void printOpCodeTraits(BinaryOp bop, std::string_view name)
 {
     Info<< "op: " << name << ' ';
-    if constexpr (UPstream_opType<BinaryOp>::value)
-    {
-        Info<< "supported";
-    }
-    else
+
+    printOpCodeId(UPstream_opType<BinaryOp>::opcode_id);
+    Info<< nl;
+}
+
+
+template<class DataType, class BinaryOp>
+void printOpCodeTraits(BinaryOp bop, std::string_view name)
+{
+    Info<< "op: " << name << ' ';
+
+    printOpCodeId(UPstream_opType<BinaryOp>::opcode_id);
+
+    if constexpr (!std::is_void_v<DataType>)
     {
-        Info<< "unknown";
+        if constexpr (UPstream_basic_dataType<DataType>::value)
+        {
+            Info<< " [supported type]";
+        }
+        else
+        {
+            Info<< " [disabled]";
+        }
     }
-    Info<< ": " << int(UPstream_opType<BinaryOp>::opcode_id) << nl;
+    Info<< nl;
+}
+
+
+template<class DataType, class BinaryOp>
+void print_data_opType(BinaryOp bop, std::string_view name)
+{
+    Info<< "op: " << name << ' ';
+
+    printOpCodeId(UPstream_data_opType<BinaryOp, DataType>::opcode_id);
+
+    const bool ok = UPstream_data_opType<BinaryOp, DataType>::value;
+
+    Info<< " okay=" << ok << nl;
 }
 
 
@@ -210,6 +370,16 @@ int main()
     printPstreamTraits<bool>();
     printPstreamTraits<label>();
 
+    printPstreamTraits<char, false>("<char>");
+    printPstreamTraits<signed char, false>("<signed char>");
+    printPstreamTraits<unsigned char, false>("<unsigned char>");
+
+    printPstreamTraits<int8_t, false>("<int8_t>");
+    printPstreamTraits<uint8_t, false>("<uint8_t>");
+
+    printPstreamTraits<int16_t, false>("<int16_t>");
+    printPstreamTraits<uint16_t, false>("<uint16_t>");
+
     printPstreamTraits<int>("<int>");
     printPstreamTraits<long>("<long>");
     printPstreamTraits<unsigned>("<unsigned>");
@@ -258,6 +428,35 @@ int main()
     printOpCodeTraits(bitAndOp<unsigned>{}, "bitAnd<unsigned>");
     printOpCodeTraits(bitOrOp<unsigned>{}, "bitOr<unsigned>");
 
+    printOpCodeTraits<vector>(sumOp<vector>{}, "sum");
+    printOpCodeTraits(sumOp<scalarMinMax>{}, "sum");
+
+    printOpCodeTraits(std::plus<>{}, "sum");
+    printOpCodeTraits<bool>(std::plus<>{}, "sum");
+    printOpCodeTraits<vector>(std::plus<>{}, "sum");
+
+
+    // Expect success
+    Info<< nl << "expect success" << nl;
+    print_data_opType<vector>(maxOp<scalar>(), "maxOp(scalar)");
+    print_data_opType<unsigned>(bitOrOp<unsigned>(), "bitOrOp(unsigned)");
+    print_data_opType<uint8_t>(bitOrOp<uint8_t>(), "bitOrOp(uint8_t)");
+    print_data_opType<uint16_t>(bitOrOp<uint16_t>(), "bitOrOp(uint16_t)");
+
+    // Even allow signed integrals
+    print_data_opType<int>(bitOrOp<int>(), "bitOrOp(int)");
+    print_data_opType<int8_t>(bitOrOp<int8_t>(), "bitOrOp(int8_t)");
+
+    // Failure - supported op, unsupported data type.
+    Info<< nl << "expect failure" << nl;
+    print_data_opType<bool>(maxOp<scalar>(), "maxOp(scalar, bool)");
+    print_data_opType<bool>(bitOrOp<unsigned>(), "bitOrOp(unsigned, bool)");
+
+    // False positives. Failure - supported op, unsupported data type.
+    Info<< nl << "false positives" << nl;
+    print_data_opType<void>(maxOp<bool>(), "maxOp(bool, void)");
+    print_data_opType<float>(bitOrOp<unsigned>(), "bitOrOp(unsigned, float)");
+
     Info<< nl << "End\n" << endl;
 
     return 0;
diff --git a/applications/test/globalIndex3/Test-globalIndex3.cxx b/applications/test/globalIndex3/Test-globalIndex3.cxx
index 19a72499d3290652b284becd53b5dc6597523dfc..19beee62390423d68c0b9ac5855f97c7220bca52 100644
--- a/applications/test/globalIndex3/Test-globalIndex3.cxx
+++ b/applications/test/globalIndex3/Test-globalIndex3.cxx
@@ -345,8 +345,8 @@ static void reportOffsets(const globalIndex& gi)
 
         UPstream::broadcast
         (
-            allOffsets.data_bytes(),
-            allOffsets.size_bytes(),
+            allOffsets.data(),
+            allOffsets.size(),
             interNodeComm
         );
     }
@@ -508,7 +508,7 @@ int main(int argc, char *argv[])
 
     #include "setRootCase.H"
 
-    const bool useLocalComms = UPstream::usingNodeComms();
+    const bool useLocalComms = UPstream::usingNodeComms(UPstream::worldComm);
     bool useWindow = args.found("window");
     bool useBuiltin = args.found("builtin");
 
diff --git a/applications/test/nodeTopology/Test-nodeTopology.cxx b/applications/test/nodeTopology/Test-nodeTopology.cxx
index 9909d51d4f51b7b0e8443cd86bd6e01adaee588b..58b3d56cde534bda035555cfe0e5eb88150d4fde 100644
--- a/applications/test/nodeTopology/Test-nodeTopology.cxx
+++ b/applications/test/nodeTopology/Test-nodeTopology.cxx
@@ -115,6 +115,13 @@ int main(int argc, char *argv[])
     );
 
 
+    if (UPstream::parRun())
+    {
+        const auto& procs = UPstream::localNode_parentProcs();
+        Perr<< "local processors: [" << procs.min()
+            << ".." << procs.max() << ']' << endl;
+    }
+
     // Generate the graph
     if (UPstream::master(UPstream::worldComm))
     {
diff --git a/applications/test/vector/Make/files b/applications/test/vector/Make/files
index 62f06825eaea118c5850244641d6f8c1fcbaa81b..68db4be0f7b8912c987016776f65d037f8a1486c 100644
--- a/applications/test/vector/Make/files
+++ b/applications/test/vector/Make/files
@@ -1,3 +1,3 @@
-Test-vector.C
+Test-vector.cxx
 
 EXE = $(FOAM_USER_APPBIN)/Test-vector
diff --git a/applications/test/vector/Test-vector.C b/applications/test/vector/Test-vector.cxx
similarity index 84%
rename from applications/test/vector/Test-vector.C
rename to applications/test/vector/Test-vector.cxx
index 582f8bf50490b3f9b9804a06a6ef3334940bc5fe..cc2ad57d36edb423193995a5d77898d530ddc84d 100644
--- a/applications/test/vector/Test-vector.C
+++ b/applications/test/vector/Test-vector.cxx
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018-2023 OpenCFD Ltd.
+    Copyright (C) 2018-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,7 +32,10 @@ Description
 \*---------------------------------------------------------------------------*/
 
 #include "vectorField.H"
+#include "boolVector.H"
+#include "labelVector.H"
 #include "IOstreams.H"
+#include "FixedList.H"
 #include "Random.H"
 #include <algorithm>
 #include <random>
@@ -125,6 +128,42 @@ void testNormalise(Field<Type>& fld)
 }
 
 
+// Transcribe vectorspace information into a FixedList
+template<class Type>
+void testTranscribe(Type& input)
+{
+    if constexpr
+    (
+        is_vectorspace_v<Type>
+     && std::is_floating_point_v<typename pTraits_cmptType<Type>::type>
+    )
+    {
+        constexpr auto nCmpts = pTraits_nComponents<Type>::value;
+        using cmpt = typename pTraits_cmptType<Type>::type;
+
+        FixedList<cmpt, nCmpts+1> values;
+        values.back() = 100;  // some additional data
+
+        VectorSpaceOps<nCmpts>::copy_n(input.cdata(), values.data());
+
+        Info<< "Transcribed " << input << " => " << values << nl;
+
+        for (auto& val : values)
+        {
+            val *= -1;
+        }
+
+        VectorSpaceOps<nCmpts>::copy_n(values.cdata(), input.data());
+        Info<< "  copied back (-1) as " << input
+            << " from " << values << nl;
+    }
+    else
+    {
+        Info<< "Did not transcribe " << input << nl;
+    }
+}
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 //  Main program:
 
@@ -240,6 +279,16 @@ int main(int argc, char *argv[])
         testNormalise(vfld2);
     }
 
+    Info<< nl
+        << "Test transcribing components" << nl;
+    {
+        vector vec1(1.1, 2.2, 3.3);
+        testTranscribe(vec1);
+
+        labelVector vec2(10, 20, 30);
+        testTranscribe(vec2);
+    }
+
     Info<< "\nEnd\n" << nl;
 
     return 0;
diff --git a/applications/test/vectorTools/Make/files b/applications/test/vectorTools/Make/files
index 0b30b98f8f3b0c0c1048846c8e90a62733a12dda..6c1e81deb863913fc857364785ba4d096e5eaccd 100644
--- a/applications/test/vectorTools/Make/files
+++ b/applications/test/vectorTools/Make/files
@@ -1,3 +1,3 @@
-Test-vectorTools.C
+Test-vectorTools.cxx
 
 EXE = $(FOAM_USER_APPBIN)/Test-vectorTools
diff --git a/applications/test/vectorTools/Test-vectorTools.C b/applications/test/vectorTools/Test-vectorTools.cxx
similarity index 100%
rename from applications/test/vectorTools/Test-vectorTools.C
rename to applications/test/vectorTools/Test-vectorTools.cxx
diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C
index cf15e2f1a51391c64663279962d2fa6e0fc3b3ff..d1fb66a6056c4b48562672c70d9270bd2d116b9e 100644
--- a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C
+++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C
@@ -661,8 +661,8 @@ void countExtrudePatches
     }
     // Synchronise decision. Actual numbers are not important, just make
     // sure that they're > 0 on all processors.
-    Pstream::listCombineReduce(zoneSidePatch, plusEqOp<label>());
-    Pstream::listCombineReduce(zoneZonePatch, plusEqOp<label>());
+    Pstream::listReduce(zoneSidePatch, sumOp<label>());
+    Pstream::listReduce(zoneZonePatch, sumOp<label>());
 }
 
 
diff --git a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
index 64c0b0ef341c0acbadd2d3cf98b447c96ecdcf34..ae9d91f0b194b196630a4b467b9955b15393605d 100644
--- a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
+++ b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
@@ -1081,7 +1081,7 @@ label findCorrespondingRegion
         }
     }
 
-    Pstream::listCombineReduce(cellsInZone, plusEqOp<label>());
+    Pstream::listReduce(cellsInZone, sumOp<label>());
 
     // Pick region with largest overlap of zoneI
     label regionI = findMax(cellsInZone);
diff --git a/applications/utilities/postProcessing/lagrangian/particleTracks/particleTracks.C b/applications/utilities/postProcessing/lagrangian/particleTracks/particleTracks.C
index 754109e162ee10444458e529b1b8ccfa94dfbc50..2202574ad88b3d3a4a62fc229fc6ad026d806e50 100644
--- a/applications/utilities/postProcessing/lagrangian/particleTracks/particleTracks.C
+++ b/applications/utilities/postProcessing/lagrangian/particleTracks/particleTracks.C
@@ -186,7 +186,7 @@ int main(int argc, char *argv[])
         const label maxNProcs = returnReduce(maxIds.size(), maxOp<label>());
         maxIds.resize(maxNProcs, -1);
 
-        Pstream::listCombineReduce(maxIds, maxEqOp<label>());
+        Pstream::listReduce(maxIds, maxOp<label>());
 
         // From ids to count
         const labelList numIds = maxIds + 1;
diff --git a/applications/utilities/postProcessing/miscellaneous/postChannel/channelIndexTemplates.C b/applications/utilities/postProcessing/miscellaneous/postChannel/channelIndexTemplates.C
index e0ca2042b6252cec3094ac6cb7bae890e189258b..5668bcc3cb9ed62cd479f6c76fbbde0a38012b17 100644
--- a/applications/utilities/postProcessing/miscellaneous/postChannel/channelIndexTemplates.C
+++ b/applications/utilities/postProcessing/miscellaneous/postChannel/channelIndexTemplates.C
@@ -40,7 +40,7 @@ Foam::Field<T> Foam::channelIndex::regionSum(const Field<T>& cellField) const
     }
 
     // Global sum
-    Pstream::listCombineReduce(regionField, plusEqOp<T>());
+    Pstream::listReduce(regionField, sumOp<T>());
 
     return regionField;
 }
diff --git a/applications/utilities/preProcessing/createViewFactors/viewFactorModels/raySearchEngine/raySearchEngine/raySearchEngine.C b/applications/utilities/preProcessing/createViewFactors/viewFactorModels/raySearchEngine/raySearchEngine/raySearchEngine.C
index f1a37bbc5f389adc3274f29c3adf730e272c5d76..4f2699517d72c0a5cc6e36efa85c6b2478dcbd68 100644
--- a/applications/utilities/preProcessing/createViewFactors/viewFactorModels/raySearchEngine/raySearchEngine/raySearchEngine.C
+++ b/applications/utilities/preProcessing/createViewFactors/viewFactorModels/raySearchEngine/raySearchEngine/raySearchEngine.C
@@ -229,7 +229,7 @@ void Foam::VF::raySearchEngine::createAgglomeration(const IOobject& io)
     Pstream::allGatherList(allSf_);
     Pstream::allGatherList(allAgg_);
 
-    Pstream::listCombineGather(patchAreas_, plusEqOp<scalar>());
+    Pstream::listGather(patchAreas_, sumOp<scalar>());
     Pstream::broadcast(patchAreas_);
 
     globalNumbering_ = globalIndex(nCoarseFace_);
@@ -262,8 +262,11 @@ void Foam::VF::raySearchEngine::createGeometry()
     Pstream::allGatherList(allCf_);
     Pstream::allGatherList(allSf_);
 
-    Pstream::listCombineGather(patchAreas_, plusEqOp<scalar>());
-    Pstream::broadcast(patchAreas_);
+    // Pstream::listCombineGather(patchAreas_, plusEqOp<scalar>());
+    // Pstream::broadcast(patchAreas_);
+
+    // Basic type and op_sum, so can use listReduce (ie, mpiAllReduce)
+    Pstream::listReduce(patchAreas_, sumOp<scalar>());
 
     globalNumbering_ = globalIndex(nFace_);
 }
diff --git a/applications/utilities/preProcessing/setFields/setFields.C b/applications/utilities/preProcessing/setFields/setFields.C
index 276b36c2f3d5d13b7a03745fefa75cc7f50f65a8..44778b680aea48ce52477d82f5bc579cc0738500 100644
--- a/applications/utilities/preProcessing/setFields/setFields.C
+++ b/applications/utilities/preProcessing/setFields/setFields.C
@@ -407,7 +407,7 @@ bool setFaceFieldType
             }
         }
 
-        Pstream::listCombineReduce(nChanged, plusEqOp<label>());
+        Pstream::listReduce(nChanged, sumOp<label>());
 
         auto& fieldBf = field.boundaryFieldRef();
 
diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H
index 5344e5b364254cf0502bbb0a7df44d61d6f0feb6..8a6abaa91f0d468bc121f0a762112a5014dfa061 100644
--- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H
+++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H
@@ -384,6 +384,10 @@ public:
         //- Return an iterator to end traversing the FixedList
         inline iterator end() noexcept;
 
+        //- Return iterator at offset i from begin,
+        //- clamped to [0,N] range
+        inline iterator begin(const int i) noexcept;
+
 
     // Random access iterator (const)
 
@@ -399,6 +403,14 @@ public:
         //- Return const_iterator to end traversing the constant FixedList
         inline const_iterator end() const noexcept;
 
+        //- Return const_iterator at offset i from begin,
+        //- clamped to [0,N] range
+        inline const_iterator cbegin(const int i) const noexcept;
+
+        //- Return const_iterator at offset i from begin,
+        //- clamped to [0,N] range
+        inline const_iterator begin(const int i) const noexcept;
+
 
     // Reverse iterator (non-const)
 
diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H
index 7d590c3799443d0a1867ae2ae5629671e84df3eb..61fe38572fb27fdb2fab76ef98c9b217cae3d553 100644
--- a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H
+++ b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H
@@ -499,6 +499,30 @@ Foam::FixedList<T, N>::cbegin() const noexcept
 }
 
 
+template<class T, unsigned N>
+inline typename Foam::FixedList<T, N>::iterator
+Foam::FixedList<T, N>::begin(const int i) noexcept
+{
+    return (v_ + (i < 0 ? 0 : int(N) < i ? int(N) : i));
+}
+
+
+template<class T, unsigned N>
+inline typename Foam::FixedList<T, N>::const_iterator
+Foam::FixedList<T, N>::begin(const int i) const noexcept
+{
+    return (v_ + (i < 0 ? 0 : int(N) < i ? int(N) : i));
+}
+
+
+template<class T, unsigned N>
+inline typename Foam::FixedList<T, N>::const_iterator
+Foam::FixedList<T, N>::cbegin(const int i) const noexcept
+{
+    return (v_ + (i < 0 ? 0 : int(N) < i ? int(N) : i));
+}
+
+
 template<class T, unsigned N>
 inline typename Foam::FixedList<T, N>::iterator
 Foam::FixedList<T, N>::end() noexcept
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/IPBstreams.C b/src/OpenFOAM/db/IOstreams/Pstreams/IPBstreams.C
index 54b1305f27ed6d378682f44c0de1aec9280e0cb4..43fcb428d73d062735bda45f412ac9431a743c91 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/IPBstreams.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/IPBstreams.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2024 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -33,24 +33,21 @@ License
 
 Foam::UIPBstream::UIPBstream
 (
-    const UPstream::commsTypes commsType,
-    const int rootProcNo,
     DynamicList<char>& receiveBuf,
     label& receiveBufPosition,
-    const int tag,
-    const label comm,
+    const int communicator,
     const bool clearAtEnd,
     IOstreamOption::streamFormat fmt
 )
 :
     UIPstreamBase
     (
-        commsType,              // irrelevant
-        rootProcNo,             // normally UPstream::masterNo()
+        UPstream::commsTypes::scheduled,    // irrelevant
+        UPstream::masterNo(),   // irrelevant
         receiveBuf,
         receiveBufPosition,
-        tag,                    // irrelevant
-        comm,
+        UPstream::msgType(),    // irrelevant
+        communicator,
         clearAtEnd,
         fmt
     )
@@ -61,64 +58,20 @@ Foam::UIPBstream::UIPBstream
 
 Foam::IPBstream::IPBstream
 (
-    const UPstream::commsTypes commsType,
-    const int rootProcNo,
-    const label bufSize,
-    const int tag,
-    const label comm,
+    const int communicator,
     IOstreamOption::streamFormat fmt
 )
 :
-    Pstream(commsType, bufSize),
+    Pstream(UPstream::commsTypes::scheduled),  // type is irrelevant
     UIPBstream
     (
-        commsType,              // irrelevant
-        rootProcNo,             // normally UPstream::masterNo()
         Pstream::transferBuf_,
         UIPstreamBase::storedRecvBufPos_,   // Internal only
-        tag,                    // irrelevant
-        comm,
+        communicator,
         false,  // Do not clear Pstream::transferBuf_ if at end
         fmt
     )
 {}
 
 
-Foam::IPBstream::IPBstream
-(
-    const int rootProcNo,
-    const label comm,
-    IOstreamOption::streamFormat fmt
-)
-:
-    IPBstream
-    (
-        UPstream::commsTypes::scheduled,    // irrelevant
-        rootProcNo,
-        label(0),  // bufSize
-        UPstream::msgType(),                // irrelevant
-        comm,
-        fmt
-    )
-{}
-
-
-Foam::IPBstream::IPBstream
-(
-    const label comm,
-    IOstreamOption::streamFormat fmt
-)
-:
-    IPBstream
-    (
-        UPstream::commsTypes::scheduled,    // irrelevant
-        UPstream::masterNo(),  // rootProcNo
-        label(0),  // bufSize
-        UPstream::msgType(),                // irrelevant
-        comm,
-        fmt
-    )
-{}
-
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/IPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/IPstream.H
index e1304da88512322a2b7c3a1c5d150a4fc04445a8..056d3dd0fbafcccd321c06e9051749d535528385 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/IPstream.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/IPstream.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2013 OpenFOAM Foundation
-    Copyright (C) 2021-2024 OpenCFD Ltd.
+    Copyright (C) 2021-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -61,14 +61,13 @@ public:
     // Constructors
 
         //- Construct given process index to read from
-        //- and optional buffer size, read format
         IPstream
         (
             const UPstream::commsTypes commsType,
             const int fromProcNo,
-            const label bufSize = 0,
+            const int bufferSize = 0,  //!< optional buffer size
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
 
@@ -83,7 +82,7 @@ public:
             Type& value,
             const int fromProcNo,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         )
         {
@@ -91,9 +90,9 @@ public:
             (
                 UPstream::commsTypes::scheduled,  // ie, MPI_Recv()
                 fromProcNo,
-                0,  // bufSize
+                0,  // bufferSize
                 tag,
-                comm,
+                communicator,
                 fmt
             );
             is >> value;
@@ -116,31 +115,11 @@ public:
 
     // Constructors
 
-        //- Construct for broadcast root, optional buffer size, read format
-        IPBstream
-        (
-            const UPstream::commsTypes,     //!< ignored
-            const int rootProcNo,           //!< normally UPstream::masterNo()
-            const label bufSize = 0,
-            const int tag = UPstream::msgType(),  //!< ignored
-            const label comm = UPstream::worldComm,
-            IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
-        );
-
-        //- Construct for broadcast root and communicator,
-        //- with optional read format
-        IPBstream
-        (
-            const int rootProcNo,           //!< normally UPstream::masterNo()
-            const label comm,
-            IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
-        );
-
         //- Construct with optional communicator and read format.
         //- Uses UPstream::masterNo() root
         explicit IPBstream
         (
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
 
@@ -154,12 +133,33 @@ public:
         static void recv
         (
             Type& value,
-            const label comm = UPstream::worldComm,
-            IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
+            const int communicator = UPstream::worldComm
         )
         {
-            IPBstream is(comm, fmt);
-            is >> value;
+            IPBstream is(communicator);
+            {
+                is >> value;
+            }
+        }
+
+        //- Receive (from broadcast) a buffer and deserialize
+        //- multiple items.
+        //- Uses \c operator>> for de-serialization
+        template<class Type, class... Args>
+        static void recvs
+        (
+            const int communicator,
+            Type& value,
+            Args&&... values
+        )
+        {
+            IPBstream is(communicator);
+            {
+                Detail::inputLoop(is, value, std::forward<Args>(values)...);
+                // Depending on compiler support:
+                // Unpack via fold expression
+                // (((is >> value) >> std::forward<Args>(values)), ...);
+            }
         }
 };
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/IPstreams.C b/src/OpenFOAM/db/IOstreams/Pstreams/IPstreams.C
index 340f0a2f990813172778ad811721fc72e35fce46..667970803bcb344f4fafb983dfaa009e7715caeb 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/IPstreams.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/IPstreams.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2023 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -38,7 +38,7 @@ Foam::UIPstream::UIPstream
     DynamicList<char>& receiveBuf,
     label& receiveBufPosition,
     const int tag,
-    const label comm,
+    const int communicator,
     const bool clearAtEnd,
     IOstreamOption::streamFormat fmt
 )
@@ -50,7 +50,7 @@ Foam::UIPstream::UIPstream
         receiveBuf,
         receiveBufPosition,
         tag,
-        comm,
+        communicator,
         clearAtEnd,
         fmt
     )
@@ -105,13 +105,13 @@ Foam::IPstream::IPstream
 (
     const UPstream::commsTypes commsType,
     const int fromProcNo,
-    const label bufSize,
+    const int bufferSize,
     const int tag,
-    const label comm,
+    const int communicator,
     IOstreamOption::streamFormat fmt
 )
 :
-    Pstream(commsType, bufSize),
+    Pstream(commsType, bufferSize),
     UIPstream
     (
         commsType,
@@ -119,7 +119,7 @@ Foam::IPstream::IPstream
         Pstream::transferBuf_,
         UIPstreamBase::storedRecvBufPos_,   // Internal only
         tag,
-        comm,
+        communicator,
         false,  // Do not clear Pstream::transferBuf_ if at end
         fmt
     )
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/OPBstreams.C b/src/OpenFOAM/db/IOstreams/Pstreams/OPBstreams.C
index b68dc927a709dee58c924768adeb6291482be183..c5aed9a4252fdf4b0e0f0312eed1a2cfcd8e67d3 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/OPBstreams.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/OPBstreams.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2024 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -33,22 +33,19 @@ License
 
 Foam::UOPBstream::UOPBstream
 (
-    const UPstream::commsTypes commsType,
-    const int rootProcNo,
     DynamicList<char>& sendBuf,
-    const int tag,
-    const label comm,
+    const int communicator,
     const bool sendAtDestruct,
     IOstreamOption::streamFormat fmt
 )
 :
     UOPstreamBase
     (
-        commsType,              // irrelevant
-        rootProcNo,             // normally UPstream::masterNo()
+        UPstream::commsTypes::scheduled,    // irrelevant
+        UPstream::masterNo(),   // irrelevant
         sendBuf,
-        tag,                    // irrelevant
-        comm,
+        UPstream::msgType(),    // irrelevant
+        communicator,
         sendAtDestruct,
         fmt
     )
@@ -57,65 +54,21 @@ Foam::UOPBstream::UOPBstream
 
 Foam::OPBstream::OPBstream
 (
-    const UPstream::commsTypes commsType,
-    const int rootProcNo,
-    const label bufSize,
-    const int tag,
-    const label comm,
+    const int communicator,
     IOstreamOption::streamFormat fmt
 )
 :
-    Pstream(commsType, bufSize),
+    Pstream(UPstream::commsTypes::scheduled),  // type is irrelevant
     UOPBstream
     (
-        commsType,              // irrelevant
-        rootProcNo,             // normally UPstream::masterNo()
         Pstream::transferBuf_,
-        tag,                    // irrelevant
-        comm,
+        communicator,
         true,  // sendAtDestruct
         fmt
     )
 {}
 
 
-Foam::OPBstream::OPBstream
-(
-    const int rootProcNo,
-    const label comm,
-    IOstreamOption::streamFormat fmt
-)
-:
-    OPBstream
-    (
-        UPstream::commsTypes::scheduled,    // irrelevant
-        rootProcNo,
-        label(0),  // bufSize
-        UPstream::msgType(),                // irrelevant
-        comm,
-        fmt
-    )
-{}
-
-
-Foam::OPBstream::OPBstream
-(
-    const label comm,
-    IOstreamOption::streamFormat fmt
-)
-:
-    OPBstream
-    (
-        UPstream::commsTypes::scheduled,    // irrelevant
-        UPstream::masterNo(),  // rootProcNo
-        label(0),  // bufSize
-        UPstream::msgType(),                // irrelevant
-        comm,
-        fmt
-    )
-{}
-
-
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::UOPBstream::~UOPBstream()
@@ -125,8 +78,7 @@ Foam::UOPBstream::~UOPBstream()
         if (!bufferIPCsend())
         {
             FatalErrorInFunction
-                << "Failed broadcast message of size "
-                << sendBuf_.size() << " root: " << toProcNo_
+                << "Failed broadcast message of size " << sendBuf_.size()
                 << Foam::abort(FatalError);
         }
     }
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.H
index 1b4414a4604a4e366726ab2397f5c0ee2e8469b0..8513b4fbf125b82f1e0b9912639ac85e50f90e4e 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2013 OpenFOAM Foundation
-    Copyright (C) 2021-2024 OpenCFD Ltd.
+    Copyright (C) 2021-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -61,14 +61,13 @@ public:
     // Constructors
 
         //- Construct for given process index to send to
-        //- and optional buffer size, write format
         OPstream
         (
             const UPstream::commsTypes commsType,
             const int toProcNo,
-            const label bufSize = 0,
+            const int bufferSize = 0,  //!< optional buffer size
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
 
@@ -81,15 +80,15 @@ public:
         static void send
         (
             const Type& value,
-            //! blocking or scheduled only!
+            //! buffered or scheduled only!
             const UPstream::commsTypes commsType,
             const int toProcNo,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         )
         {
-            OPstream os(commsType, toProcNo, 0, tag, comm, fmt);
+            OPstream os(commsType, toProcNo, 0, tag, communicator, fmt);
             os << value;
         }
 
@@ -101,7 +100,7 @@ public:
             const Type& value,
             const int toProcNo,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         )
         {
@@ -111,7 +110,7 @@ public:
                 UPstream::commsTypes::scheduled,  // ie, MPI_Send()
                 toProcNo,
                 tag,
-                comm,
+                communicator,
                 fmt
             );
         }
@@ -133,49 +132,51 @@ public:
 
     // Constructors
 
-        //- Construct for broadcast root, optional buffer size, write format
-        OPBstream
-        (
-            const UPstream::commsTypes,     //!< ignored
-            const int rootProcNo,           //!< normally UPstream::masterNo()
-            const label bufSize = 0,
-            const int tag = UPstream::msgType(),  //!< ignored
-            const label comm = UPstream::worldComm,
-            IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
-        );
-
-        //- Construct for broadcast root and communicator,
-        //- with optional write format
-        OPBstream
-        (
-            const int rootProcNo,           //!< normally UPstream::masterNo()
-            const label comm,
-            IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
-        );
-
         //- Construct with optional communicator and write format.
-        //- Uses UPstream::masterNo() root
         explicit OPBstream
         (
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
 
 
     // Static Functions
 
+        //- Use all send methods from base
+        using UOPBstream::send;
+
         //- Serialize a value and broadcast (root == UPstream::masterNo()).
         //- Uses \c operator<< for serialization
         template<class Type>
         static void send
         (
             const Type& value,
-            const label comm = UPstream::worldComm,
-            IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
+            const int communicator = UPstream::worldComm
         )
         {
-            OPBstream os(comm, fmt);
-            os << value;
+            OPBstream os(communicator);
+            {
+                os << value;
+            }
+        }
+
+        //- Serialize multiple items and broadcast the buffer
+        //- Uses \c operator<< for serialization
+        template<class Type, class... Args>
+        static void sends
+        (
+            const int communicator,
+            Type& value,
+            Args&&... values
+        )
+        {
+            OPBstream os(communicator);
+            {
+                Detail::outputLoop(os, value, std::forward<Args>(values)...);
+                // Depending on compiler support:
+                // Pack via fold expression
+                // (((os << value) << std::forward<Args>(values)), ...);
+            }
         }
 };
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/OPstreams.C b/src/OpenFOAM/db/IOstreams/Pstreams/OPstreams.C
index fc8312f674923b47a0b6fcccd4ec742eb46585b7..281bc01a687a5cc90f4a247d115dad67deed32b2 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/OPstreams.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/OPstreams.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011 OpenFOAM Foundation
-    Copyright (C) 2022-2024 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -37,7 +37,7 @@ Foam::UOPstream::UOPstream
     const int toProcNo,
     DynamicList<char>& sendBuf,
     const int tag,
-    const label comm,
+    const int comm,
     const bool sendAtDestruct,
     IOstreamOption::streamFormat fmt
 )
@@ -66,20 +66,20 @@ Foam::OPstream::OPstream
 (
     const UPstream::commsTypes commsType,
     const int toProcNo,
-    const label bufSize,
+    const int bufferSize,
     const int tag,
-    const label comm,
+    const int communicator,
     IOstreamOption::streamFormat fmt
 )
 :
-    Pstream(commsType, bufSize),
+    Pstream(commsType, bufferSize),
     UOPstream
     (
         commsType,
         toProcNo,
         Pstream::transferBuf_,
         tag,
-        comm,
+        communicator,
         true,  // sendAtDestruct
         fmt
     )
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/Pstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/Pstream.H
index 0e26a4a3998035568ee44bcccf2001a3d87244b8..91329be13da8104fe0ddb8e8edcecfabe4f84834 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/Pstream.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/Pstream.H
@@ -75,18 +75,20 @@ public:
 
     // Constructors
 
-        //- Construct for given communication type, with optional buffer size
-        explicit Pstream
-        (
-            const UPstream::commsTypes commsType,
-            const label bufSize = 0
-        )
+        //- Construct for communication type with empty buffer
+        explicit Pstream(const UPstream::commsTypes commsType) noexcept
+        :
+            UPstream(commsType)
+        {}
+
+        //- Construct for communication type with given buffer size
+        Pstream(const UPstream::commsTypes commsType, int bufferSize)
         :
             UPstream(commsType)
         {
-            if (bufSize > 0)
+            if (bufferSize > 0)
             {
-                transferBuf_.setCapacity(bufSize + 2*sizeof(scalar) + 1);
+                transferBuf_.setCapacity(bufferSize + 2*sizeof(scalar) + 1);
             }
         }
 
@@ -104,13 +106,27 @@ public:
         static void broadcast
         (
             Type& value,
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
+        );
+
+        //- Broadcast fixed-list content (contiguous or non-contiguous) to all
+        //- communicator ranks. Does nothing in \b non-parallel.
+        template<class Type, unsigned N>
+        static void broadcast
+        (
+            FixedList<Type, N>& list,
+            const int communicator = UPstream::worldComm
         );
 
         //- Broadcast multiple items to all communicator ranks.
         //- Does nothing in \b non-parallel.
         template<class Type, class... Args>
-        static void broadcasts(const label comm, Type& arg1, Args&&... args);
+        static void broadcasts
+        (
+            const int communicator,
+            Type& value,
+            Args&&... values
+        );
 
         //- Broadcast list content (contiguous or non-contiguous) to all
         //- communicator ranks. Does nothing in \b non-parallel.
@@ -120,7 +136,7 @@ public:
         static void broadcastList
         (
             ListType& list,
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
 
@@ -134,7 +150,7 @@ public:
             const UPstream::commsStructList& comms,  //!< Communication order
             //! [in,out]
             T& value,
-            const BinaryOp& bop,
+            BinaryOp bop,
             const int tag,
             const int communicator
         );
@@ -150,9 +166,9 @@ public:
         (
             //! [in,out] the result is only reliable on rank=0
             T& value,
-            const BinaryOp& bop,
+            BinaryOp bop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Gather individual values into list locations.
@@ -164,7 +180,7 @@ public:
         static List<T> listGatherValues
         (
             const T& localValue,
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             //! Only used for non-contiguous types
             const int tag = UPstream::msgType()
         );
@@ -178,7 +194,7 @@ public:
         static T listScatterValues
         (
             const UList<T>& allValues,
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             //! Only used for non-contiguous types
             const int tag = UPstream::msgType()
         );
@@ -192,9 +208,9 @@ public:
         (
             //! [in,out] the result is only reliable on rank=0
             T& value,
-            const CombineOp& cop,
+            CombineOp cop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Reduce inplace (cf. MPI Allreduce)
@@ -205,9 +221,9 @@ public:
         (
             //! [in,out] the result is consistent on all ranks
             T& value,
-            const CombineOp& cop,
+            CombineOp cop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Same as Pstream::combineReduce
@@ -216,12 +232,12 @@ public:
         (
             //! [in,out] the result is consistent on all ranks
             T& value,
-            const CombineOp& cop,
+            CombineOp cop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         )
         {
-            Pstream::combineReduce(value, cop, tag, comm);
+            Pstream::combineReduce(value, cop, tag, communicator);
         }
 
 
@@ -235,7 +251,7 @@ public:
             const UPstream::commsStructList& comms,  //!< Communication order
             //! [in,out]
             UList<T>& values,
-            const BinaryOp& bop,
+            BinaryOp bop,
             const int tag,
             const int communicator
         );
@@ -250,9 +266,9 @@ public:
         (
             //! [in,out] the result is only reliable on rank=0
             UList<T>& values,
-            const BinaryOp& bop,
+            BinaryOp bop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Forwards to Pstream::listGather with an \em in-place \c cop
@@ -261,9 +277,9 @@ public:
         (
             //! [in,out] the result is only reliable on rank=0
             UList<T>& values,
-            const CombineOp& cop,
+            CombineOp cop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Reduce list elements (list must be equal size on all ranks),
@@ -276,9 +292,9 @@ public:
         (
             //! [in,out] the result is consistent on all ranks
             UList<T>& values,
-            const BinaryOp& bop,
+            BinaryOp bop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Forwards to Pstream::listReduce with an \em in-place \c cop
@@ -287,9 +303,9 @@ public:
         (
             //! [in,out] the result is consistent on all ranks
             UList<T>& values,
-            const CombineOp& cop,
+            CombineOp cop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Same as Pstream::listCombineReduce
@@ -298,12 +314,12 @@ public:
         (
             //! [in,out] the result is consistent on all ranks
             UList<T>& values,
-            const CombineOp& cop,
+            CombineOp cop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         )
         {
-            Pstream::listCombineReduce(values, cop, tag, comm);
+            Pstream::listCombineReduce(values, cop, tag, communicator);
         }
 
 
@@ -316,7 +332,7 @@ public:
         (
             const UPstream::commsStructList& comms,  //!< Communication order
             Container& values,
-            const BinaryOp& bop,
+            BinaryOp bop,
             const int tag,
             const int communicator
         );
@@ -331,9 +347,9 @@ public:
         (
             //! [in,out] the result is only reliable on rank=0
             Container& values,
-            const BinaryOp& bop,
+            BinaryOp bop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Forwards to Pstream::mapGather with an \em in-place \c cop
@@ -342,9 +358,9 @@ public:
         (
             //! [in,out] the result is only reliable on rank=0
             Container& values,
-            const CombineOp& cop,
+            CombineOp cop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Reduce inplace (cf. MPI Allreduce)
@@ -358,9 +374,9 @@ public:
         (
             //! [in,out] the result is consistent on all ranks
             Container& values,
-            const BinaryOp& bop,
+            BinaryOp bop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Forwards to Pstream::mapReduce with an \em in-place \c cop
@@ -369,9 +385,9 @@ public:
         (
             //! [in,out] the result is consistent on all ranks
             Container& values,
-            const CombineOp& cop,
+            CombineOp cop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Same as Pstream::mapCombineReduce
@@ -380,12 +396,12 @@ public:
         (
             //! [in,out] the result is consistent on all ranks
             Container& values,
-            const CombineOp& cop,
+            CombineOp cop,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         )
         {
-            Pstream::mapCombineReduce(values, cop, tag, comm);
+            Pstream::mapCombineReduce(values, cop, tag, communicator);
         }
 
 
@@ -423,7 +439,7 @@ public:
             //! [in,out]
             UList<T>& values,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Gather data, but keep individual values separate.
@@ -436,7 +452,7 @@ public:
             //! [in,out]
             UList<T>& values,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
 
@@ -449,7 +465,7 @@ public:
             //! [in,out]
             UList<T>& values,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
+            const int communicator = UPstream::worldComm
         );
 
 
@@ -640,7 +656,7 @@ public:
         (
             T& value,
             const int tag = UPstream::msgType(),  //!< ignored
-            const label comm = UPstream::worldComm
+            const int comm = UPstream::worldComm
         )
         {
             Pstream::broadcast(value, comm);
@@ -653,7 +669,7 @@ public:
         (
             T& value,
             const int tag = UPstream::msgType(),  //!< ignored
-            const label comm = UPstream::worldComm
+            const int comm = UPstream::worldComm
         )
         {
             Pstream::broadcast(value, comm);
@@ -666,7 +682,7 @@ public:
         (
             List<T>& value,
             const int tag = UPstream::msgType(),  //!< ignored
-            const label comm = UPstream::worldComm
+            const int comm = UPstream::worldComm
         )
         {
             Pstream::broadcast(value, comm);
@@ -679,7 +695,7 @@ public:
         (
             Container& values,
             const int tag = UPstream::msgType(),  //!< ignored
-            const label comm = UPstream::worldComm
+            const int comm = UPstream::worldComm
         )
         {
             Pstream::broadcast(values, comm);
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBroadcast.txx b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBroadcast.txx
index 90c427ab506a83dfcddabe82ea86dd4c4e478fbf..447d2685447314565a2a1b968d9431cda79f10b1 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBroadcast.txx
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBroadcast.txx
@@ -25,110 +25,181 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "OPstream.H"
 #include "IPstream.H"
-#include "contiguous.H"
+#include "OPstream.H"
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::Pstream::broadcast(Type& value, const label comm)
+void Foam::Pstream::broadcast
+(
+    Type& value,
+    const int communicator
+)
 {
-    if constexpr (is_contiguous_v<Type>)
+    if (!UPstream::is_parallel(communicator))
+    {
+        return;
+    }
+    else if constexpr (is_contiguous_v<Type>)
     {
-        // Note: contains parallel guard internally
         UPstream::broadcast
         (
             reinterpret_cast<char*>(&value),
             sizeof(Type),
-            comm
+            communicator
         );
     }
-    else if (UPstream::is_parallel(comm))
+    else
+    {
+        if (UPstream::master(communicator))
+        {
+            OPBstream::send(value, communicator);
+        }
+        else
+        {
+            IPBstream::recv(value, communicator);
+        }
+    }
+}
+
+
+template<class Type, unsigned N>
+void Foam::Pstream::broadcast
+(
+    FixedList<Type, N>& list,
+    const int communicator
+)
+{
+    if (!UPstream::is_parallel(communicator))
+    {
+        return;
+    }
+    else if constexpr (is_contiguous_v<Type>)
+    {
+        // Size is known and identical on all ranks
+        UPstream::broadcast(list.data(), list.size(), communicator);
+    }
+    else
     {
-        if (UPstream::master(comm))
+        // Non-contiguous content - serialize it
+        if (UPstream::master(communicator))
         {
-            OPBstream os(comm);
-            os << value;
+            OPBstream::send(list, communicator);
         }
-        else  // UPstream::is_subrank(comm)
+        else
         {
-            IPBstream is(comm);
-            is >> value;
+            IPBstream::recv(list, communicator);
         }
     }
 }
 
 
 template<class Type, class... Args>
-void Foam::Pstream::broadcasts(const label comm, Type& arg1, Args&&... args)
+void Foam::Pstream::broadcasts
+(
+    const int communicator,
+    Type& value,
+    Args&&... values
+)
 {
-    if (UPstream::is_parallel(comm))
+    if (!UPstream::is_parallel(communicator))
+    {
+        return;
+    }
+    else if constexpr (!sizeof...(values) && is_contiguous_v<Type>)
+    {
+        // A single-value and contiguous
+        UPstream::broadcast(&value, 1, communicator);
+    }
+    else
     {
-        if (UPstream::master(comm))
+        // Non-contiguous data, or multiple data - needs serialization
+
+        if (UPstream::master(communicator))
         {
-            OPBstream os(comm);
-            Detail::outputLoop(os, arg1, std::forward<Args>(args)...);
+            OPBstream::sends
+            (
+                communicator,
+                value,
+                std::forward<Args>(values)...
+            );
         }
-        else  // UPstream::is_subrank(comm)
+        else
         {
-            IPBstream is(comm);
-            Detail::inputLoop(is, arg1, std::forward<Args>(args)...);
+            IPBstream::recvs
+            (
+                communicator,
+                value,
+                std::forward<Args>(values)...
+            );
         }
     }
 }
 
 
 template<class ListType>
-void Foam::Pstream::broadcastList(ListType& list, const label comm)
+void Foam::Pstream::broadcastList
+(
+    ListType& list,
+    const int communicator
+)
 {
-    if constexpr (is_contiguous_v<typename ListType::value_type>)
+    if (!UPstream::is_parallel(communicator))
+    {
+        return;
+    }
+    else if constexpr (is_contiguous_v<typename ListType::value_type>)
     {
         // List data are contiguous
         // 1. broadcast the size
         // 2. resize for receiver list
         // 3. broadcast contiguous contents
 
-        if (UPstream::is_parallel(comm))
-        {
-            label len(list.size());
+        label len(list.size());
 
-            UPstream::broadcast
-            (
-                reinterpret_cast<char*>(&len),
-                sizeof(label),
-                comm
-            );
-
-            if (UPstream::is_subrank(comm))
-            {
-                list.resize_nocopy(len);
-            }
+        UPstream::mpi_broadcast
+        (
+            reinterpret_cast<char*>(&len),
+            sizeof(label),
+            UPstream::dataTypes::type_byte,
+            communicator
+        );
 
-            if (len)
-            {
-                UPstream::broadcast
-                (
-                    list.data_bytes(),
-                    list.size_bytes(),
-                    comm
-                );
-            }
+        if (len)
+        {
+            // Only broadcast non-empty content
+            UPstream::broadcast(list.data(), list.size(), communicator);
         }
     }
-    else if (UPstream::is_parallel(comm))
+    else
     {
         // List data are non-contiguous - serialize/de-serialize
 
-        if (UPstream::master(comm))
+        if (UPstream::master(communicator))
         {
-            OPBstream os(comm);
-            os << list;
+            if (list.empty())
+            {
+                // Do not serialize if empty.
+                // Just broadcast zero-size in a form that IPBstream can expect
+                OPBstream::send(Foam::zero{}, communicator);
+            }
+            else
+            {
+                OPBstream::send(list, communicator);
+            }
         }
-        else  // UPstream::is_subrank(comm)
+        else
         {
-            IPBstream is(comm);
-            is >> list;
+            IPBstream is(communicator);
+            if (is.remaining() > 0)  // Received a non-empty buffer
+            {
+                is >> list;
+            }
+            else
+            {
+                list.clear();
+            }
         }
     }
 }
@@ -148,11 +219,11 @@ template<class Type>
 Type returnBroadcast
 (
     const Type& value,
-    const label comm = UPstream::worldComm
+    const int communicator = UPstream::worldComm
 )
 {
     Type work(value);
-    Pstream::broadcast(work, comm);
+    Pstream::broadcast(work, communicator);
     return work;
 }
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.C b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.C
index 391c094beace15fa281aef2584b4234df1a44691..5332f3cf895d099b73e758d36863ec0bc76f6901 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2021-2023 OpenCFD Ltd.
+    Copyright (C) 2021-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -300,7 +300,7 @@ Foam::PstreamBuffers::PstreamBuffers
 (
     UPstream::commsTypes commsType,
     int tag,
-    label communicator,
+    int communicator,
     IOstreamOption::streamFormat fmt
 )
 :
@@ -313,7 +313,7 @@ Foam::PstreamBuffers::PstreamBuffers
     nProcs_(UPstream::nProcs(comm_)),
     sendBuffers_(nProcs_),
     recvBuffers_(nProcs_),
-    recvPositions_(nProcs_, Zero)
+    recvPositions_(nProcs_, Foam::zero{})
 {
     DebugPoutInFunction
         << "tag:" << tag_
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.H b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.H
index 97cb68fe9acb624bb1d0814520c64f39effc8a03..d80607d37996d8158c548aee22ee90502c9a7087 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2021-2023 OpenCFD Ltd.
+    Copyright (C) 2021-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -182,10 +182,10 @@ class PstreamBuffers
         const int tag_;
 
         //- Communicator
-        const label comm_;
+        const int comm_;
 
         //- Number of ranks associated with PstreamBuffers (at construction)
-        const label nProcs_;
+        const int nProcs_;
 
 
     // Buffer storage
@@ -266,7 +266,7 @@ public:
         (
             UPstream::commsTypes commsType = UPstream::commsTypes::nonBlocking,
             int tag = UPstream::msgType(),
-            label communicator = UPstream::worldComm,
+            int communicator = UPstream::worldComm,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
 
@@ -274,7 +274,7 @@ public:
         //- (default: nonBlocking), message tag, IO format (default: binary)
         explicit PstreamBuffers
         (
-            label communicator,
+            int communicator,
             UPstream::commsTypes commsType = UPstream::commsTypes::nonBlocking,
             int tag = UPstream::msgType(),
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
@@ -287,7 +287,7 @@ public:
         //- (default: nonBlocking), IO format (default: binary)
         PstreamBuffers
         (
-            label communicator,
+            int communicator,
             int tag,
             UPstream::commsTypes commsType = UPstream::commsTypes::nonBlocking,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
@@ -306,34 +306,19 @@ public:
     // Attributes
 
         //- The associated buffer format (ascii | binary)
-        IOstreamOption::streamFormat format() const noexcept
-        {
-            return format_;
-        }
+        IOstreamOption::streamFormat format() const noexcept { return format_; }
 
         //- The communications type of the stream
-        UPstream::commsTypes commsType() const noexcept
-        {
-            return commsType_;
-        }
+        UPstream::commsTypes commsType() const noexcept { return commsType_; }
 
         //- The transfer message tag
-        int tag() const noexcept
-        {
-            return tag_;
-        }
+        int tag() const noexcept { return tag_; }
 
         //- The communicator index
-        label comm() const noexcept
-        {
-            return comm_;
-        }
+        int comm() const noexcept { return comm_; }
 
         //- Number of ranks associated with PstreamBuffers
-        label nProcs() const noexcept
-        {
-            return nProcs_;
-        }
+        int nProcs() const noexcept { return nProcs_; }
 
 
     // Sizing
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGather.txx b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGather.txx
index 8aa66bb79511697ac7c33eb7c1422539e328782a..3b5e34c9739690489a92e56733048a444f67a254 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGather.txx
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGather.txx
@@ -53,7 +53,7 @@ void Foam::Pstream::gather_algorithm
 (
     const UPstream::commsStructList& comms,  // Communication order
     T& value,
-    const BinaryOp& bop,
+    BinaryOp bop,
     const int tag,
     const int communicator
 )
@@ -151,9 +151,9 @@ template<class T, class BinaryOp, bool InplaceMode>
 void Foam::Pstream::gather
 (
     T& value,
-    const BinaryOp& bop,
-    const int tag,
-    const label communicator
+    [[maybe_unused]] BinaryOp bop,
+    [[maybe_unused]] const int tag,
+    const int communicator
 )
 {
     if (!UPstream::is_parallel(communicator))
@@ -161,6 +161,17 @@ void Foam::Pstream::gather
         // Nothing to do
         return;
     }
+    else if constexpr (!InplaceMode && UPstream_data_opType<BinaryOp, T>::value)
+    {
+        // Valid opcode and (directly/indirectly) uses basic dataType
+        UPstream::mpiReduce
+        (
+            &value,
+            1,
+            UPstream_opType<BinaryOp>::opcode_id,
+            communicator
+        );
+    }
     else
     {
         // Communication order
@@ -182,9 +193,9 @@ template<class T, class CombineOp>
 void Foam::Pstream::combineGather
 (
     T& value,
-    const CombineOp& cop,
+    CombineOp cop,
     const int tag,
-    const label comm
+    const int comm
 )
 {
     // In-place binary operation
@@ -196,9 +207,9 @@ template<class T, class CombineOp>
 void Foam::Pstream::combineReduce
 (
     T& value,
-    const CombineOp& cop,
+    CombineOp cop,
     const int tag,
-    const label comm
+    const int comm
 )
 {
     if (UPstream::is_parallel(comm))
@@ -219,7 +230,7 @@ void Foam::Pstream::listGather_algorithm
 (
     const UPstream::commsStructList& comms,  // Communication order
     UList<T>& values,
-    const BinaryOp& bop,
+    BinaryOp bop,
     const int tag,
     const int communicator
 )
@@ -330,9 +341,9 @@ template<class T, class BinaryOp, bool InplaceMode>
 void Foam::Pstream::listGather
 (
     UList<T>& values,
-    const BinaryOp& bop,
-    const int tag,
-    const label communicator
+    [[maybe_unused]] BinaryOp bop,
+    [[maybe_unused]] const int tag,
+    const int communicator
 )
 {
     if (!UPstream::is_parallel(communicator) || values.empty())
@@ -340,6 +351,17 @@ void Foam::Pstream::listGather
         // Nothing to do
         return;
     }
+    else if constexpr (!InplaceMode && UPstream_data_opType<BinaryOp, T>::value)
+    {
+        // Valid opcode and (directly/indirectly) uses basic dataType
+        UPstream::mpiReduce
+        (
+            values.data(),
+            values.size(),  // Same length on all ranks
+            UPstream_opType<BinaryOp>::opcode_id,
+            communicator
+        );
+    }
     else if (values.size() == 1)
     {
         // Single value - optimized version
@@ -372,15 +394,26 @@ template<class T, class BinaryOp, bool InplaceMode>
 void Foam::Pstream::listReduce
 (
     UList<T>& values,
-    const BinaryOp& bop,
-    const int tag,
-    const label comm
+    [[maybe_unused]] BinaryOp bop,
+    [[maybe_unused]] const int tag,
+    const int comm
 )
 {
     if (!UPstream::is_parallel(comm) || values.empty())
     {
         // Nothing to do
     }
+    else if constexpr (!InplaceMode && UPstream_data_opType<BinaryOp, T>::value)
+    {
+        // Valid opcode and (directly/indirectly) uses basic dataType
+        UPstream::mpiAllReduce
+        (
+            values.data(),
+            values.size(),  // Same length on all ranks
+            UPstream_opType<BinaryOp>::opcode_id,
+            comm
+        );
+    }
     else if (values.size() == 1)
     {
         // Single value - optimized version
@@ -400,9 +433,9 @@ template<class T, class CombineOp>
 void Foam::Pstream::listCombineGather
 (
     UList<T>& values,
-    const CombineOp& cop,
+    CombineOp cop,
     const int tag,
-    const label comm
+    const int comm
 )
 {
     // In-place binary operation
@@ -414,9 +447,9 @@ template<class T, class CombineOp>
 void Foam::Pstream::listCombineReduce
 (
     UList<T>& values,
-    const CombineOp& cop,
+    CombineOp cop,
     const int tag,
-    const label comm
+    const int comm
 )
 {
     // In-place binary operation
@@ -433,7 +466,7 @@ void Foam::Pstream::mapGather_algorithm
 (
     const UPstream::commsStructList& comms,  // Communication order
     Container& values,
-    const BinaryOp& bop,
+    BinaryOp bop,
     const int tag,
     const int communicator
 )
@@ -519,9 +552,9 @@ template<class Container, class BinaryOp, bool InplaceMode>
 void Foam::Pstream::mapGather
 (
     Container& values,
-    const BinaryOp& bop,
+    BinaryOp bop,
     const int tag,
-    const label communicator
+    const int communicator
 )
 {
     if (!UPstream::is_parallel(communicator))
@@ -550,9 +583,9 @@ template<class Container, class BinaryOp, bool InplaceMode>
 void Foam::Pstream::mapReduce
 (
     Container& values,
-    const BinaryOp& bop,
+    BinaryOp bop,
     const int tag,
-    const label comm
+    const int comm
 )
 {
     Pstream::mapGather<Container, BinaryOp, InplaceMode>
@@ -567,9 +600,9 @@ template<class Container, class CombineOp>
 void Foam::Pstream::mapCombineGather
 (
     Container& values,
-    const CombineOp& cop,
+    CombineOp cop,
     const int tag,
-    const label comm
+    const int comm
 )
 {
     // In-place binary operation
@@ -584,9 +617,9 @@ template<class Container, class CombineOp>
 void Foam::Pstream::mapCombineReduce
 (
     Container& values,
-    const CombineOp& cop,
+    CombineOp cop,
     const int tag,
-    const label comm
+    const int comm
 )
 {
     // In-place binary operation
@@ -605,7 +638,7 @@ template<class T>
 Foam::List<T> Foam::Pstream::listGatherValues
 (
     const T& localValue,
-    const label communicator,
+    const int communicator,
     [[maybe_unused]] const int tag
 )
 {
@@ -658,7 +691,7 @@ template<class T>
 T Foam::Pstream::listScatterValues
 (
     const UList<T>& allValues,
-    const label communicator,
+    const int communicator,
     [[maybe_unused]] const int tag
 )
 {
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGatherList.txx b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGatherList.txx
index a77c13bda68ccfe9094c9f66a320e5d81595750a..5a3de56ad5db344fba09a4a6a691cfa3a9c16294 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGatherList.txx
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGatherList.txx
@@ -415,7 +415,7 @@ void Foam::Pstream::gatherList
 (
     UList<T>& values,
     [[maybe_unused]] const int tag,
-    const label communicator
+    const int communicator
 )
 {
     if (!UPstream::is_parallel(communicator))
@@ -433,14 +433,8 @@ void Foam::Pstream::gatherList
                 << Foam::abort(FatalError);
         }
 
-        // In-place gather for contiguous types
-        UPstream::mpiGather
-        (
-            nullptr,
-            values.data_bytes(),
-            sizeof(T),
-            communicator
-        );
+        // In-place gather for contiguous types - one element per rank
+        UPstream::mpiGather(nullptr, values.data(), 1, communicator);
     }
     else
     {
@@ -457,7 +451,7 @@ void Foam::Pstream::scatterList
 (
     UList<T>& values,
     [[maybe_unused]] const int tag,
-    const label communicator
+    const int communicator
 )
 {
     if (!UPstream::is_parallel(communicator))
@@ -467,14 +461,8 @@ void Foam::Pstream::scatterList
     }
     else if constexpr (is_contiguous_v<T>)
     {
-        // In-place scatter for contiguous types
-        UPstream::mpiScatter
-        (
-            nullptr,
-            values.data_bytes(),
-            sizeof(T),
-            communicator
-        );
+        // In-place scatter for contiguous types - one element per rank
+        UPstream::mpiScatter(nullptr, values.data(), 1, communicator);
     }
     else
     {
@@ -491,33 +479,34 @@ void Foam::Pstream::allGatherList
 (
     UList<T>& values,
     [[maybe_unused]] const int tag,
-    const label comm
+    const int communicator
 )
 {
-    if (!UPstream::is_parallel(comm))
+    if (!UPstream::is_parallel(communicator))
     {
         // Nothing to do
         return;
     }
     else if constexpr (is_contiguous_v<T>)
     {
-        if (FOAM_UNLIKELY(values.size() < UPstream::nProcs(comm)))
+        if (FOAM_UNLIKELY(values.size() < UPstream::nProcs(communicator)))
         {
             FatalErrorInFunction
                 << "List of values is too small:" << values.size()
-                << " vs numProcs:" << UPstream::nProcs(comm) << nl
+                << " vs numProcs:" << UPstream::nProcs(communicator) << nl
                 << Foam::abort(FatalError);
         }
 
-        UPstream::mpiAllGather(values.data_bytes(), sizeof(T), comm);
+        // Allgather for contiguous types - one element per rank
+        UPstream::mpiAllGather(values.data(), 1, communicator);
     }
     else
     {
         // Communication order
-        const auto& commOrder = UPstream::whichCommunication(comm);
+        const auto& commOrder = UPstream::whichCommunication(communicator);
 
-        Pstream::gatherList_algorithm(commOrder, values, tag, comm);
-        Pstream::scatterList_algorithm(commOrder, values, tag, comm);
+        Pstream::gatherList_algorithm(commOrder, values, tag, communicator);
+        Pstream::scatterList_algorithm(commOrder, values, tag, communicator);
     }
 }
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamReduceOps.H b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamReduceOps.H
index 93a1e4b8e4b1743028728482606f6aca55df2f0c..c13757d3c30d58bcab745358b08ad3e4639bb0bd 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamReduceOps.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamReduceOps.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2016-2024 OpenCFD Ltd.
+    Copyright (C) 2016-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -38,6 +38,7 @@ Description
 #include "Pstream.H"
 #include "FixedList.H"
 #include "ops.H"
+#include "VectorSpaceOps.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -46,74 +47,160 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+// Single value: mpiAllReduce or manual
+
 //- Reduce inplace (cf. MPI Allreduce)
-//- using linear/tree communication schedule
 template<class T, class BinaryOp>
 void reduce
 (
     T& value,
-    const BinaryOp& bop,
-    const int tag = UPstream::msgType(),
-    const label comm = UPstream::worldComm
+    [[maybe_unused]] BinaryOp bop,
+    [[maybe_unused]] const int tag = UPstream::msgType(),
+    const int communicator = UPstream::worldComm
 )
 {
-    if (UPstream::is_parallel(comm))
+    if (!UPstream::is_parallel(communicator))
+    {
+        // Nothing to do
+        return;
+    }
+    else if constexpr (UPstream_data_opType<BinaryOp, T>::value)
+    {
+        // Valid opcode and (directly/indirectly) uses basic dataType
+        UPstream::mpiAllReduce
+        (
+            &value,
+            1,
+            UPstream_opType<BinaryOp>::opcode_id,
+            communicator
+        );
+    }
+    else
     {
-        if (UPstream::warnComm >= 0 && comm != UPstream::warnComm)
+        if (UPstream::warnComm >= 0 && communicator != UPstream::warnComm)
         {
-            Perr<< "** reducing:" << value << " with comm:" << comm << endl;
+            Perr<< "** reducing:" << value << " comm:" << communicator << endl;
             error::printStack(Perr);
         }
-        Pstream::gather(value, bop, tag, comm);
-        Pstream::broadcast(value, comm);
+        Pstream::gather(value, bop, tag, communicator);
+        Pstream::broadcast(value, communicator);
     }
 }
 
 
+// Multiple values: mpiAllReduce only!
+
 //- Reduce inplace (cf. MPI Allreduce)
 //- multiple values (same size on all ranks!)
 template<class T, class BinaryOp>
 void reduce
 (
     T values[],
-    const int size,
-    const BinaryOp&,
-    const int tag,
-    const label comm
+    const int count,
+    [[maybe_unused]] BinaryOp bop,
+    [[maybe_unused]] const int tag,
+    const int communicator = UPstream::worldComm
+)
+{
+    if (!UPstream::is_parallel(communicator))
+    {
+        // Nothing to do
+        return;
+    }
+    else if constexpr (UPstream_data_opType<BinaryOp, T>::value)
+    {
+        // Valid opcode and (directly/indirectly) uses basic dataType
+        UPstream::mpiAllReduce
+        (
+            values,
+            count,
+            UPstream_opType<BinaryOp>::opcode_id,
+            communicator
+        );
+    }
+    else
+    {
+        // static_assert(false, "unsupported data type");
+        static_assert
+        (
+            stdFoam::dependent_false_v<T>,
+            "only for specific, contiguous, known data types"
+        );
+    }
+}
+
+
+//- Reduce multiple values
+//  Multiple values: mpiAllReduce only!
+template<class T, unsigned N, class BinaryOp>
+inline void reduce
+(
+    FixedList<T, N>& values,
+    BinaryOp bop,
+    const int tag = UPstream::msgType(),
+    const int communicator = UPstream::worldComm
 )
 {
-    NotImplemented;
+    reduce(values.data(), int(values.size()), bop, tag, communicator);
 }
 
+
 //- Non-blocking reduce inplace (cf. MPI Iallreduce)
-//- single value. Sets request.
+//- multiple values. Sets request.
 template<class T, class BinaryOp>
 void reduce
 (
-    T& Value,
-    const BinaryOp&,
-    const int tag,
-    const label comm,
+    T values[],
+    int count,
+    [[maybe_unused]] BinaryOp bop,
+    [[maybe_unused]] const int tag,
+    const int communicator,
     UPstream::Request& req
 )
 {
-    NotImplemented;
+    if (!UPstream::is_parallel(communicator))
+    {
+        // Nothing to do
+        return;
+    }
+    else if constexpr (UPstream_data_opType<BinaryOp, T>::value)
+    {
+        // Valid opcode and (directly/indirectly) uses basic dataType
+        UPstream::mpiAllReduce
+        (
+            values,
+            count,
+            UPstream_opType<BinaryOp>::opcode_id,
+            communicator,
+            req
+        );
+    }
+    else
+    {
+        // static_assert(false, "unsupported data type");
+        static_assert
+        (
+            stdFoam::dependent_false_v<T>,
+            "only for specific, contiguous, known data types"
+        );
+    }
 }
 
+
 //- Non-blocking reduce inplace (cf. MPI Iallreduce)
-//- of multiple values (same size on all ranks!). Sets request.
+//- single value. Sets request.
 template<class T, class BinaryOp>
 void reduce
 (
-    T values[],
-    const int size,
-    const BinaryOp&,
+    T& value,
+    BinaryOp bop,
     const int tag,
-    const label comm,
+    const int communicator,
     UPstream::Request& req
 )
 {
-    NotImplemented;
+    // single value
+    reduce(&value, 1, tag, communicator, req);
 }
 
 
@@ -125,245 +212,97 @@ void reduce
 void reduce
 (
     bool& value,
-    const andOp<bool>&,
-    const int tag = UPstream::msgType(),  /*!< (ignored) */
-    const label comm = UPstream::worldComm
+    Foam::andOp<bool>,
+    [[maybe_unused]] const int tag = UPstream::msgType(),  /*!< (ignored) */
+    const int communicator = UPstream::worldComm
 );
+// UPstream::reduceAnd(value, communicator);
+
 
 //- Logical (or) inplace reduction. Uses UPstream::reduceOr
 void reduce
 (
     bool& value,
-    const orOp<bool>&,
-    const int tag = UPstream::msgType(),  /*!< (ignored) */
-    const label comm = UPstream::worldComm
+    Foam::orOp<bool>,
+    [[maybe_unused]] const int tag = UPstream::msgType(),  /*!< (ignored) */
+    const int communicator = UPstream::worldComm
 );
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Common reductions
-
-#undef  Pstream_CommonReductions
-#define Pstream_CommonReductions(Native)                                      \
-                                                                              \
-/*! \brief Reduce (min) multiple Native values (same size on all ranks!) */   \
-void reduce                                                                   \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const minOp<Native>&,                                                     \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-);                                                                            \
-                                                                              \
-/*! \brief Reduce (min) single Native value */                                \
-void reduce                                                                   \
-(                                                                             \
-    Native& value,                                                            \
-    const minOp<Native>&,                                                     \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-);                                                                            \
-                                                                              \
-/*! \brief Reduce (min) multiple Native values */                             \
-template<unsigned N>                                                          \
-inline void reduce                                                            \
-(                                                                             \
-    FixedList<Native, N>& values,                                             \
-    const minOp<Native>&,                                                     \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-)                                                                             \
-{                                                                             \
-    reduce(values.data(), int(values.size()), minOp<Native>(), tag, comm);    \
-}                                                                             \
-                                                                              \
-/*! \brief Reduce (max) multiple Native values (same size on all ranks!) */   \
-void reduce                                                                   \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const maxOp<Native>&,                                                     \
-    const int tag,  /*!< (ignored) */                                         \
-    const label comm                                                          \
-);                                                                            \
-                                                                              \
-/*! \brief Reduce (max) single Native value */                                \
-void reduce                                                                   \
-(                                                                             \
-    Native& value,                                                            \
-    const maxOp<Native>&,                                                     \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-);                                                                            \
-                                                                              \
-/*! \brief Reduce (max) multiple Native values */                             \
-template<unsigned N>                                                          \
-inline void reduce                                                            \
-(                                                                             \
-    FixedList<Native, N>& values,                                             \
-    const maxOp<Native>&,                                                     \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-)                                                                             \
-{                                                                             \
-    reduce(values.data(), int(values.size()), maxOp<Native>(), tag, comm);    \
-}                                                                             \
-                                                                              \
-/*! \brief Reduce (sum) multiple Native values (same size on all ranks!) */   \
-void reduce                                                                   \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const sumOp<Native>&,                                                     \
-    const int tag,  /*!< (ignored) */                                         \
-    const label comm                                                          \
-);                                                                            \
-                                                                              \
-/*! \brief Reduce (sum) single Native value */                                \
-void reduce                                                                   \
-(                                                                             \
-    Native& value,                                                            \
-    const sumOp<Native>&,                                                     \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-);                                                                            \
-                                                                              \
-/*! \brief Reduce (sum) multiple Native values */                             \
-template<unsigned N>                                                          \
-inline void reduce                                                            \
-(                                                                             \
-    FixedList<Native, N>& values,                                             \
-    const sumOp<Native>&,                                                     \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-)                                                                             \
-{                                                                             \
-    reduce(values.data(), int(values.size()), sumOp<Native>(), tag, comm);    \
-}
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Floating-point reductions
-
-#undef  Pstream_FloatReductions
-#define Pstream_FloatReductions(Native)                                       \
-                                                                              \
-Pstream_CommonReductions(Native);                                             \
-                                                                              \
-/*! \brief Non-blocking reduce (sum) multiple Native values. Sets request */  \
-void reduce                                                                   \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const sumOp<Native>&,                                                     \
-    const int tag,  /*!< (ignored) */                                         \
-    const label comm,                                                         \
-    UPstream::Request& req  /*!< [out] request information */                 \
-);                                                                            \
-                                                                              \
-/*! \brief Non-blocking reduce (sum) single Native value. Sets request */     \
-void reduce                                                                   \
-(                                                                             \
-    Native& value,                                                            \
-    const sumOp<Native>&,                                                     \
-    const int tag,  /*!< (ignored) */                                         \
-    const label comm,                                                         \
-    UPstream::Request& req  /*!< [out] request information */                 \
-);
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Bitwise reductions
-
-#undef  Pstream_BitwiseReductions
-#define Pstream_BitwiseReductions(Native)                                     \
-                                                                              \
-/*! \brief Reduce (bit-or) multiple Native values (same size on all ranks!)*/ \
-void reduce                                                                   \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const bitOrOp<Native>&,                                                   \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-);                                                                            \
-                                                                              \
-/*! \brief Reduce (bit-or) single Native value */                             \
-void reduce                                                                   \
-(                                                                             \
-    Native& value,                                                            \
-    const bitOrOp<Native>&,                                                   \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-);
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-Pstream_CommonReductions(int32_t);
-Pstream_CommonReductions(int64_t);
-Pstream_CommonReductions(uint32_t);
-Pstream_CommonReductions(uint64_t);
-
-Pstream_FloatReductions(float);
-Pstream_FloatReductions(double);
-
-Pstream_BitwiseReductions(unsigned char);
-Pstream_BitwiseReductions(unsigned int);
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#undef Pstream_CommonReductions
-#undef Pstream_FloatReductions
-#undef Pstream_BitwiseReductions
+// UPstream::reduceOr(value, communicator);
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 //- Reduce inplace (cf. MPI Allreduce)
 //- the sum of both value and count (for averaging)
-template<class T>
+template<class T, class IntType = int>
 void sumReduce
 (
     T& value,
-    label& count,
-    const int tag = UPstream::msgType(),
-    const label comm = UPstream::worldComm
+    IntType& count,
+    [[maybe_unused]] const int tag = UPstream::msgType(),
+    const int communicator = UPstream::worldComm
 )
 {
-    if (UPstream::is_parallel(comm))
+    static_assert(std::is_arithmetic_v<IntType>, "Counter not arithmetic");
+
+    if (!UPstream::is_parallel(communicator))
+    {
+        // Nothing to do
+        return;
+    }
+    else if constexpr (std::is_floating_point_v<T>)
+    {
+        // Bundle value and count together
+        T work[2];
+        work[0] = value;
+        work[1] = static_cast<T>(count);
+
+        UPstream::mpiAllReduce
+        (
+            work,
+            2,
+            UPstream::opCodes::op_sum,
+            communicator
+        );
+
+        // Unbundle
+        value = work[0];
+        count = static_cast<IntType>(work[1]);
+    }
+    else if constexpr
+    (
+        is_vectorspace_v<T>
+     && std::is_floating_point_v<typename pTraits_cmptType<T>::type>
+    )
     {
-        Foam::reduce(value, sumOp<T>(), tag, comm);
-        Foam::reduce(count, sumOp<label>(), tag, comm);
+        constexpr auto nCmpts = pTraits_nComponents<T>::value;
+        using cmpt = typename pTraits_cmptType<T>::type;
+
+        // Bundle all components and count together
+        cmpt work[nCmpts+1];
+        VectorSpaceOps<nCmpts>::copy_n(value.begin(), work);
+        work[nCmpts] = static_cast<cmpt>(count);
+
+        UPstream::mpiAllReduce
+        (
+            work,
+            nCmpts+1,
+            UPstream::opCodes::op_sum,
+            communicator
+        );
+
+        // Unbundle
+        VectorSpaceOps<nCmpts>::copy_n(work, value.begin());
+        count = static_cast<IntType>(work[nCmpts]);
+    }
+    else
+    {
+        Foam::reduce(value, sumOp<T>(), tag, communicator);
+        Foam::reduce(count, sumOp<IntType>(), tag, communicator);
     }
 }
 
 
-// Floating-point sum-reduce
-
-#undef  Pstream_SumReduce
-#define Pstream_SumReduce(Native)                                             \
-                                                                              \
-/*! \brief Sum of both Native value and count (for averaging) */              \
-void sumReduce                                                                \
-(                                                                             \
-    Native& value,                                                            \
-    label& count,                                                             \
-    const int tag = UPstream::msgType(),  /*!< (ignored) */                   \
-    const label comm = UPstream::worldComm                                    \
-);
-
-
-Pstream_SumReduce(float);
-Pstream_SumReduce(double);
-
-#undef Pstream_SumReduce
-
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 // Convenience wrappers - defined after all specialisations are known
@@ -374,13 +313,13 @@ template<class T, class BinaryOp>
 T returnReduce
 (
     const T& value,
-    const BinaryOp& bop,
+    BinaryOp bop,
     const int tag = UPstream::msgType(),
-    const label comm = UPstream::worldComm
+    const int communicator = UPstream::worldComm
 )
 {
     T work(value);
-    Foam::reduce(work, bop, tag, comm);
+    Foam::reduce(work, bop, tag, communicator);
     return work;
 }
 
@@ -390,11 +329,11 @@ T returnReduce
 inline bool returnReduceAnd
 (
     const bool value,
-    const label comm = UPstream::worldComm
+    const int communicator = UPstream::worldComm
 )
 {
     bool work(value);
-    UPstream::reduceAnd(work, comm);
+    UPstream::reduceAnd(work, communicator);
     return work;
 }
 
@@ -404,11 +343,11 @@ inline bool returnReduceAnd
 inline bool returnReduceOr
 (
     const bool value,
-    const label comm = UPstream::worldComm
+    const int communicator = UPstream::worldComm
 )
 {
     bool work(value);
-    UPstream::reduceOr(work, comm);
+    UPstream::reduceOr(work, communicator);
     return work;
 }
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H
index eb2deb9a87dcae6e911b360b36dabc77804d1797..42ecd8f1d6c2aa05411400f93b83703b39c2476e 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2013 OpenFOAM Foundation
-    Copyright (C) 2017-2024 OpenCFD Ltd.
+    Copyright (C) 2017-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -33,6 +33,7 @@ Description
     Not to be used directly, thus contructors are protected.
 
 SourceFiles
+    UIPstream.txx
     UIPstreamBase.C
 
 \*---------------------------------------------------------------------------*/
@@ -124,7 +125,7 @@ protected:
             DynamicList<char>& receiveBuf,
             label& receiveBufPosition,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             const bool clearAtEnd = false,   // destroy receiveBuf if at end
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
@@ -165,6 +166,9 @@ public:
             return std::ios_base::fmtflags(0);
         }
 
+        //- The number of characters remaining in the get buffer
+        label remaining() const noexcept;
+
 
     // Read Functions
 
@@ -249,7 +253,7 @@ public:
             DynamicList<char>& receiveBuf,
             label& receiveBufPosition,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             const bool clearAtEnd = false,   // destroy receiveBuf if at end
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
@@ -280,48 +284,36 @@ public:
 
     // Static Functions
 
-        //- Read buffer contents from given processor.
-        //  \return the message size (bytes read). May change in the future
+        //- Receive buffer contents (contiguous types) from given processor.
+        //  \return the message size (elements read). May change in the future
+        template<class Type>
         static std::streamsize read
         (
             const UPstream::commsTypes commsType,
             const int fromProcNo,
-            char* buf,
-            const std::streamsize bufSize,
+            Type* buffer,
+            std::streamsize count,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             //! [out] request information (for non-blocking)
             UPstream::Request* req = nullptr
         );
 
-        //- Read buffer contents (non-blocking) from given processor.
-        //  \return the message size (bytes read). May change in the future
+        //- Read buffer contents (non-blocking) from given processor
+        //  \return number of elements read. May change in the future
+        template<class Type>
         inline static std::streamsize read
         (
             //! [out] request information
             UPstream::Request& req,
             const int fromProcNo,
-            char* buf,
-            const std::streamsize bufSize,
+            Type* buffer,
+            std::streamsize count,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
-        )
-        {
-            return UIPstream::read
-            (
-                UPstream::commsTypes::nonBlocking,
-                fromProcNo,
-                buf,
-                bufSize,
-                tag,
-                comm,
-               &req
-            );
-        }
+            const int communicator = UPstream::worldComm
+        );
 
-        //- Read into UList storage from given processor.
-        //  Only valid for contiguous data types.
-        //  \return the message size (bytes read). May change in the future
+        //- Receive into UList storage from given processor.
         template<class Type>
         inline static std::streamsize read
         (
@@ -329,26 +321,12 @@ public:
             const int fromProcNo,
             UList<Type>& buffer,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             //! [out] request information (for non-blocking)
             UPstream::Request* req = nullptr
-        )
-        {
-            return UIPstream::read
-            (
-                commsType,
-                fromProcNo,
-                buffer.data_bytes(),
-                buffer.size_bytes(),
-                tag,
-                comm,
-                req
-            );
-        }
+        );
 
-        //- Read into SubList storage from given processor.
-        //  Only valid for contiguous data types.
-        //  \return the message size (bytes read). May change in the future
+        //- Receive into SubList storage from given processor.
         template<class Type>
         inline static std::streamsize read
         (
@@ -356,26 +334,12 @@ public:
             const int fromProcNo,
             SubList<Type> buffer,  // passed by shallow copy
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             //! [out] request information (for non-blocking)
             UPstream::Request* req = nullptr
-        )
-        {
-            return UIPstream::read
-            (
-                commsType,
-                fromProcNo,
-                buffer.data_bytes(),
-                buffer.size_bytes(),
-                tag,
-                comm,
-                req
-            );
-        }
+        );
 
-        //- Read into UList storage (non-blocking) from given processor.
-        //  Only valid for contiguous data types.
-        //  \return the message size (bytes read). May change in the future
+        //- Receive into UList storage (non-blocking) from given processor.
         template<class Type>
         inline static std::streamsize read
         (
@@ -384,24 +348,10 @@ public:
             const int fromProcNo,
             UList<Type>& buffer,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
-        )
-        {
-            return UIPstream::read
-            (
-                UPstream::commsTypes::nonBlocking,
-                fromProcNo,
-                buffer.data_bytes(),
-                buffer.size_bytes(),
-                tag,
-                comm,
-               &req
-            );
-        }
+            const int communicator = UPstream::worldComm
+        );
 
-        //- Read into SubList storage (non-blocking) from given processor.
-        //  Only valid for contiguous data types.
-        //  \return the message size (bytes read). May change in the future
+        //- Receive into SubList storage (non-blocking) from given processor.
         template<class Type>
         inline static std::streamsize read
         (
@@ -410,20 +360,8 @@ public:
             const int fromProcNo,
             SubList<Type> buffer,  // passed by shallow copy
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm
-        )
-        {
-            return UIPstream::read
-            (
-                UPstream::commsTypes::nonBlocking,
-                fromProcNo,
-                buffer.data_bytes(),
-                buffer.size_bytes(),
-                tag,
-                comm,
-               &req
-            );
-        }
+            const int communicator = UPstream::worldComm
+        );
 };
 
 
@@ -447,17 +385,13 @@ public:
 
     // Constructors
 
-        //- Construct given process index to read from using the given
-        //- attached receive buffer, optional communication characteristics
-        //- and IO format
+        //- Construct using the given attached receive buffer,
+        // optional communication characteristics and IO format
         UIPBstream
         (
-            const UPstream::commsTypes,     //!< irrelevant
-            const int rootProcNo,           //!< normally UPstream::masterNo()
             DynamicList<char>& receiveBuf,
             label& receiveBufPosition,
-            const int tag = UPstream::msgType(),  //!< irrelevant
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             const bool clearAtEnd = false,  //!< destroy receiveBuf if at end
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
@@ -465,25 +399,6 @@ public:
 
     //- Destructor
     virtual ~UIPBstream() = default;
-
-
-    // Member Functions
-
-        //- Use all read methods from base
-        using UIPstreamBase::read;
-
-
-    // Static Functions
-
-        //- Wrapped version of UPstream::broadcast
-        //  \return the message size (bytes read). May change in the future
-        static std::streamsize read
-        (
-            const int rootProcNo,  //!< normally UPstream::masterNo()
-            char* buf,
-            const std::streamsize bufSize,
-            const label comm = UPstream::worldComm
-        );
 };
 
 
@@ -493,6 +408,12 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+#ifdef NoRepository
+    #include "UIPstream.txx"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 #endif
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.txx b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.txx
new file mode 100644
index 0000000000000000000000000000000000000000..4ee2044924e2bed6dc364738a9057d75b4c1dbb0
--- /dev/null
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.txx
@@ -0,0 +1,187 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2025 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+template<class Type>
+std::streamsize Foam::UIPstream::read
+(
+    const UPstream::commsTypes commsType,
+    const int fromProcNo,
+    Type* buffer,
+    std::streamsize count,
+    const int tag,
+    const int communicator,
+    [[maybe_unused]] UPstream::Request* req
+)
+{
+    if constexpr (!is_contiguous_v<Type>)
+    {
+        // Report parameters to silence compiler warnings about unused
+        FatalErrorInFunction
+            << "Invalid for non-contiguous data types. "
+            << int(commsType) << ':' << fromProcNo
+            << ':' << (buffer != nullptr)
+            << ':' << count
+            << ':' << tag
+            << ':' << communicator
+            << Foam::abort(FatalError);
+        return 0;
+    }
+    else
+    {
+        // Use element or component type (or byte-wise) for data type
+        return UPstream::mpi_receive
+        (
+            commsType,
+            buffer,         // The data or cmpt pointer
+            UPstream_dataType<Type>::size(count),
+            UPstream_dataType<Type>::datatype_id,
+            fromProcNo,
+            tag,
+            communicator,
+            req
+        );
+    }
+}
+
+
+template<class Type>
+std::streamsize Foam::UIPstream::read
+(
+    UPstream::Request& req,
+    const int fromProcNo,
+    Type* buffer,
+    std::streamsize count,
+    const int tag,
+    const int communicator
+)
+{
+    return UIPstream::read
+    (
+        UPstream::commsTypes::nonBlocking,
+        fromProcNo,
+        buffer,
+        count,
+        tag,
+        communicator,
+       &req
+    );
+}
+
+
+template<class Type>
+std::streamsize Foam::UIPstream::read
+(
+    const UPstream::commsTypes commsType,
+    const int fromProcNo,
+    UList<Type>& buffer,
+    const int tag,
+    const int communicator,
+    UPstream::Request* req
+)
+{
+    return UIPstream::read
+    (
+        commsType,
+        fromProcNo,
+        buffer.data(), buffer.size(),
+        tag,
+        communicator,
+        req
+    );
+}
+
+
+template<class Type>
+std::streamsize Foam::UIPstream::read
+(
+    const UPstream::commsTypes commsType,
+    const int fromProcNo,
+    SubList<Type> buffer,
+    const int tag,
+    const int communicator,
+    UPstream::Request* req
+)
+{
+    return UIPstream::read
+    (
+        commsType,
+        fromProcNo,
+        buffer.data(), buffer.size(),
+        tag,
+        communicator,
+        req
+    );
+}
+
+
+template<class Type>
+std::streamsize Foam::UIPstream::read
+(
+    UPstream::Request& req,
+    const int fromProcNo,
+    UList<Type>& buffer,
+    const int tag,
+    const int communicator
+)
+{
+    return UIPstream::read
+    (
+        UPstream::commsTypes::nonBlocking,
+        fromProcNo,
+        buffer.data(), buffer.size(),
+        tag,
+        communicator,
+        &req
+    );
+}
+
+
+template<class Type>
+std::streamsize Foam::UIPstream::read
+(
+    UPstream::Request& req,
+    const int fromProcNo,
+    SubList<Type> buffer,
+    const int tag,
+    const int communicator
+)
+{
+    return UIPstream::read
+    (
+        UPstream::commsTypes::nonBlocking,
+        fromProcNo,
+        buffer.data(), buffer.size(),
+        tag,
+        communicator,
+       &req
+    );
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstreamBase.C b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstreamBase.C
index cfbb324164619f066e1bbce0faac81897c83b74f..c9444e673537c76c534fd8947cfb8dcaeff92242 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstreamBase.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstreamBase.C
@@ -167,7 +167,7 @@ Foam::UIPstreamBase::UIPstreamBase
     DynamicList<char>& receiveBuf,
     label& receiveBufPosition,
     const int tag,
-    const label comm,
+    const int communicator,
     const bool clearAtEnd,
     IOstreamOption::streamFormat fmt
 )
@@ -176,7 +176,7 @@ Foam::UIPstreamBase::UIPstreamBase
     Istream(fmt),
     fromProcNo_(fromProcNo),
     tag_(tag),
-    comm_(comm),
+    comm_(communicator),
     messageSize_(0),
     storedRecvBufPos_(0),
     clearAtEnd_(clearAtEnd),
@@ -548,6 +548,18 @@ bool Foam::UIPstreamBase::beginRawRead()
 ///     return recvBufPos_;
 /// }
 
+Foam::label Foam::UIPstreamBase::remaining() const noexcept
+{
+    if (messageSize_ && (recvBufPos_ < recvBuf_.size()))
+    {
+        return (recvBuf_.size() - recvBufPos_);
+    }
+    else
+    {
+        return 0;
+    }
+}
+
 
 void Foam::UIPstreamBase::rewind()
 {
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H
index e96a05d8754eedf7b4907dd9f12aa3529b3961b7..0dc65315f186b9ec6aa0a2c7ae06b12263f8b287 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2014 OpenFOAM Foundation
-    Copyright (C) 2017-2024 OpenCFD Ltd.
+    Copyright (C) 2017-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -33,6 +33,7 @@ Description
     Not to be used directly, thus contructors are protected.
 
 SourceFiles
+    UOPstream.txx
     UOPstreamBase.C
 
 \*---------------------------------------------------------------------------*/
@@ -121,7 +122,7 @@ protected:
             const int toProcNo,
             DynamicList<char>& sendBuf,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             const bool sendAtDestruct = true,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
@@ -325,7 +326,7 @@ public:
             const int toProcNo,
             DynamicList<char>& sendBuf,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             const bool sendAtDestruct = true,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
@@ -358,51 +359,39 @@ public:
 
     // Static Functions
 
-        //- Write buffer contents to given processor
+        //- Write buffer contents (contiguous types only) to given processor
         //  \return True on success
+        template<class Type>
         static bool write
         (
             const UPstream::commsTypes commsType,
             const int toProcNo,
-            const char* buf,
-            const std::streamsize bufSize,
+            const Type* buffer,
+            std::streamsize count,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             //! [out] request information (for non-blocking)
             UPstream::Request* req = nullptr,
+            //! optional send mode (normal | sync)
             const UPstream::sendModes sendMode = UPstream::sendModes::normal
         );
 
-        //- Write buffer contents (non-blocking) to given processor
+        //- Write buffer contents (contiguous types only) to given processor
         //  \return True on success
+        template<class Type>
         inline static bool write
         (
             //! [out] request information
             UPstream::Request& req,
             const int toProcNo,
-            const char* buf,
-            const std::streamsize bufSize,
+            const Type* buffer,
+            std::streamsize count,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             const UPstream::sendModes sendMode = UPstream::sendModes::normal
-        )
-        {
-            return UOPstream::write
-            (
-                UPstream::commsTypes::nonBlocking,
-                toProcNo,
-                buf,
-                bufSize,
-                tag,
-                comm,
-               &req,
-                sendMode
-            );
-        }
+        );
 
-        //- Write UList contents to given processor.
-        //  Only valid for contiguous data types.
-        //  \return True on success
+        //- Send UList contiguous contents to given processor.
         template<class Type>
         inline static bool write
         (
@@ -410,28 +399,27 @@ public:
             const int toProcNo,
             const UList<Type>& buffer,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             //! [out] request information (for non-blocking)
             UPstream::Request* req = nullptr,
             const UPstream::sendModes sendMode = UPstream::sendModes::normal
-        )
-        {
-            return UOPstream::write
-            (
-                commsType,
-                toProcNo,
-                buffer.cdata_bytes(),
-                buffer.size_bytes(),
-                tag,
-                comm,
-                req,
-                sendMode
-            );
-        }
+        );
 
-        //- Write UList contents (non-blocking) to given processor.
-        //  Only valid for contiguous data types.
-        //  \return True on success
+        //- Send SubList contiguous contents to given processor.
+        template<class Type>
+        inline static bool write
+        (
+            const UPstream::commsTypes commsType,
+            const int toProcNo,
+            const SubList<Type> buffer,  // passed by shallow copy
+            const int tag = UPstream::msgType(),
+            const int communicator = UPstream::worldComm,
+            //! [out] request information (for non-blocking)
+            UPstream::Request* req = nullptr,
+            const UPstream::sendModes sendMode = UPstream::sendModes::normal
+        );
+
+        //- Send UList contiguous contents (non-blocking) to given processor.
         template<class Type>
         inline static bool write
         (
@@ -440,22 +428,22 @@ public:
             const int toProcNo,
             const UList<Type>& buffer,
             const int tag = UPstream::msgType(),
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             const UPstream::sendModes sendMode = UPstream::sendModes::normal
-        )
-        {
-            return UOPstream::write
-            (
-                UPstream::commsTypes::nonBlocking,
-                toProcNo,
-                buffer.cdata_bytes(),
-                buffer.size_bytes(),
-                tag,
-                comm,
-               &req,
-                sendMode
-            );
-        }
+        );
+
+        //- Send SubList contiguous contents (non-blocking) to given processor.
+        template<class Type>
+        inline static bool write
+        (
+            //! [out] request information
+            UPstream::Request& req,
+            const int toProcNo,
+            const SubList<Type> buffer,  // passed by shallow copy
+            const int tag = UPstream::msgType(),
+            const int communicator = UPstream::worldComm,
+            const UPstream::sendModes sendMode = UPstream::sendModes::normal
+        );
 };
 
 
@@ -481,16 +469,12 @@ public:
 
     // Constructors
 
-        //- Construct given process index to write to using the given
-        //- attached send buffer, optional communication characteristics
-        //- and IO format
-        UOPBstream
+        //- Construct with attached send buffer,
+        //- optional communication characteristics and IO format
+        explicit UOPBstream
         (
-            const UPstream::commsTypes,     //!< irrelevant
-            const int toProcNo,             //!< normally UPstream::masterNo()
             DynamicList<char>& sendBuf,
-            const int tag = UPstream::msgType(),  //!< irrelevant
-            const label comm = UPstream::worldComm,
+            const int communicator = UPstream::worldComm,
             const bool sendAtDestruct = true,
             IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
         );
@@ -502,21 +486,9 @@ public:
 
     // Member Functions
 
-        //- Use all write methods from base
-        using UOPstreamBase::write;
-
-
-    // Static Functions
-
-        //- Wrapped version of UPstream::broadcast with const-cast
-        //  \return True on success
-        static bool write
-        (
-            const int rootProcNo,  //!< normally UPstream::masterNo()
-            const char* buf,
-            const std::streamsize bufSize,
-            const label comm = UPstream::worldComm
-        );
+        //- Broadcast a zero value (buffer) size that can be matched
+        //- by the UIPBstream constructor.
+        static void send(Foam::zero, const int communicator);
 };
 
 
@@ -526,6 +498,12 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+#ifdef NoRepository
+    #include "UOPstream.txx"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 #endif
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.txx b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.txx
new file mode 100644
index 0000000000000000000000000000000000000000..940dfc5a166e4e1168db155b4ac189b33cf1d876
--- /dev/null
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.txx
@@ -0,0 +1,200 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2025 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+template<class Type>
+bool Foam::UOPstream::write
+(
+    const UPstream::commsTypes commsType,
+    const int toProcNo,
+    const Type* buffer,
+    std::streamsize count,
+    const int tag,
+    const int communicator,
+    [[maybe_unused]] UPstream::Request* req,
+    const UPstream::sendModes sendMode
+)
+{
+    if constexpr (!is_contiguous_v<Type>)
+    {
+        // Report parameters to silence compiler warnings about unused
+        FatalErrorInFunction
+            << "Invalid for non-contiguous data types. "
+            << int(commsType) << ':' << int(sendMode)
+            << ':' << toProcNo
+            << ':' << (buffer != nullptr)
+            << ':' << count
+            << ':' << tag
+            << ':' << communicator
+            << Foam::abort(FatalError);
+        return false;
+    }
+    else
+    {
+        // Use element or component type (or byte-wise) for data type
+        return UPstream::mpi_send
+        (
+            commsType,
+            buffer,         // The data or cmpt pointer
+            UPstream_dataType<Type>::size(count),
+            UPstream_dataType<Type>::datatype_id,
+            toProcNo,
+            tag,
+            communicator,
+            req,
+            sendMode
+       );
+    }
+}
+
+
+template<class Type>
+bool Foam::UOPstream::write
+(
+    UPstream::Request& req,
+    const int toProcNo,
+    const Type* buffer,
+    std::streamsize count,
+    const int tag,
+    const int communicator,
+    const UPstream::sendModes sendMode
+)
+{
+    return UOPstream::write
+    (
+        UPstream::commsTypes::nonBlocking,
+        toProcNo,
+        buffer,
+        count,
+        tag,
+        communicator,
+       &req,
+        sendMode
+    );
+}
+
+
+template<class Type>
+bool Foam::UOPstream::write
+(
+    const UPstream::commsTypes commsType,
+    const int toProcNo,
+    const UList<Type>& buffer,
+    const int tag,
+    const int communicator,
+    UPstream::Request* req,
+    const UPstream::sendModes sendMode
+)
+{
+    return UOPstream::write
+    (
+        commsType,
+        toProcNo,
+        buffer.cdata(), buffer.size(),
+        tag,
+        communicator,
+        req,
+        sendMode
+    );
+}
+
+
+template<class Type>
+bool Foam::UOPstream::write
+(
+    const UPstream::commsTypes commsType,
+    const int toProcNo,
+    const SubList<Type> buffer,
+    const int tag,
+    const int communicator,
+    UPstream::Request* req,
+    const UPstream::sendModes sendMode
+)
+{
+    return UOPstream::write
+    (
+        commsType,
+        toProcNo,
+        buffer.cdata(), buffer.size(),
+        tag,
+        communicator,
+        req,
+        sendMode
+    );
+}
+
+
+template<class Type>
+bool Foam::UOPstream::write
+(
+    UPstream::Request& req,
+    const int toProcNo,
+    const UList<Type>& buffer,
+    const int tag,
+    const int communicator,
+    const UPstream::sendModes sendMode
+)
+{
+    return UOPstream::write
+    (
+        UPstream::commsTypes::nonBlocking,
+        toProcNo,
+        buffer.cdata(), buffer.size(),
+        tag,
+        communicator,
+       &req,
+        sendMode
+    );
+}
+
+
+template<class Type>
+bool Foam::UOPstream::write
+(
+    UPstream::Request& req,
+    const int toProcNo,
+    const SubList<Type> buffer,
+    const int tag,
+    const int communicator,
+    const UPstream::sendModes sendMode
+)
+{
+    return UOPstream::write
+    (
+        UPstream::commsTypes::nonBlocking,
+        toProcNo,
+        buffer.cdata(), buffer.size(),
+        tag,
+        communicator,
+       &req,
+        sendMode
+    );
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstreamBase.C b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstreamBase.C
index e07c5320e8f1118f9b4290a46fa455a4f7d5170d..cc665f0cb64cf66c8e65f0254391e4cd62aa8fe5 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstreamBase.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstreamBase.C
@@ -146,7 +146,7 @@ Foam::UOPstreamBase::UOPstreamBase
     const int toProcNo,
     DynamicList<char>& sendBuf,
     const int tag,
-    const label comm,
+    const int communicator,
     const bool sendAtDestruct,
     IOstreamOption::streamFormat fmt
 )
@@ -155,7 +155,7 @@ Foam::UOPstreamBase::UOPstreamBase
     Ostream(fmt),
     toProcNo_(toProcNo),
     tag_(tag),
-    comm_(comm),
+    comm_(communicator),
     sendAtDestruct_(sendAtDestruct),
     sendBuf_(sendBuf)
 {
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C
index 4ba0e1f4abb38b3cc00b858507629a7428eb36d9..2c1d72b143acf4957a5e4c1f0de0300f83052d6c 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C
@@ -112,7 +112,7 @@ void Foam::UPstream::printTopoControl(Ostream& os)
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::UPstream::setParRun(const label nProcs, const bool haveThreads)
+void Foam::UPstream::setParRun(const int nProcs, const bool haveThreads)
 {
     parRun_ = (nProcs > 0);
     haveThreads_ = haveThreads;
@@ -725,7 +725,7 @@ void Foam::UPstream::printCommTree
 }
 
 
-bool Foam::UPstream::usingNodeComms(const label communicator)
+bool Foam::UPstream::usingNodeComms(const int communicator)
 {
     // Starting point must be "real" world-communicator
     // ("real" means without any local trickery with worldComm)
@@ -791,6 +791,38 @@ const Foam::List<int>& Foam::UPstream::interNode_offsets()
 }
 
 
+const Foam::UPstream::rangeType& Foam::UPstream::localNode_parentProcs()
+{
+    static UPstream::rangeType singleton;
+
+    if (singleton.empty())
+    {
+        // The inter-node offsets [in const world comm] also include a
+        // startup guard
+        const auto& offsets = UPstream::interNode_offsets();
+
+        const auto nodei =
+            Foam::findLower
+            (
+                offsets,
+                // My place within const world comm
+                UPstream::myProcNo(constWorldComm_)+1
+            );
+
+        if (nodei >= 0)
+        {
+            singleton.reset
+            (
+                offsets[nodei],
+                offsets[nodei+1] - offsets[nodei]
+            );
+        }
+    }
+
+    return singleton;
+}
+
+
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 bool Foam::UPstream::parRun_(false);
@@ -817,10 +849,10 @@ Foam::DynamicList<Foam::UPstream::commsStructList>
 Foam::UPstream::treeCommunication_(16);
 
 
-Foam::label Foam::UPstream::constWorldComm_(0);
-Foam::label Foam::UPstream::numNodes_(1);
-Foam::label Foam::UPstream::commInterNode_(-1);
-Foam::label Foam::UPstream::commLocalNode_(-1);
+int Foam::UPstream::constWorldComm_(0);
+int Foam::UPstream::commInterNode_(-1);
+int Foam::UPstream::commLocalNode_(-1);
+int Foam::UPstream::numNodes_(1);
 
 Foam::label Foam::UPstream::worldComm(0);  // Initially same as constWorldComm_
 Foam::label Foam::UPstream::warnComm(-1);
@@ -828,7 +860,7 @@ Foam::label Foam::UPstream::warnComm(-1);
 
 // Predefine world and self communicator slots.
 // These are overwritten in parallel mode (by UPstream::setParRun())
-const Foam::label nPredefinedComm = []()
+const int nPredefinedComm = []()
 {
     // 0: COMM_WORLD : commGlobal(), constWorldComm_, worldComm
     (void) Foam::UPstream::newCommunicator(-1, Foam::labelRange(1), false);
@@ -862,7 +894,6 @@ registerOptSwitch
     Foam::UPstream::nodeCommsMin_
 );
 
-
 int Foam::UPstream::topologyControl_
 (
     Foam::debug::optimisationSwitch("topoControl", 0)
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H
index d0e23c298cc3969f8412033640e77c51e0190747..8caf255853fd814852436a50bdaf16d48312fd24 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H
@@ -91,52 +91,54 @@ public:
     };
 
     //- Mapping of some fundamental and aggregate types to MPI data types
-    enum class dataTypes : int
+    enum class dataTypes : char
     {
         // NOTE: changes here require adjustment in
         // PstreamGlobals, UPstreamTraits
 
-        // Builtin Types [8]:
-        DataTypes_begin,    //!< (internal use) begin all data types
-        type_byte = DataTypes_begin,  //!< byte, char, unsigned char, ...
+        // Fundamental Types [10]:
+        Basic_begin,    //!< (internal use) begin marker [basic/all types]
+        type_byte = Basic_begin,  //!< byte, char, unsigned char, ...
+        type_int16,
         type_int32,
         type_int64,
+        type_uint16,
         type_uint32,
         type_uint64,
         type_float,
         type_double,
         type_long_double,
 
-        //! (internal use) end of builtin data types marker
-        BuiltinTypes_end, UserTypes_begin = BuiltinTypes_end,
-        //!< (internal use) begin of user data types marker
+        //! (internal use) end marker [basic types]
+        Basic_end, User_begin = Basic_end,
+        //!< (internal use) begin marker [user types]
 
         // User Types [6]:
-        type_3float = UserTypes_begin, //!< 3*float (eg, floatVector)
+        type_3float = User_begin, //!< 3*float (eg, floatVector)
         type_3double,   //!< 3*double (eg, doubleVector)
         type_6float,    //!< 6*float (eg, floatSymmTensor, complex vector)
         type_6double,   //!< 6*double (eg, doubleSymmTensor, complex vector)
         type_9float,    //!< 9*float (eg, floatTensor)
         type_9double,   //!< 9*double (eg, doubleTensor)
 
-        // Internal markers
+        // Internal markers [1]
         invalid,        //!< invalid type (NULL)
-        //! (internal use) end of user data types marker
-        UserTypes_end = invalid, DataTypes_end = invalid
-        //!< (internal use) end of all data types marker
+        //! (internal use) end marker [user types]
+        User_end = invalid, DataTypes_end = invalid
+        //!< (internal use) end marker [all types]
     };
 
     //- Mapping of some MPI op codes.
     //  Currently excluding min/max location until they are needed
-    enum class opCodes : int
+    enum class opCodes : char
     {
         // NOTE: changes here require adjustment in
         // PstreamGlobals, UPstreamTraits
 
-        ReduceOps_begin,  //!< (internal use) begin reduce/window
+        Basic_begin,  //!< (internal use) begin marker [reduce/window types]
 
         // Reduce or window operations [10]
-        op_min = ReduceOps_begin, //!< min(x,y)
+        op_min = Basic_begin, //!< min(x,y)
         op_max,         //!< max(x,y)
         op_sum,         //!< (x + y)
         op_prod,        //!< (x * y)
@@ -147,19 +149,30 @@ public:
         op_bit_or,      //!< Bit-wise \c or for (unsigned) integral types
         op_bit_xor,     //!< Bit-wise \c xor for (unsigned) integral types
 
-        //! (internal use) end of reduce-ops marker
-        ReduceOps_end, WindowOps_begin = ReduceOps_end,
-        //!< (internal use) begin end of window-ops marker
+        //! (internal use) end marker [reduce types]
+        Basic_end, Extra_begin = Basic_end,
+        //!< (internal use) begin marker [window types]
 
         // Window-only operations [2]
-        op_replace = WindowOps_begin,  //!< Replace (window only)
+        op_replace = Extra_begin,  //!< Replace (window only)
         op_no_op,       //!< No-op (window only)
 
-        // Internal markers
+        // Internal markers [1]
         invalid,        //!< invalid op (NULL)
-        //! (internal use) end of window-ops marker
-        WindowOps_end = invalid, OpCodes_end = invalid
-        //!< (internal use) end of all ops marker
+        //! (internal use) end marker [window types]
+        Extra_end = invalid, OpCodes_end = invalid
+        //!< (internal use) end marker [all types]
+    };
+
+    //- Some bit masks corresponding to topology controls
+    //  These selectively enable topology-aware handling
+    enum class topoControls : int
+    {
+        broadcast = 1,      //!< broadcast [MPI]
+        reduce = 2,         //!< reduce/all-reduce [MPI]
+        gather = 16,        //!< gather (reduction) [manual algorithm]
+        mapGather = 32,     //!< mapGather (reduction) [manual algorithm]
+        gatherList = 64,    //!< gatherList/scatterList [manual algorithm]
     };
 
 
@@ -389,18 +402,18 @@ private:
         //- Index to the world-communicator as defined at startup
         //- (after any multi-world definitions).
         //- Is unaffected by any later changes to worldComm.
-        static label constWorldComm_;
-
-        //- The number of shared/host nodes in the (const) world communicator.
-        static label numNodes_;
+        static int constWorldComm_;
 
         //- Index to the inter-node communicator (between nodes),
         //- defined based on constWorldComm_
-        static label commInterNode_;
+        static int commInterNode_;
 
         //- Index to the intra-host communicator (within a node),
         //- defined based on constWorldComm_
-        static label commLocalNode_;
+        static int commLocalNode_;
+
+        //- The number of shared/host nodes in the (const) world communicator.
+        static int numNodes_;
 
         //- Names of all worlds
         static wordList allWorlds_;
@@ -433,7 +446,7 @@ private:
     // Private Member Functions
 
         //- Set data for parallel running
-        static void setParRun(const label nProcs, const bool haveThreads);
+        static void setParRun(const int nProcs, const bool haveThreads);
 
         //- Initialise entries for new communicator.
         //
@@ -489,6 +502,180 @@ private:
         static void freeCommunicatorComponents(const label index);
 
 
+protected:
+
+    // Protected Member Functions
+
+    // Static Functions
+
+        //- Broadcast buffer contents from rank=0 to all ranks.
+        //- The sizes must match on all processes.
+        //  For \b non-parallel : do nothing.
+        //
+        //  \note The method uses a \c void pointer and the required data type
+        //  (as per MPI). This means it should almost never be called directly
+        //  but always via a compile-time checked caller.
+        //  \return True on success
+        static bool mpi_broadcast
+        (
+            void* buf,
+            std::streamsize count,
+            const UPstream::dataTypes dataTypeId,
+            const int communicator
+        );
+
+        //- In-place reduction of \c values with result on rank 0.
+        //  Includes internal parallel guard and checks on data types, opcode.
+        //
+        //  \note The method uses a \c void pointer and the required data type
+        //  (as per MPI). This means it should almost never be called directly
+        //  but always via a compile-time checked caller.
+        static void mpi_reduce
+        (
+            void* values,
+            int count,
+            const UPstream::dataTypes dataTypeId,
+            const UPstream::opCodes opCodeId,
+            const int communicator,
+            //! [out] request information (for non-blocking)
+            UPstream::Request* req = nullptr
+        );
+
+        //- In-place reduction of \c values with same result on all ranks.
+        //  Includes internal parallel guard and checks on data types, opcode.
+        //
+        //  \note The method uses a \c void pointer and the required data type
+        //  (as per MPI). This means it should almost never be called directly
+        //  but always via a compile-time checked caller.
+        static void mpi_allreduce
+        (
+            void* values,
+            int count,
+            const UPstream::dataTypes dataTypeId,
+            const UPstream::opCodes opCodeId,
+            const int communicator,
+            //! [out] request information (for non-blocking)
+            UPstream::Request* req = nullptr
+        );
+
+        //- Send buffer contents of specified data type to given processor.
+        //
+        //  \note The method uses a \c void pointer and the required data type
+        //  (as per MPI). This means it should almost never be called directly
+        //  but always via a compile-time checked caller.
+        //  \return True on success (or Fatal)
+        static bool mpi_send
+        (
+            const UPstream::commsTypes commsType,
+            const void* buf,
+            std::streamsize count,
+            const UPstream::dataTypes dataTypeId,
+            const int toProcNo,
+            const int tag,              // eg, UPstream::msgType()
+            const int communicator,     // eg, UPstream::worldComm
+            //! [out] request information (for non-blocking)
+            UPstream::Request* req = nullptr,
+            //! optional send mode (normal | sync)
+            const UPstream::sendModes sendMode = UPstream::sendModes::normal
+        );
+
+        //- Receive buffer contents of specified data type from given processor.
+        //
+        //  \note The method uses a \c void pointer and the required data type
+        //  (as per MPI). This means it should almost never be called directly
+        //  but always via a compile-time checked caller.
+        //  The commsType will be ignored if UPstream::Request is specified.
+        //
+        //  \return number of elements read. May change in the future
+        static std::streamsize mpi_receive
+        (
+            const UPstream::commsTypes commsType,
+            void* buf,
+            std::streamsize count,
+            const UPstream::dataTypes dataTypeId,
+            const int fromProcNo,
+            const int tag,              // eg, UPstream::msgType()
+            const int communicator,     // eg, UPstream::worldComm
+            //! [out] request information (for non-blocking)
+            UPstream::Request* req = nullptr
+        );
+
+        //- Receive identically-sized (contiguous) data from all ranks
+        //  Includes internal parallel guard.
+        //  For non-parallel, does not copy any data.
+        //  If needed, this must be done by the caller.
+        static void mpi_gather
+        (
+            //! On rank: individual value to send (or nullptr for inplace)
+            const void* sendData,
+            //! Master: receive buffer with all values
+            //! Or for in-place send/recv when sendData is nullptr
+            void* recvData,
+            //! Number of send/recv data per rank. Globally consistent!
+            int count,
+            const UPstream::dataTypes dataTypeId,
+            const int communicator,
+            //! [out] request information (for non-blocking)
+            UPstream::Request* req = nullptr
+        );
+
+        //- Send identically-sized (contiguous) data to all ranks
+        //  Includes internal parallel guard.
+        static void mpi_scatter
+        (
+            //! On master: send buffer with all values (nullptr for inplace)
+            const void* sendData,
+            //! On rank: individual value to receive
+            //! Or for in-place send/recv when sendData is nullptr
+            void* recvData,
+            //! Number of send/recv data per rank. Globally consistent!
+            int count,
+            const UPstream::dataTypes dataTypeId,
+            const int communicator,
+            //! [out] request information (for non-blocking)
+            UPstream::Request* req = nullptr
+        );
+
+        //- Gather/scatter identically-sized data
+        //  Send data from proc slot, receive into all slots
+        static void mpi_allgather
+        (
+            //! On all ranks: the base of the data locations
+            void* allData,
+            //! Number of send/recv data per rank. Globally consistent!
+            int count,
+            const UPstream::dataTypes dataTypeId,
+            const int communicator,
+            //! [out] request information (for non-blocking)
+            UPstream::Request* req = nullptr
+        );
+
+        //- Receive variable length data from all ranks.
+        //- (caution: known to scale poorly)
+        static void mpi_gatherv
+        (
+            const void* sendData,
+            int sendCount,    //!< Ignored on master if recvCount[0] == 0
+            void* recvData,                 //!< Ignored on non-root rank
+            const UList<int>& recvCounts,   //!< Ignored on non-root rank
+            const UList<int>& recvOffsets,  //!< Ignored on non-root rank
+            const UPstream::dataTypes dataTypeId,
+            const int communicator
+        );
+
+        //- Send variable length data to all ranks
+        //- (caution: known to scale poorly)
+        static void mpi_scatterv
+        (
+            const void* sendData,           //!< Ignored on non-root rank
+            const UList<int>& sendCounts,   //!< Ignored on non-root rank
+            const UList<int>& sendOffsets,  //!< Ignored on non-root rank
+            void* recvData,
+            int recvCount,
+            const UPstream::dataTypes dataTypeId,
+            const int communicator
+        );
+
 public:
 
     //- Declare name of the class and its debug switch
@@ -509,13 +696,14 @@ public:
         //  >= 3 : when there are more than N nodes
         static int nodeCommsMin_;
 
-        //- Selection of topology-aware routines
+        //- Selection of topology-aware routines as a bitmask combination
+        //- of the topoControls enumerations
         static int topologyControl_;
 
-        //- Test for selection of given topology-aware routine (bitmask)
-        static bool usingTopoControl(int routine = 0) noexcept
+        //- Test for selection of given topology-aware routine
+        static bool usingTopoControl(UPstream::topoControls ctrl) noexcept
         {
-            return static_cast<bool>(topologyControl_ & routine);
+            return static_cast<bool>(topologyControl_ & int(ctrl));
         }
 
         //- Should compact transfer be used in which floats replace doubles
@@ -557,16 +745,16 @@ public:
 
         //- Communicator for all ranks, irrespective of any local worlds.
         //  This value \em never changes during a simulation.
-        static constexpr label commGlobal() noexcept { return 0; }
+        static constexpr int commGlobal() noexcept { return 0; }
 
         //- Communicator within the current rank only
         //  This value \em never changes during a simulation.
-        static constexpr label commSelf() noexcept { return 1; }
+        static constexpr int commSelf() noexcept { return 1; }
 
         //- Communicator for all ranks (respecting any local worlds).
         //  This value \em never changes after startup. Unlike the commWorld()
         //  which can be temporarily overriden.
-        static label commConstWorld() noexcept { return constWorldComm_; }
+        static int commConstWorld() noexcept { return constWorldComm_; }
 
         //- Communicator for all ranks (respecting any local worlds)
         static label commWorld() noexcept { return worldComm; }
@@ -601,13 +789,13 @@ public:
     // Host Communicators
 
         //- Communicator between nodes/hosts (respects any local worlds)
-        static label commInterNode() noexcept
+        static int commInterNode() noexcept
         {
             return (parRun_ ? commInterNode_ : constWorldComm_);
         }
 
         //- Communicator within the node/host (respects any local worlds)
-        static label commLocalNode() noexcept
+        static int commLocalNode() noexcept
         {
             return (parRun_ ? commLocalNode_ : constWorldComm_);
         }
@@ -626,7 +814,7 @@ public:
         //- it is running in parallel, the starting point is the
         //- world-communicator and it is not an odd corner case
         //- (ie, all processes on one node, all processes on different nodes)
-        static bool usingNodeComms(const label communicator = worldComm);
+        static bool usingNodeComms(const int communicator);
 
 
     // Constructors
@@ -1168,19 +1356,16 @@ public:
         }
 
         //- The number of shared/host nodes in the (const) world communicator.
-        static label numNodes() noexcept
-        {
-            return numNodes_;
-        }
+        static int numNodes() noexcept { return numNodes_; }
 
         //- The parent communicator
-        static label parent(const label communicator)
+        static label parent(int communicator)
         {
             return parentComm_(communicator);
         }
 
         //- The list of ranks within a given communicator
-        static List<int>& procID(const label communicator)
+        static List<int>& procID(int communicator)
         {
             return procIDs_[communicator];
         }
@@ -1232,6 +1417,9 @@ public:
         //- Processor offsets corresponding to the inter-node communicator
         static const List<int>& interNode_offsets();
 
+        //- The range (start/size) of the commLocalNode ranks in terms of the
+        //- (const) world communicator processors.
+        static const rangeType& localNode_parentProcs();
 
         //- Linear communication schedule (special case) for given communicator
         static const commsStructList& linearCommunication(int communicator);
@@ -1240,8 +1428,8 @@ public:
         static const commsStructList& treeCommunication(int communicator);
 
         //- Communication schedule for all-to-master (proc 0) as
-        //- linear/tree/none with switching based on UPstream::nProcsSimpleSum
-        //- and the is_parallel() state and the optional \c linear parameter.
+        //- linear/tree/none with switching based on UPstream::nProcsSimpleSum,
+        //- the is_parallel() state and the optional \c linear parameter.
         static const commsStructList& whichCommunication
         (
             const int communicator,
@@ -1391,107 +1579,69 @@ public:
 
     // Low-level gather/scatter routines
 
-        #undef  Pstream_CommonRoutines
-        #define Pstream_CommonRoutines(Type)                                  \
-                                                                              \
-        /*! \brief Receive identically-sized \c Type data from all ranks */   \
-        static void mpiGather                                                 \
-        (                                                                     \
-            /*! On rank: individual value to send (or nullptr for inplace) */ \
-            const Type* sendData,                                             \
-            /*! Master: receive buffer with all values */                     \
-            /*! Or for in-place send/recv when sendData is nullptr */         \
-            Type* recvData,                                                   \
-            /*! Number of send/recv data per rank. Globally consistent! */    \
-            int count,                                                        \
-            const label communicator = worldComm                              \
-        );                                                                    \
-                                                                              \
-        /*! \brief Send identically-sized \c Type data to all ranks */        \
-        static void mpiScatter                                                \
-        (                                                                     \
-            /*! Master: send buffer with all values (nullptr for inplace) */  \
-            const Type* sendData,                                             \
-            /*! On rank: individual value to receive */                       \
-            /*! Or for in-place send/recv when sendData is nullptr */         \
-            Type* recvData,                                                   \
-            /*! Number of send/recv data per rank. Globally consistent! */    \
-            int count,                                                        \
-            const label communicator = worldComm                              \
-        );                                                                    \
-                                                                              \
-        /*! \brief Gather/scatter identically-sized \c Type data */           \
-        /*! Send data from proc slot, receive into all slots */               \
-        static void mpiAllGather                                              \
-        (                                                                     \
-            /*! On all ranks: the base of the data locations */               \
-            Type* allData,                                                    \
-            /*! Number of send/recv data per rank. Globally consistent! */    \
-            int count,                                                        \
-            const label communicator = worldComm                              \
-        );                                                                    \
-                                                                              \
-        /*! \brief Receive variable length \c Type data from all ranks */     \
-        static void mpiGatherv                                                \
-        (                                                                     \
-            const Type* sendData,                                             \
-            int sendCount,  /*!< Ignored on master if recvCount[0] == 0 */    \
-            Type* recvData,                 /*!< Ignored on non-root rank */  \
-            const UList<int>& recvCounts,   /*!< Ignored on non-root rank */  \
-            const UList<int>& recvOffsets,  /*!< Ignored on non-root rank */  \
-            const label communicator = worldComm                              \
-        );                                                                    \
-                                                                              \
-        /*! \brief Send variable length \c Type data to all ranks */          \
-        static void mpiScatterv                                               \
-        (                                                                     \
-            const Type* sendData,           /*!< Ignored on non-root rank */  \
-            const UList<int>& sendCounts,   /*!< Ignored on non-root rank */  \
-            const UList<int>& sendOffsets,  /*!< Ignored on non-root rank */  \
-            Type* recvData,                                                   \
-            int recvCount,                                                    \
-            const label communicator = worldComm                              \
-        );                                                                    \
-                                                                              \
-        /*! \deprecated(2025-02) prefer mpiGatherv */                         \
-        FOAM_DEPRECATED_FOR(2025-02, "mpiGatherv()")                          \
-        inline static void gather                                             \
-        (                                                                     \
-            const Type* send,                                                 \
-            int count,                                                        \
-            Type* recv,                                                       \
-            const UList<int>& counts,                                         \
-            const UList<int>& offsets,                                        \
-            const label comm = worldComm                                      \
-        )                                                                     \
-        {                                                                     \
-            UPstream::mpiGatherv(send, count, recv, counts, offsets, comm);   \
-        }                                                                     \
-                                                                              \
-        /*! \deprecated(2025-02) prefer mpiScatterv */                        \
-        FOAM_DEPRECATED_FOR(2025-02, "mpiScatterv()")                         \
-        inline static void scatter                                            \
-        (                                                                     \
-            const Type* send,                                                 \
-            const UList<int>& counts,                                         \
-            const UList<int>& offsets,                                        \
-            Type* recv,                                                       \
-            int count,                                                        \
-            const label comm = worldComm                                      \
-        )                                                                     \
-        {                                                                     \
-            UPstream::mpiScatterv(send, counts, offsets, recv, count, comm);  \
-        }
+        //- Receive identically-sized (contiguous) data from all ranks
+        template<class Type>
+        static void mpiGather
+        (
+            //! On rank: individual value to send (or nullptr for inplace)
+            const Type* sendData,
+            //! Master: receive buffer with all values
+            //! Or for in-place send/recv when sendData is nullptr
+            Type* recvData,
+            //! Number of send/recv data per rank. Globally consistent!
+            int count,
+            const int communicator = UPstream::worldComm
+        );
 
-        Pstream_CommonRoutines(char);
-        Pstream_CommonRoutines(int32_t);
-        Pstream_CommonRoutines(int64_t);
-        Pstream_CommonRoutines(uint32_t);
-        Pstream_CommonRoutines(uint64_t);
-        Pstream_CommonRoutines(float);
-        Pstream_CommonRoutines(double);
+        //- Send identically-sized (contiguous) data to all ranks
+        template<class Type>
+        static void mpiScatter
+        (
+            //! On master: send buffer with all values (nullptr for inplace)
+            const Type* sendData,
+            //! On rank: individual value to receive
+            //! Or for in-place send/recv when sendData is nullptr
+            Type* recvData,
+            //! Number of send/recv data per rank. Globally consistent!
+            int count,
+            const int communicator = UPstream::worldComm
+        );
 
-        #undef Pstream_CommonRoutines
+        //- Gather/scatter identically-sized data
+        //  Send data from proc slot, receive into all slots
+        template<class Type>
+        static void mpiAllGather
+        (
+            //! On all ranks: the base of the data locations
+            Type* allData,
+            //! Number of send/recv data per rank. Globally consistent!
+            int count,
+            const int communicator = UPstream::worldComm
+        );
+
+        //- Receive variable length data from all ranks
+        template<class Type>
+        static void mpiGatherv
+        (
+            const Type* sendData,
+            int sendCount,  //!< Ignored on master if recvCount[0] == 0
+            Type* recvData,                 //!< Ignored on non-root rank
+            const UList<int>& recvCounts,   //!< Ignored on non-root rank
+            const UList<int>& recvOffsets,  //!< Ignored on non-root rank
+            const int communicator = UPstream::worldComm
+        );
+
+        //- Send variable length data to all ranks
+        template<class Type>
+        static void mpiScatterv
+        (
+            const Type* sendData,           //!< Ignored on non-root rank
+            const UList<int>& sendCounts,   //!< Ignored on non-root rank
+            const UList<int>& sendOffsets,  //!< Ignored on non-root rank
+            Type* recvData,
+            int recvCount,
+            const int communicator = UPstream::worldComm
+        );
 
 
     // Gather single, contiguous value(s)
@@ -1502,7 +1652,7 @@ public:
         static List<T> allGatherValues
         (
             const T& localValue,
-            const label communicator = worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Gather individual values into list locations.
@@ -1514,7 +1664,7 @@ public:
         static List<T> listGatherValues
         (
             const T& localValue,
-            const label communicator = worldComm
+            const int communicator = UPstream::worldComm
         );
 
         //- Scatter individual values from list locations.
@@ -1526,22 +1676,59 @@ public:
         static T listScatterValues
         (
             const UList<T>& allValues,
-            const label communicator = worldComm
+            const int communicator = UPstream::worldComm
         );
 
 
     // Broadcast Functions
 
-        //- Broadcast buffer contents to all processes in given communicator.
-        //- The sizes must match on all processes.
+        //- Broadcast buffer contents (contiguous types), from rank=0
+        //- to all ranks. The sizes must match on all processes.
         //  For \b non-parallel : do nothing.
         //  \return True on success
-        static bool broadcast
+        template<class Type>
+        inline static bool broadcast
         (
-            char* buf,
-            const std::streamsize bufSize,
-            const label communicator,
-            const int rootProcNo = masterNo()
+            Type* buffer,
+            std::streamsize count,
+            const int communicator
+        );
+
+
+    // Reductions
+
+        //- MPI_Reduce (blocking) for known operators
+        //  For \b non-parallel : do nothing.
+        template<class T>
+        static void mpiReduce
+        (
+            T values[],
+            int count,
+            const UPstream::opCodes opCodeId,
+            const int communicator
+        );
+
+        //- MPI_Allreduce (blocking) for known operators
+        //  For \b non-parallel : do nothing.
+        template<class T>
+        static void mpiAllReduce
+        (
+            T values[],
+            int count,
+            const UPstream::opCodes opCodeId,
+            const int communicator
+        );
+
+        //- MPI_Iallreduce (non-blocking) for known operators
+        //  For \b non-parallel : do nothing.
+        template<class T>
+        static void mpiAllReduce
+        (
+            T values[],
+            int count,
+            const UPstream::opCodes opCodeId,
+            const int communicator,
+            UPstream::Request& req
         );
 
 
@@ -1552,7 +1739,7 @@ public:
         static void reduceAnd
         (
             bool& value,
-            const label communicator = worldComm
+            const int communicator = worldComm
         );
 
         //- Logical (or) reduction (MPI_AllReduce)
@@ -1560,7 +1747,7 @@ public:
         static void reduceOr
         (
             bool& value,
-            const label communicator = worldComm
+            const int communicator = worldComm
         );
 
 
@@ -1603,6 +1790,38 @@ public:
         //     Should normally be restricted to a particular starting request.
         FOAM_DEPRECATED_FOR(2023-01, "waitRequests(int) method")
         static void waitRequests() { waitRequests(0); }
+
+        //- \deprecated(2025-02) prefer mpiGatherv
+        template<class Type>
+        FOAM_DEPRECATED_FOR(2025-02, "mpiGatherv()")
+        static void gather
+        (
+            const Type* send,
+            int count,
+            Type* recv,
+            const UList<int>& counts,
+            const UList<int>& offsets,
+            const int comm = UPstream::worldComm
+        )
+        {
+            UPstream::mpiGatherv(send, count, recv, counts, offsets, comm);
+        }
+
+        //- \deprecated(2025-02) prefer mpiScatterv
+        template<class Type>
+        FOAM_DEPRECATED_FOR(2025-02, "mpiScatterv()")
+        static void scatter
+        (
+            const Type* send,
+            const UList<int>& counts,
+            const UList<int>& offsets,
+            Type* recv,
+            int count,
+            const int comm = UPstream::worldComm
+        )
+        {
+            UPstream::mpiScatterv(send, counts, offsets, recv, count, comm);
+        }
 };
 
 
@@ -1691,7 +1910,7 @@ public:
         //      UPstream::Communicator::lookup(UPstream::commWorld())
         //  )
         //  \endcode
-        static Communicator lookup(const label comm);
+        static Communicator lookup(const int comm);
 
 
     // Member Functions
@@ -1710,6 +1929,9 @@ public:
 
         //- Reset to default constructed value (MPI_COMM_NULL)
         void reset() noexcept;
+
+        //- The number of ranks associated with the communicator
+        int size() const;
 };
 
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.txx b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.txx
index 844b203446d01f593670d2cd32a9cecb4cebe8aa..1e529ac018e5444e5c3d8977c373f38dfde88a1a 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.txx
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.txx
@@ -27,83 +27,238 @@ License
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template<class T>
-Foam::List<T> Foam::UPstream::allGatherValues
+template<class Type>
+bool Foam::UPstream::broadcast
 (
-    const T& localValue,
-    const label comm
+    Type* buffer,
+    std::streamsize count,
+    const int communicator
 )
 {
-    if constexpr (!is_contiguous_v<T>)
+    // Likely no reason to check for nullptr
+    if (!UPstream::is_parallel(communicator))
     {
+        // Nothing to do - ignore
+        return true;
+    }
+    else if constexpr (!is_contiguous_v<Type>)
+    {
+        // Also report parameters to silence compiler warnings about unused
         FatalErrorInFunction
-            << "Cannot all-gather values for non-contiguous types"
-               " - consider Pstream variant instead" << endl
+            << "Invalid for non-contiguous data types."
+            << " buffer:" << (buffer != nullptr)
+            << " count:" << count
             << Foam::abort(FatalError);
+        return false;
     }
+    else
+    {
+        // Use element or component type (or byte-wise) for data type
+        return UPstream::mpi_broadcast
+        (
+            buffer,     // The data or cmpt pointer
+            UPstream_dataType<Type>::size(count),
+            UPstream_dataType<Type>::datatype_id,
+            communicator
+        );
+    }
+}
 
-    List<T> allValues;
 
-    if (UPstream::is_parallel(comm))
+template<class Type>
+void Foam::UPstream::mpiGather
+(
+    const Type* sendData,
+    Type* recvData,
+    int count,
+    const int communicator
+)
+{
+    if (!count || !UPstream::is_rank(communicator))
+    {
+        // Nothing to do
+        return;
+    }
+    else if constexpr (!is_contiguous_v<Type>)
+    {
+        FatalErrorInFunction
+            << "Invalid for non-contiguous data types"
+            << Foam::abort(FatalError);
+    }
+    else if (!UPstream::is_parallel(communicator))
+    {
+        // Perform any fallback copying here, while we still know the Type
+        if (sendData && recvData && (sendData != recvData))
+        {
+            std::memmove(recvData, sendData, count*sizeof(Type));
+        }
+    }
+    else
     {
-        allValues.resize(UPstream::nProcs(comm));
-        allValues[UPstream::myProcNo(comm)] = localValue;
+        // Use element or component type (or byte-wise) for data type
+        UPstream::mpi_gather
+        (
+            sendData,   // The data or cmpt pointer
+            recvData,   // The data or cmpt pointer
+            UPstream_dataType<Type>::size(count),
+            UPstream_dataType<Type>::datatype_id,
+            communicator
+        );
+    }
+}
+
 
-        UPstream::mpiAllGather(allValues.data_bytes(), sizeof(T), comm);
+template<class Type>
+void Foam::UPstream::mpiScatter
+(
+    const Type* sendData,
+    Type* recvData,
+    int count,
+    const int communicator
+)
+{
+    if (!count || !UPstream::is_rank(communicator))
+    {
+        // Nothing to do
+        return;
+    }
+    else if constexpr (!is_contiguous_v<Type>)
+    {
+        FatalErrorInFunction
+            << "Invalid for non-contiguous data types"
+            << Foam::abort(FatalError);
+    }
+    else if (!UPstream::is_parallel(communicator))
+    {
+        // Perform any fallback copying here, while we still know the Type
+        if (sendData && recvData && (sendData != recvData))
+        {
+            std::memmove(recvData, sendData, count*sizeof(Type));
+        }
     }
     else
+    {
+        // Use element or component type (or byte-wise) for data type
+        UPstream::mpi_scatter
+        (
+            sendData,   // The data or cmpt pointer
+            recvData,   // The data or cmpt pointer
+            UPstream_dataType<Type>::size(count),
+            UPstream_dataType<Type>::datatype_id,
+            communicator
+        );
+    }
+}
+
+
+template<class Type>
+void Foam::UPstream::mpiAllGather
+(
+    Type* allData,
+    int count,
+    const int communicator
+)
+{
+    if (!count || !UPstream::is_parallel(communicator))
+    {
+        // Nothing sensible to do
+        return;
+    }
+    else if constexpr (!is_contiguous_v<Type>)
+    {
+        FatalErrorInFunction
+            << "Invalid for non-contiguous data types"
+            << Foam::abort(FatalError);
+    }
+    else
+    {
+        // Use element or component type (or byte-wise) for data type
+        UPstream::mpi_allgather
+        (
+            allData,    // The data or cmpt pointer
+            UPstream_dataType<Type>::size(count),
+            UPstream_dataType<Type>::datatype_id,
+            communicator
+        );
+    }
+}
+
+
+template<class T>
+Foam::List<T> Foam::UPstream::allGatherValues
+(
+    const T& localValue,
+    const int communicator
+)
+{
+    if (!UPstream::is_parallel(communicator))
     {
         // non-parallel: return own value
         // TBD: only when UPstream::is_rank(comm) as well?
-        allValues.resize(1);
+        List<T> allValues(1);
         allValues[0] = localValue;
+        return allValues;
     }
+    else if constexpr (!is_contiguous_v<T>)
+    {
+        FatalErrorInFunction
+            << "Cannot all-gather values for non-contiguous types"
+            << " - consider Pstream variant instead" << endl
+            << Foam::abort(FatalError);
+        return List<T>();
+    }
+    else
+    {
+        // Standard gather with direct MPI communication
+        List<T> allValues;
 
-    return allValues;
+        allValues.resize(UPstream::nProcs(communicator));
+        allValues[UPstream::myProcNo(communicator)] = localValue;
+
+        UPstream::mpiAllGather(allValues.data(), 1, communicator);
+        return allValues;
+    }
 }
 
 
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 template<class T>
 Foam::List<T> Foam::UPstream::listGatherValues
 (
     const T& localValue,
-    const label comm
+    const int communicator
 )
 {
-    if constexpr (!is_contiguous_v<T>)
+    if (!UPstream::is_parallel(communicator))
+    {
+        // non-parallel: return own value
+        // TBD: only when UPstream::is_rank(communicator) as well?
+        List<T> allValues(1);
+        allValues[0] = localValue;
+        return allValues;
+    }
+    else if constexpr (!is_contiguous_v<T>)
     {
         FatalErrorInFunction
             << "Cannot gather values for non-contiguous types"
                " - consider Pstream variant instead" << endl
             << Foam::abort(FatalError);
+        return List<T>();
     }
-
-    List<T> allValues;
-
-    if (UPstream::is_parallel(comm))
+    else
     {
-        if (UPstream::master(comm))
+        // Local sizes are identical, can use MPI_Gather
+        List<T> allValues;
+
+        if (UPstream::master(communicator))
         {
-            allValues.resize(UPstream::nProcs(comm));
+            allValues.resize(UPstream::nProcs(communicator));
         }
 
-        UPstream::mpiGather
-        (
-            reinterpret_cast<const char*>(&localValue),
-            allValues.data_bytes(),
-            sizeof(T),  // The send/recv size per rank
-            comm
-        );
-    }
-    else
-    {
-        // non-parallel: return own value
-        // TBD: only when UPstream::is_rank(comm) as well?
-        allValues.resize(1);
-        allValues[0] = localValue;
+        UPstream::mpiGather(&localValue, allValues.data(), 1, communicator);
+        return allValues;
     }
-
-    return allValues;
 }
 
 
@@ -111,51 +266,252 @@ template<class T>
 T Foam::UPstream::listScatterValues
 (
     const UList<T>& allValues,
-    const label comm
+    const int communicator
 )
 {
-    if constexpr (!is_contiguous_v<T>)
+    if (!UPstream::is_parallel(communicator))
+    {
+        // non-parallel: return own value
+        // TBD: only when UPstream::is_rank(communicator) as well?
+
+        if (!allValues.empty())
+        {
+            return allValues[0];
+        }
+
+        return T{};  // Fallback value
+    }
+    else if constexpr (!is_contiguous_v<T>)
     {
         FatalErrorInFunction
-            << "Cannot scatter values for non-contiguous types"
+            << "Cannot scatter non-contiguous values"
                " - consider Pstream variant instead" << endl
             << Foam::abort(FatalError);
-    }
-
-    T localValue{};
 
-    if (UPstream::is_parallel(comm))
+        return T{};  // Fallback value
+    }
+    else
     {
-        const label numProc = UPstream::nProcs(comm);
+        // Local sizes are identical, can use MPI_Scatter
+
+        const label nProcs = UPstream::nProcs(communicator);
 
-        if (UPstream::master(comm) && allValues.size() < numProc)
+        if
+        (
+            FOAM_UNLIKELY
+            (
+                UPstream::master(communicator)
+             && allValues.size() < nProcs
+            )
+        )
         {
             FatalErrorInFunction
                 << "Attempting to send " << allValues.size()
-                << " values to " << numProc << " processors" << endl
+                << " values to " << nProcs << " processors" << endl
                 << Foam::abort(FatalError);
         }
 
-        UPstream::mpiScatter
+        T localValue{};
+        UPstream::mpiScatter(allValues.cdata(), &localValue, 1, communicator);
+        return localValue;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class Type>
+void Foam::UPstream::mpiGatherv
+(
+    const Type* sendData,
+    int sendCount,
+    Type* recvData,
+    const UList<int>& recvCounts,
+    const UList<int>& recvOffsets,
+    const int communicator
+)
+{
+    if (!UPstream::is_parallel(communicator))
+    {
+        if constexpr (is_contiguous_v<Type>)
+        {
+            if (sendData && recvData)
+            {
+                // recvCounts[0] may be invalid - use sendCount instead
+                std::memmove(recvData, sendData, sendCount*sizeof(Type));
+            }
+        }
+        // Nothing further to do
+    }
+    else if constexpr (UPstream_basic_dataType<Type>::value)
+    {
+        // Restrict to basic (or aliased) MPI types to avoid recalculating
+        // the list of counts/offsets.
+
+        UPstream::mpi_gatherv
         (
-            allValues.cdata_bytes(),
-            reinterpret_cast<char*>(&localValue),
-            sizeof(T),  // The send/recv size per rank
-            comm
+            sendData,
+            sendCount,
+            recvData,
+            recvCounts,
+            recvOffsets,
+
+            UPstream_basic_dataType<Type>::datatype_id,
+            communicator
         );
     }
     else
     {
-        // non-parallel: return first value
-        // TBD: only when UPstream::is_rank(comm) as well?
+        static_assert
+        (
+            stdFoam::dependent_false_v<Type>, "Only basic MPI data types"
+        );
+    }
+}
 
-        if (!allValues.empty())
+
+template<class Type>
+void Foam::UPstream::mpiScatterv
+(
+    const Type* sendData,
+    const UList<int>& sendCounts,
+    const UList<int>& sendOffsets,
+    Type* recvData,
+    int recvCount,
+    const int communicator
+)
+{
+    if (!UPstream::is_parallel(communicator))
+    {
+        if constexpr (is_contiguous_v<Type>)
         {
-            return allValues[0];
+            if (sendData && recvData)
+            {
+                std::memmove(recvData, sendData, recvCount*sizeof(Type));
+            }
         }
-     }
+        // Nothing further to do
+    }
+    else if constexpr (UPstream_basic_dataType<Type>::value)
+    {
+        // Restrict to basic (or aliased) MPI types to avoid recalculating
+        // the list of counts/offsets.
+
+        UPstream::mpi_scatterv
+        (
+            sendData,
+            sendCounts,
+            sendOffsets,
+            recvData,
+            recvCount,
 
-     return localValue;
+            UPstream_basic_dataType<Type>::datatype_id,
+            communicator
+        );
+    }
+    else
+    {
+        static_assert
+        (
+            stdFoam::dependent_false_v<Type>, "Only basic MPI data types"
+        );
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class T>
+void Foam::UPstream::mpiReduce
+(
+    T values[],
+    int count,
+    const UPstream::opCodes opCodeId,
+    const int communicator
+)
+{
+    if (!count || !UPstream::is_parallel(communicator))
+    {
+        // Nothing to do
+        return;
+    }
+    else
+    {
+        // Use element or component type (or byte-wise) for data type
+        // Restricted to basic data types
+        UPstream::mpi_reduce
+        (
+            values,     // The data or cmpt pointer
+            UPstream_basic_dataType<T>::size(count),
+            UPstream_basic_dataType<T>::datatype_id,
+            opCodeId,
+            communicator
+        );
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class T>
+void Foam::UPstream::mpiAllReduce
+(
+    T values[],
+    int count,
+    const UPstream::opCodes opCodeId,
+    const int communicator
+)
+{
+    if (!count || !UPstream::is_parallel(communicator))
+    {
+        // Nothing to do
+        return;
+    }
+    else
+    {
+        // Use element or component type (or byte-wise) for data type
+        // Restricted to basic data types
+        UPstream::mpi_allreduce
+        (
+            values,     // The data or cmpt pointer
+            UPstream_basic_dataType<T>::size(count),
+            UPstream_basic_dataType<T>::datatype_id,
+            opCodeId,
+            communicator
+        );
+    }
+}
+
+
+template<class T>
+void Foam::UPstream::mpiAllReduce
+(
+    T values[],
+    int count,
+    const UPstream::opCodes opCodeId,
+    const int communicator,
+    UPstream::Request& req
+)
+{
+    if (!count || !UPstream::is_parallel(communicator))
+    {
+        // Nothing to do
+        return;
+    }
+    else
+    {
+        // Use element or component type (or byte-wise) for data type
+        // Restricted to basic data types
+        UPstream::mpi_allreduce
+        (
+            values,     // The data or cmpt pointer
+            UPstream_basic_dataType<T>::size(count),
+            UPstream_basic_dataType<T>::datatype_id,
+            opCodeId,
+            communicator,
+           &req
+        );
+    }
 }
 
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamTraits.H b/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamTraits.H
index 224300002d4750fd6cee9714d7d63c4e28815165..ec0d3ad8631bc1b3695090f2d0003755f8e5019f 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamTraits.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamTraits.H
@@ -26,28 +26,50 @@ License
 Description
     A set of traits associated with UPstream communication
 
-    - UPstream_dataType trait:
-      This wrapper is unwinds the type to check against base/alias, but also
-      checks if it is a component aggregate of a supported UPstream data type.
-      This will be that main entry point for usage.
+    \par Front-facing traits
 
-    - UPstream_opType trait:
-      Provides a mapping of OpenFOAM ops to their MPI equivalent.
+    - \c UPstream_basic_dataType trait :<br>
+      The main entry point for reduction operations
+      (requires fundamental types).<br>
+      Checks against fundamental/aliased (excludes user-defined),
+      or is a component-wise aggregate of the same.
+
+    - \c UPstream_dataType trait :<br>
+      The main entry point for transmission (broadcast, send/recv, ...).<br>
+      Checks against fundamental/aliased/user-defined,
+      or is a component-wise aggregate of the same.
+
+    - \c UPstream_opType trait :<br>
+      Mapping of OpenFOAM ops to their MPI equivalent.
       The \c opcode_id is the corresponding internal representation.
 
-Note
-    Additional helper traits:
+    - \c UPstream_data_opType trait :<br>
+      Combination of UPstream_opType and UPstream_basic_dataType.
+    .
+
+    \par Additional helper traits (not normally used directly):
 
-    - UPstream_base_dataType trait:
-      Tests true/false if the specified data type has an internal
-      MPI equivalent.  The \c datatype_id is the corresponding
-      internal enumeration. Even if this tests as false, it will
-      always return \c type_byte as the fallback for general contiguous data
+    - \c UPstream_mpi_dataType trait :<br>
+      Tests true and provides valid \c datatype_id for MPI fundamental
+      data types. This trait will should not normally be used directly:
+      use UPstream_alias_dataType for 'low-level' purposes (see below).
 
-    - UPstream_alias_dataType trait:
-      Provides mapping for <int/long/long long,...> to the fundamental
+    - \c UPstream_user_dataType trait :<br>
+      Tests true and provides valid \c datatype_id for user-defined
+      data types.
+
+    - \c UPstream_alias_dataType trait :<br>
+      Use this in preference to UPstream_mpi_dataType.<br>
+      A pass-through to UPstream_mpi_dataType, but provides additional
+      mappings for <int/long/long long,...> to the fundamental
       32/64 bit integrals, since <int/long/long long,...> may not otherwise
-      directly map on all systems.
+      map directly on all systems.
+
+    - \c UPstream_any_dataType trait :<br>
+      Used as a building block for uniform aggregate types.<br>
+      Combines UPstream_user_dataType and UPstream_alias_dataType into a
+      single trait.
+    .
 
 \*---------------------------------------------------------------------------*/
 
@@ -88,130 +110,37 @@ template<class T> class Tensor;
 // template<class T> struct bitXorOp;
 
 //! \cond
+template<class T> struct UPstream_basic_dataType;
 template<class T> struct UPstream_dataType;
-template<class T> struct UPstream_opType;
 //! \endcond
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-// Base traits
-
-//- A supported UPstream (MPI) reduce/window operation type
-template<class T>
-struct UPstream_opType : std::false_type
-{
-    static constexpr auto opcode_id = UPstream::opCodes::invalid;
-};
-
-
-//- A supported UPstream data type (intrinsic or user-defined)
+//- UPstream data type corresponding to a fundamental (MPI) type
 template<class T>
-struct UPstream_base_dataType : std::false_type
+struct UPstream_mpi_dataType : std::false_type
 {
     static constexpr auto datatype_id = UPstream::dataTypes::invalid;
 };
 
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Trait specializations (op-codes)
-
-//- Map minOp\<T\> to \c UPstream::opCodes::op_min
-template<class T>
-struct UPstream_opType<Foam::minOp<T>> : std::true_type
-{
-    static constexpr auto opcode_id = UPstream::opCodes::op_min;
-};
-
-//- Map maxOp\<T\> to \c UPstream::opCodes::op_max
-template<class T>
-struct UPstream_opType<Foam::maxOp<T>> : std::true_type
+//- Disallow \c void
+template<> struct UPstream_mpi_dataType<void> : std::false_type
 {
-    static constexpr auto opcode_id = UPstream::opCodes::op_max;
-};
-
-//- Map sumOp\<T\> to \c UPstream::opCodes::op_sum
-template<class T>
-struct UPstream_opType<Foam::sumOp<T>> : std::true_type
-{
-    static constexpr auto opcode_id = UPstream::opCodes::op_sum;
-};
-
-//- Map plusOp\<T\> to \c UPstream::opCodes::op_sum
-//- as a recognized alternative to sumOp\<T\>
-template<class T>
-struct UPstream_opType<Foam::plusOp<T>> : std::true_type
-{
-    static constexpr auto opcode_id = UPstream::opCodes::op_sum;
-};
-
-//- Map multiplyOp\<T\> to \c UPstream::opCodes::op_prod
-template<class T>
-struct UPstream_opType<Foam::multiplyOp<T>> : std::true_type
-{
-    static constexpr auto opcode_id = UPstream::opCodes::op_prod;
-};
-
-// NOTE (2025-02):
-// currently no mappings provided for
-// (op_bool_and, op_bool_or, op_bool_xor) until the calling semantics
-// have been properly defined
-
-
-// These are only viable for unsigned integral types,
-// probably not for signed integral types.
-// Be extra restrictive for now
-
-//- Map bitAndOp\<T\> to \c UPstream::opCodes::op_bit_and
-//- (for unsigned integrals)
-template<class T>
-struct UPstream_opType<Foam::bitAndOp<T>>
-:
-    // ie, std::unsigned_integral<T> concept
-    std::bool_constant<std::is_integral_v<T> && !std::is_signed_v<T>>
-{
-    static constexpr auto opcode_id = []() constexpr noexcept
-    {
-        if constexpr (std::is_integral_v<T> && !std::is_signed_v<T>)
-            return UPstream::opCodes::op_bit_and;
-        else
-            return UPstream::opCodes::invalid;
-    }();
+    static constexpr auto datatype_id = UPstream::dataTypes::invalid;
 };
 
-//- Map bitOrOp\<T\> to \c UPstream::opCodes::op_bit_or
-//- (for unsigned integrals)
+//- UPstream data type corresponding to user-defined type
 template<class T>
-struct UPstream_opType<Foam::bitOrOp<T>>
-:
-    // ie, std::unsigned_integral<T> concept
-    std::bool_constant<std::is_integral_v<T> && !std::is_signed_v<T>>
+struct UPstream_user_dataType : std::false_type
 {
-    static constexpr auto opcode_id = []() constexpr noexcept
-    {
-        if constexpr (std::is_integral_v<T> && !std::is_signed_v<T>)
-            return UPstream::opCodes::op_bit_or;
-        else
-            return UPstream::opCodes::invalid;
-    }();
+    static constexpr auto datatype_id = UPstream::dataTypes::invalid;
 };
 
-//- Map bitXorOp\<T\> to \c UPstream::opCodes::op_bit_xor
-//- (for unsigned integrals)
-template<class T>
-struct UPstream_opType<Foam::bitXorOp<T>>
-:
-    // ie, std::unsigned_integral<T> concept
-    std::bool_constant<std::is_integral_v<T> && !std::is_signed_v<T>>
+//- Disallow \c void
+template<> struct UPstream_user_dataType<void> : std::false_type
 {
-    static constexpr auto opcode_id = []() constexpr noexcept
-    {
-        if constexpr (std::is_integral_v<T> && !std::is_signed_v<T>)
-            return UPstream::opCodes::op_bit_xor;
-        else
-            return UPstream::opCodes::invalid;
-    }();
+    static constexpr auto datatype_id = UPstream::dataTypes::invalid;
 };
 
 
@@ -219,36 +148,59 @@ struct UPstream_opType<Foam::bitXorOp<T>>
 
 // Trait specializations (data types)
 
-// Specializations to match elements of UPstream::dataTypes
+// Specializations to match elements of UPstream::dataTypes.
+
 #undef  defineUPstreamDataTraits
 #define defineUPstreamDataTraits(TypeId, Type)                                \
                                                                               \
     /*! \brief Map \c Type to UPstream::dataTypes::TypeId */                  \
-    template<> struct UPstream_base_dataType<Type> : std::true_type           \
+    template<> struct UPstream_mpi_dataType<Type> : std::true_type            \
     {                                                                         \
         static constexpr auto datatype_id = UPstream::dataTypes::TypeId;      \
     };                                                                        \
     /*! \brief Map \c const \c Type to \c UPstream::dataTypes::TypeId */      \
-    template<> struct UPstream_base_dataType<const Type> : std::true_type     \
+    template<> struct UPstream_mpi_dataType<const Type> : std::true_type      \
     {                                                                         \
         static constexpr auto datatype_id = UPstream::dataTypes::TypeId;      \
     };
 
-
-// Intrinsic Types [8]:
+// Fundamental Types [10]:
 // Note: uses 'int32_t,int64_t,...' instead of 'int,long,...' to minimize
-// the possibility of duplicates types.
+// the possibility of duplicate types. However, 'int8_t,uint8_t' are treated
+// as aliases (char,unsigned char) to avoid possible compilation issues.
+//
 // OpenFOAM defines Foam::label as either int32_t,int64_t (not int,long) too.
 defineUPstreamDataTraits(type_byte,   char);
 defineUPstreamDataTraits(type_byte,   unsigned char);
+defineUPstreamDataTraits(type_int16,  int16_t);
 defineUPstreamDataTraits(type_int32,  int32_t);
 defineUPstreamDataTraits(type_int64,  int64_t);
+defineUPstreamDataTraits(type_uint16, uint16_t);
 defineUPstreamDataTraits(type_uint32, uint32_t);
 defineUPstreamDataTraits(type_uint64, uint64_t);
 defineUPstreamDataTraits(type_float,  float);
 defineUPstreamDataTraits(type_double, double);
 defineUPstreamDataTraits(type_long_double, long double);
 
+#undef defineUPstreamDataTraits
+
+// ------------------------------------------------------------------------- //
+
+#undef  defineUPstreamDataTraits
+#define defineUPstreamDataTraits(TypeId, Type)                                \
+                                                                              \
+    /*! \brief Map \c Type to UPstream::dataTypes::TypeId */                  \
+    template<> struct UPstream_user_dataType<Type> : std::true_type           \
+    {                                                                         \
+        static constexpr auto datatype_id = UPstream::dataTypes::TypeId;      \
+    };                                                                        \
+    /*! \brief Map \c const \c Type to \c UPstream::dataTypes::TypeId */      \
+    template<> struct UPstream_user_dataType<const Type> : std::true_type     \
+    {                                                                         \
+        static constexpr auto datatype_id = UPstream::dataTypes::TypeId;      \
+    };
+
+
 // User Types [6]:
 defineUPstreamDataTraits(type_3float,  Vector<float>);
 defineUPstreamDataTraits(type_3double, Vector<double>);
@@ -264,14 +216,17 @@ defineUPstreamDataTraits(type_9double, Tensor<double>);
 
 //- Explicit handling of data type aliases. This is necessary since
 //- different systems map things like 'unsigned long' differently but we
-//- restrict ourselves to int32/int64 types
+//- restrict ourselves to int32/int64 types.
+//
+//  Note that this trait serves as the single pass-through point when needing
+//  to reference UPstream_mpi_dataType elsewhere
 template<class T>
 struct UPstream_alias_dataType
 :
     std::bool_constant
     <
-        // Base type (no alias needed)
-        UPstream_base_dataType<std::remove_cv_t<T>>::value ||
+        // Basic MPI type
+        UPstream_mpi_dataType<std::remove_cv_t<T>>::value ||
         (
             // Or some int 32/64 type to re-map
             std::is_integral_v<T>
@@ -279,14 +234,10 @@ struct UPstream_alias_dataType
         )
     >
 {
-    // Is it using the base type? (no alias needed)
-    static constexpr bool is_base =
-        UPstream_base_dataType<std::remove_cv_t<T>>::value;
-
     using base = std::conditional_t
     <
-        UPstream_base_dataType<std::remove_cv_t<T>>::value,
-        std::remove_cv_t<T>,  // <- using base
+        UPstream_mpi_dataType<std::remove_cv_t<T>>::value,
+        std::remove_cv_t<T>,  // <- using mpi type (no alias)
         std::conditional_t    // <- using alias
         <
             (
@@ -304,66 +255,342 @@ struct UPstream_alias_dataType
     >;
 
     static constexpr auto datatype_id =
-        UPstream_base_dataType<base>::datatype_id;
+        UPstream_mpi_dataType<base>::datatype_id;
+};
+
+
+// Handle int8_t/uint8_t as aliases since 'signed char' etc may be
+// ambiguous
+
+//- Map \c int8_t to UPstream::dataTypes::type_byte
+template<>
+struct UPstream_alias_dataType<int8_t> : std::true_type
+{
+    using base = char;
+    static constexpr auto datatype_id = UPstream::dataTypes::type_byte;
+};
+
+//- Map \c uint8_t to UPstream::dataTypes::type_byte
+template<>
+struct UPstream_alias_dataType<uint8_t> : std::true_type
+{
+    using base = unsigned char;
+    static constexpr auto datatype_id = UPstream::dataTypes::type_byte;
+};
+
+// ------------------------------------------------------------------------- //
+
+//- UPstream data type (fundamental or user-defined),
+//- after resolving any aliases
+template<class T>
+struct UPstream_any_dataType
+:
+    std::bool_constant
+    <
+        UPstream_user_dataType<std::remove_cv_t<T>>::value
+     || UPstream_alias_dataType<T>::value
+    >
+{
+    using base = std::conditional_t
+    <
+        UPstream_user_dataType<std::remove_cv_t<T>>::value,
+        std::remove_cv_t<T>,
+        typename UPstream_alias_dataType<T>::base
+    >;
+
+    //- The corresponding UPstream::dataTypes enumeration
+    static constexpr auto datatype_id = []() constexpr noexcept
+    {
+        if constexpr (UPstream_user_dataType<std::remove_cv_t<T>>::value)
+        {
+            // A user-defined type
+            return UPstream_user_dataType<std::remove_cv_t<T>>::datatype_id;
+        }
+        else if constexpr (UPstream_alias_dataType<T>::value)
+        {
+            // Fundamental type or alias to a fundamental type
+            return UPstream_alias_dataType<T>::datatype_id;
+        }
+        else
+        {
+            return UPstream::dataTypes::invalid;
+        }
+    }();
 };
 
 
 // ------------------------------------------------------------------------- //
 
-//- A supported UPstream data type (fundamental or user-defined)
-//- or a component aggregate of a supported UPstream data type.
+//- UPstream fundamental/aliased (excludes user-defined) data type
+//- or a component aggregate of the same.
 //
-// Is true for the following conditions:
+// True for the following conditions:
 // - The \c Type is directly supported
 // - The \c cmptType (eg, from VectorSpace) exists and is directly supported
 // - Fallback to byte-wise representation (ie, for contiguous)
 // .
 template<class T>
-struct UPstream_dataType
+struct UPstream_basic_dataType
 :
     std::bool_constant
     <
+        // non-aggregate type
         UPstream_alias_dataType<T>::value
+        // aggregate type
      || UPstream_alias_dataType<typename pTraits_cmptType<T>::type>::value
     >
 {
-    // Is it using the base type? (ie, not using components)
-    static constexpr bool is_base = UPstream_alias_dataType<T>::value;
-
     //- The underlying data type (if supported) or byte
     using base = std::conditional_t
     <
         UPstream_alias_dataType<T>::value,
-        typename UPstream_alias_dataType<T>::base,  // <- using base
+        typename UPstream_alias_dataType<T>::base,  // <- non-aggregate
         typename UPstream_alias_dataType
-        <typename pTraits_cmptType<T>::type>::base  // <- using components
+        <typename pTraits_cmptType<T>::type>::base  // <- aggregate
     >;
 
     //- The corresponding UPstream::dataTypes enumeration
     static constexpr auto datatype_id =
-        UPstream_base_dataType<base>::datatype_id;
+        UPstream_alias_dataType<base>::datatype_id;
 
     //- The size in terms of the number of underlying data elements
-    static std::streamsize size(std::streamsize count) noexcept
+    static std::streamsize size(std::streamsize n) noexcept
     {
         if constexpr (UPstream_alias_dataType<T>::value)
         {
-            // using base: no multiplier
-            return count;
+            // non-aggregate: no multiplier
+            return n;
         }
         else
         {
-            // using components: with multiplier
-            return count*(sizeof(T)/sizeof(base));
+            // aggregate: with multiplier
+            return n*(sizeof(T)/sizeof(base));
         }
     }
 };
 
+//- Disallow \c void
+template<> struct UPstream_basic_dataType<void> : UPstream_mpi_dataType<void>
+{
+    using base = void;
+    static std::streamsize size(std::streamsize n) noexcept { return n; }
+};
+
+
+// ------------------------------------------------------------------------- //
+
+//- UPstream fundamental/aliased/user-defined data type
+//- or a component aggregate of the same.
+//
+// True for the following conditions:
+// - The \c Type is directly supported
+// - The \c cmptType (eg, from VectorSpace) exists and is directly supported
+// - Fallback to byte-wise representation (ie, for contiguous)
+// .
+template<class T>
+struct UPstream_dataType
+:
+    std::bool_constant
+    <
+        UPstream_any_dataType<T>::value
+     || UPstream_any_dataType<typename pTraits_cmptType<T>::type>::value
+    >
+{
+    //- The underlying data type (if supported) or byte
+    using base = std::conditional_t
+    <
+        UPstream_any_dataType<T>::value,
+        typename UPstream_any_dataType<T>::base,   // <- non-aggregate
+        typename UPstream_any_dataType
+        <typename pTraits_cmptType<T>::type>::base  // <- aggregate
+    >;
+
+    //- The corresponding UPstream::dataTypes enumeration
+    static constexpr auto datatype_id =
+        UPstream_any_dataType<base>::datatype_id;
+
+    //- The size in terms of the number of base data elements
+    static std::streamsize size(std::streamsize n) noexcept
+    {
+        if constexpr (UPstream_any_dataType<T>::value)
+        {
+            // non-aggregate: no multiplier
+            return n;
+        }
+        else
+        {
+            // aggregate: with multiplier
+            return n*(sizeof(T)/sizeof(base));
+        }
+    }
+};
+
+//- Disallow \c void
+template<> struct UPstream_dataType<void> : UPstream_basic_dataType<void> {};
+
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace Foam
+// Reduction op-codes
+
+//- A supported UPstream (MPI) reduce/window operation type
+template<class BinaryOp>
+struct UPstream_opType : std::false_type
+{
+    static constexpr auto opcode_id = UPstream::opCodes::invalid;
+};
+
+//- Disallow \c void
+template<> struct UPstream_opType<void> : std::false_type
+{
+    static constexpr auto opcode_id = UPstream::opCodes::invalid;
+};
+
+//- Map minOp\<T\> to \c UPstream::opCodes::op_min
+template<class T>
+struct UPstream_opType<Foam::minOp<T>> : std::true_type
+{
+    static constexpr auto opcode_id = UPstream::opCodes::op_min;
+};
+
+//- Map maxOp\<T\> to \c UPstream::opCodes::op_max
+template<class T>
+struct UPstream_opType<Foam::maxOp<T>> : std::true_type
+{
+    static constexpr auto opcode_id = UPstream::opCodes::op_max;
+};
+
+//- Map sumOp\<T\> to \c UPstream::opCodes::op_sum
+template<class T>
+struct UPstream_opType<Foam::sumOp<T>> : std::true_type
+{
+    static constexpr auto opcode_id = UPstream::opCodes::op_sum;
+};
+
+//- Map plusOp\<T\> (same as sumOp\<T\>) to \c UPstream::opCodes::op_sum
+template<class T>
+struct UPstream_opType<Foam::plusOp<T>> : std::true_type
+{
+    static constexpr auto opcode_id = UPstream::opCodes::op_sum;
+};
+
+//- Map multiplyOp\<T\> to \c UPstream::opCodes::op_prod
+template<class T>
+struct UPstream_opType<Foam::multiplyOp<T>> : std::true_type
+{
+    static constexpr auto opcode_id = UPstream::opCodes::op_prod;
+};
+
+// NOTE (2025-02):
+// currently no mappings provided for
+// (op_bool_and, op_bool_or, op_bool_xor) until the calling semantics
+// have been properly defined
+
+
+// These are only viable for unsigned integral types,
+// probably not for signed integral types.
+// Be extra restrictive for now
+
+//- Map bitAndOp\<T\> to \c UPstream::opCodes::op_bit_and
+//- for integrals (signed or unsigned), but also allow void as "generic"
+template<class T>
+struct UPstream_opType<Foam::bitAndOp<T>>
+:
+    std::bool_constant<std::is_integral_v<T> || std::is_void_v<T>>
+{
+    static constexpr auto opcode_id = []() constexpr noexcept
+    {
+        if constexpr (std::is_integral_v<T> || std::is_void_v<T>)
+            return UPstream::opCodes::op_bit_and;
+        else
+            return UPstream::opCodes::invalid;
+    }();
+};
+
+//- Map bitOrOp\<T\> to \c UPstream::opCodes::op_bit_or
+//- for integrals (signed or unsigned), but also allow void as "generic"
+template<class T>
+struct UPstream_opType<Foam::bitOrOp<T>>
+:
+    std::bool_constant<std::is_integral_v<T> || std::is_void_v<T>>
+{
+    static constexpr auto opcode_id = []() constexpr noexcept
+    {
+        if constexpr (std::is_integral_v<T> || std::is_void_v<T>)
+            return UPstream::opCodes::op_bit_or;
+        else
+            return UPstream::opCodes::invalid;
+    }();
+};
 
+//- Map bitXorOp\<T\> to \c UPstream::opCodes::op_bit_xor
+//- for integrals (signed or unsigned), but also allow void as "generic"
+template<class T>
+struct UPstream_opType<Foam::bitXorOp<T>>
+:
+    std::bool_constant<std::is_integral_v<T> || std::is_void_v<T>>
+{
+    static constexpr auto opcode_id = []() constexpr noexcept
+    {
+        if constexpr (std::is_integral_v<T> || std::is_void_v<T>)
+            return UPstream::opCodes::op_bit_xor;
+        else
+            return UPstream::opCodes::invalid;
+    }();
+};
+
+
+//- Combined query of opType and the underlying basic data type
+//  This handling may be simplified in the future...
+template<class BinaryOp, class T>
+struct UPstream_data_opType
+:
+    std::bool_constant
+    <
+        UPstream_opType<BinaryOp>::value
+     && UPstream_basic_dataType<T>::value
+    >
+{
+    static constexpr auto opcode_id = []() constexpr noexcept
+    {
+        if constexpr
+        (
+            UPstream_opType<BinaryOp>::value
+         && UPstream_basic_dataType<T>::value
+        )
+            return UPstream_opType<BinaryOp>::opcode_id;
+        else
+            return UPstream::opCodes::invalid;
+    }();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Convenience Functions (FUTURE?)
+
+// inline bool is_UPstream_mpi_dataTypeCode(UPstream::dataTypes id) noexcept
+// {
+//     return
+//     (
+//         int(id) >= int(UPstream::opCodes::Basic_begin)
+//      && int(id)  < int(UPstream::opCodes::Basic_end)
+//     );
+// }
+//
+// inline bool is_UPstream_reduceOpCode(UPstream::opCodes id) noexcept
+// {
+//     return
+//     (
+//         int(id) >= int(UPstream::opCodes::Basic_begin)
+//      && int(id)  < int(UPstream::opCodes::Basic_end)
+//     );
+// }
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamWindow.H b/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamWindow.H
index aa3ef233f87ccf952718979c0889681d1191cd2a..54ce90aecc94b7c9c4b076f7c5bcb40dcb2499ef 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamWindow.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamWindow.H
@@ -137,6 +137,11 @@ public:
 
         //- Reset to default constructed value (MPI_WIN_NULL)
         void reset() noexcept;
+
+        //- The number of ranks associated with the window group.
+        //  The same as querying the original communicator, assuming the
+        //  communicator is available within the current code scope.
+        int size() const;
 };
 
 
diff --git a/src/OpenFOAM/db/error/IOerror.C b/src/OpenFOAM/db/error/IOerror.C
index 23029959ffcb24ae3c37985a59eb61e891b04190..b245976499b2b8a3f473d14a884beebaab4129aa 100644
--- a/src/OpenFOAM/db/error/IOerror.C
+++ b/src/OpenFOAM/db/error/IOerror.C
@@ -69,7 +69,7 @@ Foam::OSstream& Foam::IOerror::operator()
     const char* functionName,
     const char* sourceFileName,
     const int sourceFileLineNumber,
-    const string& ioFileName,
+    string ioFileName,
     const label ioStartLineNumber,
     const label ioEndLineNumber
 )
@@ -81,7 +81,7 @@ Foam::OSstream& Foam::IOerror::operator()
         sourceFileLineNumber
     );
 
-    ioFileName_ = ioFileName;
+    ioFileName_ = std::move(ioFileName);
     ioStartLineNumber_ = ioStartLineNumber;
     ioEndLineNumber_ = ioEndLineNumber;
 
@@ -296,7 +296,7 @@ void Foam::IOerror::write(Ostream& os, const bool withTitle) const
     }
 
 
-    const label lineNo = sourceFileLineNumber();
+    const auto lineNo = sourceFileLineNumber();
 
     if (messageStream::level >= 2 && lineNo && !functionName().empty())
     {
diff --git a/src/OpenFOAM/db/error/error.C b/src/OpenFOAM/db/error/error.C
index 22b81ca642fae6e7b1c33acc5d2b15227f935a34..f127e5f8aa3e057b6a2710176c69c88591e8abaf 100644
--- a/src/OpenFOAM/db/error/error.C
+++ b/src/OpenFOAM/db/error/error.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2014 OpenFOAM Foundation
-    Copyright (C) 2015-2023 OpenCFD Ltd.
+    Copyright (C) 2015-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -57,7 +57,7 @@ Foam::error::handlerNames
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
-bool Foam::error::master(const label communicator)
+bool Foam::error::master(const int communicator)
 {
     // Trap negative value for comm as 'default'. This avoids direct use
     // of UPstream::worldComm which may have not yet been initialised
@@ -177,12 +177,20 @@ Foam::error::~error() noexcept
 
 Foam::OSstream& Foam::error::operator()
 (
-    const string& functionName
+    string functionName,
+    const char* sourceFileName,
+    const int sourceFileLineNumber
 )
 {
-    functionName_ = functionName;
+    functionName_ = std::move(functionName);
     sourceFileName_.clear();
-    sourceFileLineNumber_ = -1;
+
+    if (sourceFileName)  // nullptr check
+    {
+        sourceFileName_.assign(sourceFileName);
+    }
+
+    sourceFileLineNumber_ = sourceFileLineNumber;
 
     return this->stream();
 }
@@ -198,14 +206,12 @@ Foam::OSstream& Foam::error::operator()
     functionName_.clear();
     sourceFileName_.clear();
 
-    if (functionName)
+    if (functionName)  // nullptr check
     {
-        // With nullptr protection
         functionName_.assign(functionName);
     }
-    if (sourceFileName)
+    if (sourceFileName)  // nullptr check
     {
-        // With nullptr protection
         sourceFileName_.assign(sourceFileName);
     }
     sourceFileLineNumber_ = sourceFileLineNumber;
@@ -214,22 +220,6 @@ Foam::OSstream& Foam::error::operator()
 }
 
 
-Foam::OSstream& Foam::error::operator()
-(
-    const string& functionName,
-    const char* sourceFileName,
-    const int sourceFileLineNumber
-)
-{
-    return operator()
-    (
-        functionName.c_str(),
-        sourceFileName,
-        sourceFileLineNumber
-    );
-}
-
-
 Foam::error::operator Foam::dictionary() const
 {
     dictionary errDict;
@@ -401,7 +391,7 @@ void Foam::error::write(Ostream& os, const bool withTitle) const
     os  << message().c_str();
 
 
-    const label lineNo = sourceFileLineNumber();
+    const auto lineNo = sourceFileLineNumber();
 
     if (messageStream::level >= 2 && lineNo && !functionName().empty())
     {
diff --git a/src/OpenFOAM/db/error/error.H b/src/OpenFOAM/db/error/error.H
index 22832dd8e4af951d156b0a293203f842515c509a..59d7128fd931e304fbf68dd7db63730a2af869fb 100644
--- a/src/OpenFOAM/db/error/error.H
+++ b/src/OpenFOAM/db/error/error.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2015 OpenFOAM Foundation
-    Copyright (C) 2015-2024 OpenCFD Ltd.
+    Copyright (C) 2015-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -89,7 +89,7 @@ protected:
 
         string functionName_;
         string sourceFileName_;
-        label sourceFileLineNumber_;
+        int sourceFileLineNumber_;
         bool throwing_;
         std::unique_ptr<OStringStream> messageStreamPtr_;
 
@@ -143,7 +143,7 @@ public:
         //
         //  \param communicator is the numbered MPI communicator.
         //      By default it uses UPstream::worldComm
-        static bool master(const label communicator = -1);
+        static bool master(const int communicator = -1);
 
         //- Test if an age warning should be emitted.
         //  \param version is the old version (YYMM) for determining the
@@ -180,7 +180,7 @@ public:
         }
 
         //- The currently defined source-file line number for output messages
-        label sourceFileLineNumber() const noexcept
+        int sourceFileLineNumber() const noexcept
         {
             return sourceFileLineNumber_;
         }
@@ -218,29 +218,24 @@ public:
             return this->stream();
         }
 
-        //- Define basic print message
+        //- Define basic print message with originating function name,
+        //- optionally with 'source file, line number'
         //  \return OSstream for further operations
         OSstream& operator()
         (
-            const string& functionName
+            string functionName,
+            const char* sourceFileName = nullptr,
+            const int sourceFileLineNumber = -1
         );
 
-        //- Define basic print message
+        //- Define basic print message with originating function name,
+        //- optionally with 'source file, line number'
         //  \return OSstream for further operations
         OSstream& operator()
         (
             const char* functionName,
-            const char* sourceFileName,
-            const int sourceFileLineNumber = 0
-        );
-
-        //- Define basic print message
-        //  \return OSstream for further operations
-        OSstream& operator()
-        (
-            const string& functionName,
-            const char* sourceFileName,
-            const int sourceFileLineNumber = 0
+            const char* sourceFileName = nullptr,
+            const int sourceFileLineNumber = -1
         );
 
 
@@ -361,7 +356,7 @@ public:
             const char* functionName,
             const char* sourceFileName,
             const int sourceFileLineNumber,
-            const string& ioFileName,
+            string ioFileName,
             const label ioStartLineNumber = -1,
             const label ioEndLineNumber = -1
         );
diff --git a/src/OpenFOAM/db/error/messageStream.C b/src/OpenFOAM/db/error/messageStream.C
index 04a3e907bdcda13cae30b1265ad1c14509387df1..62e26d30d21734b4a00d947521293ba0124d069e 100644
--- a/src/OpenFOAM/db/error/messageStream.C
+++ b/src/OpenFOAM/db/error/messageStream.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2017-2024 OpenCFD Ltd.
+    Copyright (C) 2017-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -49,21 +49,15 @@ int Foam::infoDetailLevel(1);
 
 Foam::messageStream::messageStream
 (
-    const char* title,
     errorSeverity severity,
     int maxErrors,
     bool use_stderr
 )
 :
-    title_(),
     severity_(severity),
     maxErrors_(maxErrors),
     errorCount_(0)
 {
-    if (title)
-    {
-        title_ = title;
-    }
     if (use_stderr)
     {
         severity_ |= errorSeverity::USE_STDERR;
@@ -71,12 +65,40 @@ Foam::messageStream::messageStream
 }
 
 
+Foam::messageStream::messageStream
+(
+    const char* title,
+    errorSeverity severity,
+    int maxErrors,
+    bool use_stderr
+)
+:
+    messageStream(severity, maxErrors, use_stderr)
+{
+    if (title)
+    {
+        title_ = title;
+    }
+}
+
+
+Foam::messageStream::messageStream
+(
+    string title,
+    errorSeverity severity,
+    int maxErrors,
+    bool use_stderr
+)
+:
+    messageStream(severity, maxErrors, use_stderr)
+{
+    title_ = std::move(title);
+}
+
+
 Foam::messageStream::messageStream(const dictionary& dict)
 :
-    title_(dict.get<string>("title")),
-    severity_(errorSeverity::FATAL),
-    maxErrors_(0),
-    errorCount_(0)
+    messageStream(dict.get<string>("title"), errorSeverity::FATAL)
 {}
 
 
@@ -153,7 +175,7 @@ Foam::OSstream& Foam::messageStream::stream
 }
 
 
-Foam::OSstream& Foam::messageStream::masterStream(const label communicator)
+Foam::OSstream& Foam::messageStream::masterStream(const int communicator)
 {
     if (UPstream::warnComm >= 0 && communicator != UPstream::warnComm)
     {
@@ -178,23 +200,6 @@ std::ostream& Foam::messageStream::stdStream()
 
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
-Foam::OSstream& Foam::messageStream::operator()
-(
-    const std::string& functionName
-)
-{
-    OSstream& os = this->stream();
-
-    if (!functionName.empty())
-    {
-        os  << nl
-            << "    From " << functionName.c_str() << nl;
-    }
-
-    return os;
-}
-
-
 Foam::OSstream& Foam::messageStream::deprecated
 (
     const int afterVersion,
@@ -239,10 +244,15 @@ Foam::OSstream& Foam::messageStream::deprecated
         {
             os  << "    From " << functionName << nl;
         }
-        if (sourceFileName)
+        if (sourceFileName)  // nullptr check
         {
-            os  << "    in file " << sourceFileName
-                << " at line " << sourceFileLineNumber << nl;
+            os  << "    in file " << sourceFileName;
+
+            if (sourceFileLineNumber >= 0)
+            {
+                os  << " at line " << sourceFileLineNumber;
+            }
+            os  << nl;
         }
     }
     os  << "    ";
@@ -253,18 +263,29 @@ Foam::OSstream& Foam::messageStream::deprecated
 
 Foam::OSstream& Foam::messageStream::operator()
 (
-    const char* functionName,
+    const std::string& functionName,
     const char* sourceFileName,
     const int sourceFileLineNumber
 )
 {
     OSstream& os = this->stream();
 
-    os  << nl
-        << "    From " << functionName << nl
-        << "    in file " << sourceFileName
-        << " at line " << sourceFileLineNumber << nl
-        << "    ";
+    if (!functionName.empty())
+    {
+        os  << nl
+            << "    From " << functionName.c_str() << nl;
+    }
+
+    if (sourceFileName)  // nullptr check
+    {
+        os  << "    in file " << sourceFileName;
+
+        if (sourceFileLineNumber >= 0)
+        {
+            os  << " at line " << sourceFileLineNumber;
+        }
+        os  << nl << "    ";
+    }
 
     return os;
 }
@@ -272,17 +293,31 @@ Foam::OSstream& Foam::messageStream::operator()
 
 Foam::OSstream& Foam::messageStream::operator()
 (
-    const std::string& functionName,
+    const char* functionName,
     const char* sourceFileName,
     const int sourceFileLineNumber
 )
 {
-    return operator()
-    (
-        functionName.c_str(),
-        sourceFileName,
-        sourceFileLineNumber
-    );
+    OSstream& os = this->stream();
+
+    if (functionName)  // nullptr check
+    {
+        os  << nl
+            << "    From " << functionName << nl;
+    }
+
+    if (sourceFileName)  // nullptr check
+    {
+        os  << "    in file " << sourceFileName;
+
+        if (sourceFileLineNumber >= 0)
+        {
+            os  << " at line " << sourceFileLineNumber;
+        }
+        os  << nl << "    ";
+    }
+
+    return os;
 }
 
 
diff --git a/src/OpenFOAM/db/error/messageStream.H b/src/OpenFOAM/db/error/messageStream.H
index e22d8d0abec143ec168947b85f822bee5f35fa90..6fe86394e9465e3f5cf8e9cd53cc2b9e8f25cfed 100644
--- a/src/OpenFOAM/db/error/messageStream.H
+++ b/src/OpenFOAM/db/error/messageStream.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2016-2024 OpenCFD Ltd.
+    Copyright (C) 2016-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -130,6 +130,14 @@ public:
 
     // Constructors
 
+        //- Construct untitled with given characteristics
+        explicit messageStream
+        (
+            errorSeverity severity,
+            int maxErrors = 0,
+            bool use_stderr = false
+        );
+
         //- Construct from components
         messageStream
         (
@@ -142,14 +150,11 @@ public:
         //- Construct from components
         messageStream
         (
-            const std::string& title,
+            string title,
             errorSeverity severity,
             int maxErrors = 0,
             bool use_stderr = false
-        )
-        :
-            messageStream(title.c_str(), severity, maxErrors, use_stderr)
-        {}
+        );
 
 
         //- Construct from dictionary as Fatal, extracting 'title'.
@@ -191,7 +196,7 @@ public:
 
         //- Return OSstream for output operations on the master process only,
         //- Snull on other processes.
-        OSstream& masterStream(const label communicator);
+        OSstream& masterStream(const int communicator);
 
         //- Return std::ostream for output operations.
         std::ostream& stdStream();
@@ -220,28 +225,23 @@ public:
             return this->stream();
         }
 
-        //- Report 'From function-name'
-        //  \return OSstream for further operations
-        OSstream& operator()
-        (
-            const std::string& functionName
-        );
-
-        //- Report 'From function-name, source file, line number'
+        //- Report 'From function-name',
+        //- optionally with 'source file, line number'
         //  \return OSstream for further operations
         OSstream& operator()
         (
-            const char* functionName,
-            const char* sourceFileName,
+            const std::string& functionName,
+            const char* sourceFileName = nullptr,
             const int sourceFileLineNumber = 0
         );
 
-        //- Report 'From function-name, source file, line number'
+        //- Report 'From function-name',
+        //- optionally with 'source file, line number'
         //  \return OSstream for further operations
         OSstream& operator()
         (
-            const std::string& functionName,
-            const char* sourceFileName,
+            const char* functionName,
+            const char* sourceFileName = nullptr,
             const int sourceFileLineNumber = 0
         );
 
diff --git a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C
index 583c4439710246ebc4abfc18b44a55a9cd8d08fc..b9053f08627c9d11c5109898c06c47029218b4b0 100644
--- a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C
+++ b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C
@@ -652,7 +652,7 @@ Type gAverage
 {
     label n = f1.size();
     Type s = sum(f1);
-    sumReduce(s, n, UPstream::msgType(), comm);
+    Foam::sumReduce(s, n, UPstream::msgType(), comm);
 
     if (n > 0)
     {
diff --git a/src/OpenFOAM/global/profiling/profilingPstream.C b/src/OpenFOAM/global/profiling/profilingPstream.C
index e7ad9050e0c2bb524383aae8022761532d6d4571..9189cd86ff490d825e31aa5e129c20c30f53cc8a 100644
--- a/src/OpenFOAM/global/profiling/profilingPstream.C
+++ b/src/OpenFOAM/global/profiling/profilingPstream.C
@@ -228,9 +228,9 @@ void Foam::profilingPstream::report(const int reportLevel)
 
         UPstream::mpiGather
         (
-            procValues.cdata_bytes(),   // Send
-            allTimes.data_bytes(),      // Recv
-            procValues.size_bytes(),    // Num send/recv data per rank
+            procValues.cdata(), // Send
+            allTimes.data(),    // Recv
+            procValues.size(),  // Num send/recv data per rank
             UPstream::commWorld()
         );
     }
@@ -247,9 +247,9 @@ void Foam::profilingPstream::report(const int reportLevel)
 
         UPstream::mpiGather
         (
-            procValues.cdata_bytes(),   // Send
-            allCounts.data_bytes(),     // Recv
-            procValues.size_bytes(),    // Num send/recv data per rank
+            procValues.cdata(), // Send
+            allCounts.data(),   // Recv
+            procValues.size(),  // Num send/recv data per rank
             UPstream::commWorld()
         );
     }
diff --git a/src/OpenFOAM/meshes/lduMesh/lduMesh.H b/src/OpenFOAM/meshes/lduMesh/lduMesh.H
index 493bbcaabc20b57af0da9d3a1c52660e89f68345..9c7e3045795e5712a70e8eef130214fbf61e314b 100644
--- a/src/OpenFOAM/meshes/lduMesh/lduMesh.H
+++ b/src/OpenFOAM/meshes/lduMesh/lduMesh.H
@@ -91,11 +91,10 @@ public:
 
             //- Helper: reduce with current communicator
             template<class T, class BinaryOp>
-            void reduce
-            (
-                T& Value,
-                const BinaryOp& bop
-            ) const;
+            void reduce(T& val, BinaryOp bop) const
+            {
+                Foam::reduce(val, bop, UPstream::msgType(), comm());
+            }
 
 
     // Info
@@ -117,10 +116,6 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#ifdef NoRepository
-    #include "lduMeshTemplates.C"
-#endif
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #endif
diff --git a/src/OpenFOAM/meshes/lduMesh/lduMeshTemplates.C b/src/OpenFOAM/meshes/lduMesh/lduMeshTemplates.C
index b44e74541732a177e0e8f72913104e7a93281deb..7cec1b4541d1553571d30afa2aac3b841f6c3d51 100644
--- a/src/OpenFOAM/meshes/lduMesh/lduMeshTemplates.C
+++ b/src/OpenFOAM/meshes/lduMesh/lduMeshTemplates.C
@@ -1,43 +1 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | www.openfoam.com
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-    Copyright (C) 2013 OpenFOAM Foundation
--------------------------------------------------------------------------------
-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 "lduMesh.H"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<class T, class BinaryOp>
-void Foam::lduMesh::reduce
-(
-    T& Value,
-    const BinaryOp& bop
-) const
-{
-    Foam::reduce(Value, bop, Pstream::msgType(), comm());
-}
-
-
-// ************************************************************************* //
+#warning File removed - left for old dependency check only
diff --git a/src/OpenFOAM/parallel/globalIndex/globalIndex.C b/src/OpenFOAM/parallel/globalIndex/globalIndex.C
index 95f64b161c6ca1f94a990b133e31d6909f1dffce..12113485a4feaedd1df3f941a347b7d961ac24e3 100644
--- a/src/OpenFOAM/parallel/globalIndex/globalIndex.C
+++ b/src/OpenFOAM/parallel/globalIndex/globalIndex.C
@@ -319,12 +319,7 @@ bool Foam::globalIndex::splitNodeOffsets
         allOffsets.resize_nocopy(numProc+1);
     }
 
-    UPstream::broadcast
-    (
-        allOffsets.data_bytes(),
-        allOffsets.size_bytes(),
-        interNodeComm
-    );
+    UPstream::broadcast(allOffsets.data(), allOffsets.size(), interNodeComm);
 
 
     if (FOAM_UNLIKELY(allOffsets.empty()))
diff --git a/src/OpenFOAM/primitives/Scalar/scalarImpl.H b/src/OpenFOAM/primitives/Scalar/scalarImpl.H
index 2517aa0aef379406f24ed7e02524aa93bc0511ca..0d1564dde5600894b06ac07b521ba82bd5ffc1f9 100644
--- a/src/OpenFOAM/primitives/Scalar/scalarImpl.H
+++ b/src/OpenFOAM/primitives/Scalar/scalarImpl.H
@@ -116,10 +116,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(Scalar val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(Scalar val) noexcept : p_(val) {}
 
         //- Read construct from Istream
         explicit pTraits(Istream& is);
@@ -128,16 +125,10 @@ public:
     // Member Functions
 
         //- Return the value
-        operator Scalar() const noexcept
-        {
-            return p_;
-        }
+        operator Scalar() const noexcept { return p_; }
 
         //- Access the value
-        operator Scalar&() noexcept
-        {
-            return p_;
-        }
+        operator Scalar&() noexcept { return p_; }
 };
 
 
diff --git a/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H b/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H
index 048f49bb407a64899cbc3622f9e1b63cfb59430a..c3f7163c4b73b39447d26e75fe6da14fa8f1c16d 100644
--- a/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H
+++ b/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H
@@ -158,7 +158,7 @@ public:
     // Constructors
 
         //- Construct initialized to zero
-        inline VectorSpace(const Foam::zero);
+        inline VectorSpace(Foam::zero);
 
         //- Copy construct
         inline VectorSpace(const VectorSpace<Form, Cmpt, Ncmpts>& vs);
@@ -174,10 +174,7 @@ public:
     // Member Functions
 
         //- The number of elements in the VectorSpace = Ncmpts.
-        static constexpr direction size() noexcept
-        {
-            return Ncmpts;
-        }
+        static constexpr direction size() noexcept { return Ncmpts; }
 
         inline const Cmpt& component(const direction) const;
         inline Cmpt& component(const direction);
@@ -186,10 +183,10 @@ public:
         inline void replace(const direction, const Cmpt&);
 
         //- Return const pointer to the first data element
-        inline const Cmpt* cdata() const noexcept;
+        const Cmpt* cdata() const noexcept { return v_; }
 
         //- Return pointer to the first data element
-        inline Cmpt* data() noexcept;
+        Cmpt* data() noexcept { return v_; }
 
         //- Assign all components to given value
         inline void fill(const Cmpt& s);
@@ -210,7 +207,7 @@ public:
         inline void operator+=(const VectorSpace<Form, Cmpt, Ncmpts>&);
         inline void operator-=(const VectorSpace<Form, Cmpt, Ncmpts>&);
 
-        inline void operator=(const Foam::zero);
+        inline void operator=(Foam::zero);
         inline void operator*=(const scalar);
         inline void operator/=(const scalar);
 
@@ -224,28 +221,25 @@ public:
         typedef const Cmpt* const_iterator;
 
 
-    // Random access iterator (non-const)
-
-        //- Return an iterator to begin of VectorSpace
-        inline iterator begin() noexcept;
-
-        //- Return an iterator to end of VectorSpace
-        inline iterator end() noexcept;
+    // Random access iterators (const and non-const)
 
+        //- Return an iterator (pointer) to begin of VectorSpace
+        iterator begin() noexcept { return v_; }
 
-    // Random access iterator (const)
+        //- Return const_iterator (const pointer) to begin of VectorSpace
+        const_iterator begin() const noexcept { return v_; }
 
-        //- Return const_iterator to begin of VectorSpace
-        inline const_iterator cbegin() const noexcept;
+        //- Return const_iterator (const pointer) to begin of VectorSpace
+        const_iterator cbegin() const noexcept { return v_; }
 
-        //- Return const_iterator to end of VectorSpace
-        inline const_iterator cend() const noexcept;
+        //- Return an iterator (pointer) to end of VectorSpace
+        iterator end() noexcept { return (v_ + Ncmpts); }
 
-        //- Return const_iterator to begin of VectorSpace
-        inline const_iterator begin() const noexcept;
+        //- Return const_iterator (const pointer) to end of VectorSpace
+        const_iterator end() const noexcept { return (v_ + Ncmpts); }
 
-        //- Return const_iterator to end of VectorSpace
-        inline const_iterator end() const noexcept;
+        //- Return const_iterator (const pointer) to end of VectorSpace
+        const_iterator cend() const noexcept { return (v_ + Ncmpts); }
 
 
     // IOstream Operators
diff --git a/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H b/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H
index 7f8bbd46dc17820ac248c2378485ab55f8d03503..772baa7d4fc2a04c4f161540e4608b0477bf8547 100644
--- a/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H
+++ b/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H
@@ -35,9 +35,9 @@ License
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline Foam::VectorSpace<Form, Cmpt, Ncmpts>::VectorSpace(const Foam::zero)
+inline Foam::VectorSpace<Form, Cmpt, Ncmpts>::VectorSpace(Foam::zero)
 {
-    VectorSpaceOps<Ncmpts,0>::eqOpS(*this, Zero, eqOp<Cmpt>());
+    VectorSpaceOps<Ncmpts>::fill_n(this->begin(), Cmpt(Foam::zero{}));
 }
 
 
@@ -47,7 +47,7 @@ inline Foam::VectorSpace<Form, Cmpt, Ncmpts>::VectorSpace
     const VectorSpace<Form, Cmpt, Ncmpts>& vs
 )
 {
-    VectorSpaceOps<Ncmpts,0>::eqOp(*this, vs, eqOp<Cmpt>());
+    VectorSpaceOps<Ncmpts>::copy_n(vs.cbegin(), this->begin());
 }
 
 
@@ -58,7 +58,7 @@ inline Foam::VectorSpace<Form, Cmpt, Ncmpts>::VectorSpace
     const VectorSpace<Form2, Cmpt2, Ncmpts>& vs
 )
 {
-    VectorSpaceOps<Ncmpts,0>::eqOp(*this, vs, eqOp<Cmpt>());
+    VectorSpaceOps<Ncmpts>::copy_n(vs.cbegin(), this->begin());
 }
 
 
@@ -163,7 +163,7 @@ inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::replace
 template<class Form, class Cmpt, Foam::direction Ncmpts>
 inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::fill(const Cmpt& s)
 {
-    VectorSpaceOps<Ncmpts,0>::eqOpS(*this, s, eqOp<Cmpt>());
+    VectorSpaceOps<Ncmpts>::fill_n(this->begin(), s);
 }
 
 
@@ -171,7 +171,7 @@ template<class Form, class Cmpt, Foam::direction Ncmpts>
 inline Form Foam::VectorSpace<Form, Cmpt, Ncmpts>::uniform(const Cmpt& s)
 {
     Form v;
-    VectorSpaceOps<Ncmpts,0>::eqOpS(v, s, eqOp<Cmpt>());
+    v.fill(s);
     return v;
 }
 
@@ -186,68 +186,6 @@ Foam::VectorSpace<Form, Cmpt, Ncmpts>::block() const
 }
 
 
-// * * * * * * * * * * * * * * * * Iterator  * * * * * * * * * * * * * * * * //
-
-template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::data() noexcept
-{
-    return v_;
-}
-
-
-template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::cdata() const noexcept
-{
-    return v_;
-}
-
-
-template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::begin() noexcept
-{
-    return v_;
-}
-
-
-template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::end() noexcept
-{
-    return (v_ + Ncmpts);
-}
-
-
-template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::cbegin()
-const noexcept
-{
-    return v_;
-}
-
-
-template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::cend()
-const noexcept
-{
-    return (v_ + Ncmpts);
-}
-
-
-template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::begin()
-const noexcept
-{
-    return v_;
-}
-
-
-template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::end()
-const noexcept
-{
-    return (v_ + Ncmpts);
-}
-
-
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 template<class Form, class Cmpt, Foam::direction Ncmpts>
@@ -346,7 +284,7 @@ inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::operator=
     const VectorSpace<Form, Cmpt, Ncmpts>& vs
 )
 {
-    VectorSpaceOps<Ncmpts,0>::eqOp(*this, vs, eqOp<Cmpt>());
+    VectorSpaceOps<Ncmpts>::copy_n(vs.cbegin(), this->begin());
 }
 
 
@@ -371,9 +309,9 @@ inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::operator-=
 
 
 template<class Form, class Cmpt, Foam::direction Ncmpts>
-inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::operator=(const Foam::zero)
+inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::operator=(Foam::zero)
 {
-    VectorSpaceOps<Ncmpts,0>::eqOpS(*this, 0, eqOp<Cmpt>());
+    VectorSpaceOps<Ncmpts>::fill_n(this->begin(), Cmpt(Foam::zero{}));
 }
 
 
diff --git a/src/OpenFOAM/primitives/VectorSpace/VectorSpaceOps.H b/src/OpenFOAM/primitives/VectorSpace/VectorSpaceOps.H
index c608971b26577b6fd8fd69b5c9835ccea2577d5a..bc1e7366880a1fe0a6c25e3b802b0e703524ebc3 100644
--- a/src/OpenFOAM/primitives/VectorSpace/VectorSpaceOps.H
+++ b/src/OpenFOAM/primitives/VectorSpace/VectorSpaceOps.H
@@ -43,9 +43,40 @@ namespace Foam
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 //- Recursive execution. Terminating at \<N\>, starting at index \<I\>
-template<direction N, direction I>
+template<direction N, direction I=0>
 struct VectorSpaceOps
 {
+    //- Somewhat equivalent to std::copy_n() but with templated loops.
+    //  \param [in] input indexable input data
+    //  \param [out] result indexable output data
+    template<class Input, class Output>
+    static inline void copy_n(Input input, Output result)
+    {
+        // if constexpr (I < N)
+        {
+            result[I] = input[I];
+            VectorSpaceOps<N, I+1>::copy_n(input, result);
+        }
+    }
+
+    //- Somewhat equivalent to std::fill_n() but with templated loops
+    //  \param [out] result indexable output data
+    //  \param val the value to assign for each entry
+    template<class Output, class T>
+    static inline void fill_n(Output result, const T& val)
+    {
+        // if constexpr (I < N)
+        {
+            result[I] = val;
+            VectorSpaceOps<N, I+1>::fill_n(result, val);
+        }
+    }
+
+    //- Apply the binary assignment operation to each vector-space
+    //- component.
+    //  \param [in,out] vs vector-space (indexed) data
+    //  \param s scalar/component data (non-indexed)
+    //  \param eo binary combine/assign operation
     template<class V, class S, class EqOp>
     static inline void eqOpS(V& vs, const S& s, EqOp eo)
     {
@@ -56,6 +87,10 @@ struct VectorSpaceOps
         }
     }
 
+    //- Apply the inplace binary reduction operation.
+    //  \param [in,out] s scalar or component data (non-indexed)
+    //  \param [in] vs input vector-space (indexed) data
+    //  \param eo binary combine/assign operation
     template<class S, class V, class EqOp>
     static inline void SeqOp(S& s, const V& vs, EqOp eo)
     {
@@ -66,6 +101,10 @@ struct VectorSpaceOps
         }
     }
 
+    //- Apply the inplace binary assignment operation to the components.
+    //  \param [in,out] vs1 vector-space (indexed) data
+    //  \param [in] vs2 second vector-space (indexed) data
+    //  \param eo binary combine/assign operation
     template<class V1, class V2, class EqOp>
     static inline void eqOp(V1& vs1, const V2& vs2, EqOp eo)
     {
@@ -76,34 +115,51 @@ struct VectorSpaceOps
         }
     }
 
-
-    template<class V, class V1, class S, class Op>
-    static inline void opVS(V& vs, const V1& vs1, const S& s, Op o)
+    //- Apply the binary operation between vector-space and scalar data
+    //- and assign the result.
+    //  \param [out] vs vector-space (indexed) data
+    //  \param [in] vs1 vector-space (indexed) data operand
+    //  \param [in] s scalar operand
+    //  \param bop binary operation
+    template<class V, class V1, class S, class BinaryOp>
+    static inline void opVS(V& vs, const V1& vs1, const S& s, BinaryOp bop)
     {
         // if constexpr (I < N)
         {
-            vs.v_[I] = o(vs1.v_[I], s);
-            VectorSpaceOps<N, I+1>::opVS(vs, vs1, s, o);
+            vs.v_[I] = bop(vs1.v_[I], s);
+            VectorSpaceOps<N, I+1>::opVS(vs, vs1, s, bop);
         }
     }
 
-    template<class V, class S, class V1, class Op>
-    static inline void opSV(V& vs, const S& s,  const V1& vs1, Op o)
+    //- Apply the binary operation between scalar and vector-space data
+    //- and assign the result.
+    //  \param [out] vs vector-space (indexed) data
+    //  \param [in] s scalar operand
+    //  \param [in] vs1 vector-space (indexed) data operand
+    //  \param bop binary operation
+    template<class V, class S, class V1, class BinaryOp>
+    static inline void opSV(V& vs, const S& s, const V1& vs1, BinaryOp bop)
     {
         // if constexpr (I < N)
         {
-            vs.v_[I] = o(s, vs1.v_[I]);
-            VectorSpaceOps<N, I+1>::opSV(vs, s, vs1, o);
+            vs.v_[I] = bop(s, vs1.v_[I]);
+            VectorSpaceOps<N, I+1>::opSV(vs, s, vs1, bop);
         }
     }
 
-    template<class V, class V1, class Op>
-    static inline void op(V& vs, const V1& vs1, const V1& vs2, Op o)
+    //- Apply the binary operation between two vector-space data
+    //- and assign the result.
+    //  \param [out] vs vector-space (indexed) data
+    //  \param [in] vs1 vector-space (indexed) data operand
+    //  \param [in] vs2 vector-space (indexed) data operand
+    //  \param bop binary operation
+    template<class V, class V1, class BinaryOp>
+    static inline void op(V& vs, const V1& vs1, const V1& vs2, BinaryOp bop)
     {
         // if constexpr (I < N)
         {
-            vs.v_[I] = o(vs1.v_[I], vs2.v_[I]);
-            VectorSpaceOps<N, I+1>::op(vs, vs1, vs2, o);
+            vs.v_[I] = bop(vs1.v_[I], vs2.v_[I]);
+            VectorSpaceOps<N, I+1>::op(vs, vs1, vs2, bop);
         }
     }
 };
@@ -115,6 +171,12 @@ struct VectorSpaceOps
 template<direction N>
 struct VectorSpaceOps<N, N>
 {
+    template<class Input, class Output>
+    static inline void copy_n(Input, Output) {}
+
+    template<class Output, class T>
+    static inline void fill_n(Output, const T&) {}
+
     template<class V, class S, class EqOp>
     static inline void eqOpS(V&, const S&, EqOp) {}
 
@@ -124,14 +186,14 @@ struct VectorSpaceOps<N, N>
     template<class V1, class V2, class EqOp>
     static inline void eqOp(V1&, const V2&, EqOp) {}
 
-    template<class V, class V1, class S, class Op>
-    static inline void opVS(V& vs, const V1&, const S&, Op) {}
+    template<class V, class V1, class S, class BinaryOp>
+    static inline void opVS(V&, const V1&, const S&, BinaryOp) {}
 
-    template<class V, class S, class V1, class Op>
-    static inline void opSV(V& vs, const S&, const V1&, Op) {}
+    template<class V, class S, class V1, class BinaryOp>
+    static inline void opSV(V&, const S&, const V1&, BinaryOp) {}
 
-    template<class V, class V1, class Op>
-    static inline void op(V& vs, const V1&, const V1&, Op) {}
+    template<class V, class V1, class BinaryOp>
+    static inline void op(V&, const V1&, const V1&, BinaryOp) {}
 };
 
 
diff --git a/src/OpenFOAM/primitives/bools/bool/bool.H b/src/OpenFOAM/primitives/bools/bool/bool.H
index 0e791d0404b2b5d7954b10926c44852789816857..090fae4137570279d43b6e90afe30e73ce5a03bf 100644
--- a/src/OpenFOAM/primitives/bools/bool/bool.H
+++ b/src/OpenFOAM/primitives/bools/bool/bool.H
@@ -102,10 +102,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(bool val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(bool val) noexcept : p_(val) {}
 
         //- Read construct from Istream
         explicit pTraits(Istream& is);
diff --git a/src/OpenFOAM/primitives/chars/char/char.H b/src/OpenFOAM/primitives/chars/char/char.H
index 959e0f075c3747625bb9a6bdc963ec581785d7a9..25ecd83f388ae9011cd8cd7c49beed0f41406f04 100644
--- a/src/OpenFOAM/primitives/chars/char/char.H
+++ b/src/OpenFOAM/primitives/chars/char/char.H
@@ -94,10 +94,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(char val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(char val) noexcept : p_(val) {}
 
         //- Read construct from Istream
         explicit pTraits(Istream& is);
diff --git a/src/OpenFOAM/primitives/complex/complex.H b/src/OpenFOAM/primitives/complex/complex.H
index 7749aae7adf027e7314cc7e24da0786ff192d70e..b04f76b4afbbac665197c05c949ace98e831333e 100644
--- a/src/OpenFOAM/primitives/complex/complex.H
+++ b/src/OpenFOAM/primitives/complex/complex.H
@@ -288,10 +288,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(const complex& val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(const complex& val) noexcept : p_(val) {}
 
 
         //- Read construct from Istream
diff --git a/src/OpenFOAM/primitives/ints/int16/int16.C b/src/OpenFOAM/primitives/ints/int16/int16.C
index 27a16f57f64acf1e549d2f21dbf4d8cf1686d4b8..1fc4b094288a7d253831d75d70743f186dc32177 100644
--- a/src/OpenFOAM/primitives/ints/int16/int16.C
+++ b/src/OpenFOAM/primitives/ints/int16/int16.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,6 +29,19 @@ License
 #include "int32.H"
 #include "IOstreams.H"
 
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const char* const Foam::pTraits<int16_t>::typeName = "int16";
+const char* const Foam::pTraits<int16_t>::componentNames[] = { "" };
+
+const int16_t Foam::pTraits<int16_t>::zero = 0;
+const int16_t Foam::pTraits<int16_t>::one = 1;
+const int16_t Foam::pTraits<int16_t>::min = INT16_MIN;
+const int16_t Foam::pTraits<int16_t>::max = INT16_MAX;
+const int16_t Foam::pTraits<int16_t>::rootMin = INT16_MIN;
+const int16_t Foam::pTraits<int16_t>::rootMax = INT16_MAX;
+
+
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
 
 Foam::Istream& Foam::operator>>(Istream& is, int16_t& val)
diff --git a/src/OpenFOAM/primitives/ints/int16/int16.H b/src/OpenFOAM/primitives/ints/int16/int16.H
index 21587e88e6b2d6799fd389b270ca7c65c73e32a2..44f6fc96c5acc9ffb9d35959151929625d78f9c1 100644
--- a/src/OpenFOAM/primitives/ints/int16/int16.H
+++ b/src/OpenFOAM/primitives/ints/int16/int16.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -73,6 +73,67 @@ Istream& operator>>(Istream& is, int16_t& val);
 Ostream& operator<<(Ostream& os, const int16_t val);
 
 
+/*---------------------------------------------------------------------------*\
+                       Specialization pTraits<int16_t>
+\*---------------------------------------------------------------------------*/
+
+//- Template specialization for pTraits<int16_t>
+template<>
+class pTraits<int16_t>
+{
+    int16_t p_;
+
+public:
+
+    // Typedefs
+
+        //- Component type
+        typedef int16_t cmptType;
+
+
+    // Member Constants
+
+        //- Dimensionality of space
+        static constexpr direction dim = 3;
+
+        //- Rank of int16_t is 0
+        static constexpr direction rank = 0;
+
+        //- Number of components in int16_t is 1
+        static constexpr direction nComponents = 1;
+
+
+    // Static Data Members
+
+        static const char* const typeName;
+        static const char* const componentNames[];
+        static const int16_t zero;
+        static const int16_t one;
+        static const int16_t min;
+        static const int16_t max;
+        static const int16_t rootMax;
+        static const int16_t rootMin;
+
+
+    // Constructors
+
+        //- Copy construct from primitive
+        explicit pTraits(int16_t val) noexcept : p_(val) {}
+
+        //- Read construct from Istream
+        explicit pTraits(Istream& is);
+
+
+    // Member Functions
+
+        //- Return the value
+        operator int16_t() const noexcept { return p_; }
+
+        //- Access the value
+        operator int16_t&() noexcept { return p_; }
+};
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/src/OpenFOAM/primitives/ints/int32/int32.C b/src/OpenFOAM/primitives/ints/int32/int32.C
index c1606ab63eb28073fbe878456a518137b478add5..ccfe8eebbc1feece70cfc36a198df61ddaa90ae2 100644
--- a/src/OpenFOAM/primitives/ints/int32/int32.C
+++ b/src/OpenFOAM/primitives/ints/int32/int32.C
@@ -36,8 +36,8 @@ const int32_t Foam::pTraits<int32_t>::zero = 0;
 const int32_t Foam::pTraits<int32_t>::one = 1;
 const int32_t Foam::pTraits<int32_t>::min = INT32_MIN;
 const int32_t Foam::pTraits<int32_t>::max = INT32_MAX;
-const int32_t Foam::pTraits<int32_t>::rootMin = pTraits<int32_t>::min;
-const int32_t Foam::pTraits<int32_t>::rootMax = pTraits<int32_t>::max;
+const int32_t Foam::pTraits<int32_t>::rootMin = INT32_MIN;
+const int32_t Foam::pTraits<int32_t>::rootMax = INT32_MAX;
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/primitives/ints/int32/int32.H b/src/OpenFOAM/primitives/ints/int32/int32.H
index bd97eae76b247e21ed07b973d1575c0f2e247eb5..39d75b155bc50f9fba48f29ae3a7b07569334d4d 100644
--- a/src/OpenFOAM/primitives/ints/int32/int32.H
+++ b/src/OpenFOAM/primitives/ints/int32/int32.H
@@ -181,10 +181,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(int32_t val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(int32_t val) noexcept : p_(val) {}
 
         //- Read construct from Istream
         explicit pTraits(Istream& is);
diff --git a/src/OpenFOAM/primitives/ints/int64/int64.C b/src/OpenFOAM/primitives/ints/int64/int64.C
index 30ad0534e2a050276f1cd3da65be25621b654fbe..051a8a7e5f8bcdb59372e85169b929b8b242382e 100644
--- a/src/OpenFOAM/primitives/ints/int64/int64.C
+++ b/src/OpenFOAM/primitives/ints/int64/int64.C
@@ -36,8 +36,8 @@ const int64_t Foam::pTraits<int64_t>::zero = 0;
 const int64_t Foam::pTraits<int64_t>::one = 1;
 const int64_t Foam::pTraits<int64_t>::min = INT64_MIN;
 const int64_t Foam::pTraits<int64_t>::max = INT64_MAX;
-const int64_t Foam::pTraits<int64_t>::rootMin = pTraits<int64_t>::min;
-const int64_t Foam::pTraits<int64_t>::rootMax = pTraits<int64_t>::max;
+const int64_t Foam::pTraits<int64_t>::rootMin = INT64_MIN;
+const int64_t Foam::pTraits<int64_t>::rootMax = INT64_MAX;
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/primitives/ints/int64/int64.H b/src/OpenFOAM/primitives/ints/int64/int64.H
index 49766d262127b262320a94cae97ea7b5ec5940ae..e88716e14aa6f0eb18ce6666d2ccf91c0f7ef3dc 100644
--- a/src/OpenFOAM/primitives/ints/int64/int64.H
+++ b/src/OpenFOAM/primitives/ints/int64/int64.H
@@ -180,10 +180,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(int64_t val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(int64_t val) noexcept : p_(val) {}
 
         //- Read construct from Istream
         explicit pTraits(Istream& is);
diff --git a/src/OpenFOAM/primitives/ints/int8/int8.H b/src/OpenFOAM/primitives/ints/int8/int8.H
index 734b5323a957cc1975980d0736f273193cf0e970..91ca4a678c6d3fbc2731d5a75df278ed38b7c691 100644
--- a/src/OpenFOAM/primitives/ints/int8/int8.H
+++ b/src/OpenFOAM/primitives/ints/int8/int8.H
@@ -124,10 +124,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(int8_t val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(int8_t val) noexcept : p_(val) {}
 
         //- Read construct from Istream
         explicit pTraits(Istream& is);
diff --git a/src/OpenFOAM/primitives/ints/uint16/uint16.C b/src/OpenFOAM/primitives/ints/uint16/uint16.C
index 1b4516ae4952f11df523bdde06cfe3dacccc46f1..91d1acbc392692375b6fc8f24b6cc99f59215066 100644
--- a/src/OpenFOAM/primitives/ints/uint16/uint16.C
+++ b/src/OpenFOAM/primitives/ints/uint16/uint16.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,6 +29,19 @@ License
 #include "int32.H"
 #include "IOstreams.H"
 
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const char* const Foam::pTraits<uint16_t>::typeName = "uint16";
+const char* const Foam::pTraits<uint16_t>::componentNames[] = { "" };
+
+const uint16_t Foam::pTraits<uint16_t>::zero = 0;
+const uint16_t Foam::pTraits<uint16_t>::one = 1;
+const uint16_t Foam::pTraits<uint16_t>::min = 0;
+const uint16_t Foam::pTraits<uint16_t>::max = UINT16_MAX;
+const uint16_t Foam::pTraits<uint16_t>::rootMin = 0;
+const uint16_t Foam::pTraits<uint16_t>::rootMax = UINT16_MAX;
+
+
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
 
 Foam::Istream& Foam::operator>>(Istream& is, uint16_t& val)
diff --git a/src/OpenFOAM/primitives/ints/uint16/uint16.H b/src/OpenFOAM/primitives/ints/uint16/uint16.H
index 14b9b249fd13139ae794482709975d4b67d45456..4ab782dd6c208a2e5f546070303b44bd56f21343 100644
--- a/src/OpenFOAM/primitives/ints/uint16/uint16.H
+++ b/src/OpenFOAM/primitives/ints/uint16/uint16.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -74,6 +74,67 @@ Istream& operator>>(Istream& is, uint16_t& val);
 Ostream& operator<<(Ostream& os, const uint16_t val);
 
 
+/*---------------------------------------------------------------------------*\
+                       Specialization pTraits<uint16_t>
+\*---------------------------------------------------------------------------*/
+
+//- Template specialization for pTraits<uint16_t>
+template<>
+class pTraits<uint16_t>
+{
+    uint16_t p_;
+
+public:
+
+    // Typedefs
+
+        //- Component type
+        typedef uint16_t cmptType;
+
+
+    // Member Constants
+
+        //- Dimensionality of space
+        static constexpr direction dim = 3;
+
+        //- Rank of uint16_t is 0
+        static constexpr direction rank = 0;
+
+        //- Number of components in uint16_t is 1
+        static constexpr direction nComponents = 1;
+
+
+    // Static Data Members
+
+        static const char* const typeName;
+        static const char* const componentNames[];
+        static const uint16_t zero;
+        static const uint16_t one;
+        static const uint16_t min;
+        static const uint16_t max;
+        static const uint16_t rootMax;
+        static const uint16_t rootMin;
+
+
+    // Constructors
+
+        //- Copy construct from primitive
+        explicit pTraits(uint16_t val) noexcept : p_(val) {}
+
+        //- Read construct from Istream
+        explicit pTraits(Istream& is);
+
+
+    // Member Functions
+
+        //- Return the value
+        operator uint16_t() const noexcept { return p_; }
+
+        //- Access the value
+        operator uint16_t&() noexcept { return p_; }
+};
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/src/OpenFOAM/primitives/ints/uint32/uint32.C b/src/OpenFOAM/primitives/ints/uint32/uint32.C
index aa728626e01784ea35cfb028fba4e259d8baf4a2..9c179acadbda2939580c781c314772dfbec6e19f 100644
--- a/src/OpenFOAM/primitives/ints/uint32/uint32.C
+++ b/src/OpenFOAM/primitives/ints/uint32/uint32.C
@@ -37,7 +37,7 @@ const uint32_t Foam::pTraits<uint32_t>::one = 1;
 const uint32_t Foam::pTraits<uint32_t>::min = 0;
 const uint32_t Foam::pTraits<uint32_t>::max = UINT32_MAX;
 const uint32_t Foam::pTraits<uint32_t>::rootMin = 0;
-const uint32_t Foam::pTraits<uint32_t>::rootMax = pTraits<uint32_t>::max;
+const uint32_t Foam::pTraits<uint32_t>::rootMax = UINT32_MAX;
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/primitives/ints/uint32/uint32.H b/src/OpenFOAM/primitives/ints/uint32/uint32.H
index ba0e7e588726f19f49896b7ced229fb70cafe5d8..7d2f1e01e99964c66c81f3132af6b5a569b83df9 100644
--- a/src/OpenFOAM/primitives/ints/uint32/uint32.H
+++ b/src/OpenFOAM/primitives/ints/uint32/uint32.H
@@ -162,10 +162,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(uint32_t val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(uint32_t val) noexcept : p_(val) {}
 
         //- Read construct from Istream
         explicit pTraits(Istream& is);
diff --git a/src/OpenFOAM/primitives/ints/uint64/uint64.C b/src/OpenFOAM/primitives/ints/uint64/uint64.C
index ab6269623485af5bac63652ff21f8198e35476fd..bf5dbb4ecbf1fc16ec87117bf341e201684965be 100644
--- a/src/OpenFOAM/primitives/ints/uint64/uint64.C
+++ b/src/OpenFOAM/primitives/ints/uint64/uint64.C
@@ -37,7 +37,7 @@ const uint64_t Foam::pTraits<uint64_t>::one = 1;
 const uint64_t Foam::pTraits<uint64_t>::min = 0;
 const uint64_t Foam::pTraits<uint64_t>::max = UINT64_MAX;
 const uint64_t Foam::pTraits<uint64_t>::rootMin = 0;
-const uint64_t Foam::pTraits<uint64_t>::rootMax = pTraits<uint64_t>::max;
+const uint64_t Foam::pTraits<uint64_t>::rootMax = UINT64_MAX;
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/primitives/ints/uint64/uint64.H b/src/OpenFOAM/primitives/ints/uint64/uint64.H
index 98e6346d6b6bbf3df01c1758ffcef9cd18d66d03..3c352e4148bbc6cd7d7d307bcf051977e7c9921a 100644
--- a/src/OpenFOAM/primitives/ints/uint64/uint64.H
+++ b/src/OpenFOAM/primitives/ints/uint64/uint64.H
@@ -170,10 +170,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(uint64_t val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(uint64_t val) noexcept : p_(val) {}
 
         //- Read construct from Istream
         explicit pTraits(Istream& is);
diff --git a/src/OpenFOAM/primitives/ints/uint8/uint8.H b/src/OpenFOAM/primitives/ints/uint8/uint8.H
index b17d19f72939404ad7a73a1fb303c2f8fb701ce1..4fc6c28f36666620e525fc6a7b53f965c20defbe 100644
--- a/src/OpenFOAM/primitives/ints/uint8/uint8.H
+++ b/src/OpenFOAM/primitives/ints/uint8/uint8.H
@@ -123,10 +123,7 @@ public:
     // Constructors
 
         //- Copy construct from primitive
-        explicit pTraits(uint8_t val) noexcept
-        :
-            p_(val)
-        {}
+        explicit pTraits(uint8_t val) noexcept : p_(val) {}
 
         //- Read construct from Istream
         explicit pTraits(Istream& is);
@@ -135,16 +132,10 @@ public:
     // Member Functions
 
         //- Return the value
-        operator uint8_t() const noexcept
-        {
-            return p_;
-        }
+        operator uint8_t() const noexcept { return p_; }
 
         //- Access the value
-        operator uint8_t&() noexcept
-        {
-            return p_;
-        }
+        operator uint8_t&() noexcept { return p_; }
 };
 
 
diff --git a/src/Pstream/dummy/UIPBstreamRead.C b/src/Pstream/dummy/UIPBstreamRead.C
index 31e0f0743fa0fd7ab502edbb20f9fb9822bb4d31..2a30bd5cbb07489fdaaef94c635298332cdbb49f 100644
--- a/src/Pstream/dummy/UIPBstreamRead.C
+++ b/src/Pstream/dummy/UIPBstreamRead.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2024 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -35,19 +35,4 @@ void Foam::UIPBstream::bufferIPCrecv()
 }
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-std::streamsize Foam::UIPBstream::read
-(
-    const int rootProcNo,
-    char* buf,
-    const std::streamsize bufSize,
-    const label comm
-)
-{
-    NotImplemented;
-    return 0;
-}
-
-
 // ************************************************************************* //
diff --git a/src/Pstream/dummy/UIPstreamRead.C b/src/Pstream/dummy/UIPstreamRead.C
index c8b7286fdf623ef7c04afb15c7b663830431cdfb..396a7a204b7268faa30eb546a469864458f6ef40 100644
--- a/src/Pstream/dummy/UIPstreamRead.C
+++ b/src/Pstream/dummy/UIPstreamRead.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2015 OpenFOAM Foundation
-    Copyright (C) 2021-2024 OpenCFD Ltd.
+    Copyright (C) 2021-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,24 +28,17 @@ License
 
 #include "UIPstream.H"
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::UIPstream::bufferIPCrecv()
-{
-    NotImplemented;
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * Protected Static Member Functions * * * * * * * * * * //
 
-std::streamsize Foam::UIPstream::read
+std::streamsize Foam::UPstream::mpi_receive
 (
     const UPstream::commsTypes commsType,
+    void* buf,
+    std::streamsize count,
+    const UPstream::dataTypes dataTypeId,
     const int fromProcNo,
-    char* buf,
-    const std::streamsize bufSize,
     const int tag,
-    const label communicator,
+    const int communicator,
     UPstream::Request* req
 )
 {
@@ -54,4 +47,12 @@ std::streamsize Foam::UIPstream::read
 }
 
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::UIPstream::bufferIPCrecv()
+{
+    NotImplemented;
+}
+
+
 // ************************************************************************* //
diff --git a/src/Pstream/dummy/UOPBstreamWrite.C b/src/Pstream/dummy/UOPBstreamWrite.C
index 72c702f0343345bb1b1ffd00ce113b75bb474a2b..794791fc6140bf85bec9b7c6468c2e7798967adb 100644
--- a/src/Pstream/dummy/UOPBstreamWrite.C
+++ b/src/Pstream/dummy/UOPBstreamWrite.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2023 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -38,17 +38,8 @@ bool Foam::UOPBstream::bufferIPCsend()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-bool Foam::UOPBstream::write
-(
-    const int rootProcNo,
-    const char* buf,
-    const std::streamsize bufSize,
-    const label comm
-)
-{
-    NotImplemented;
-    return false;
-}
+void Foam::UOPBstream::send(Foam::zero, const int communicator)
+{}
 
 
 // ************************************************************************* //
diff --git a/src/Pstream/dummy/UOPstreamWrite.C b/src/Pstream/dummy/UOPstreamWrite.C
index 24078ca9244d150dc9828a570d9f5fc5a2edaafe..b6f2a61f6dbd75c04d8b78f145c889de411ad7c5 100644
--- a/src/Pstream/dummy/UOPstreamWrite.C
+++ b/src/Pstream/dummy/UOPstreamWrite.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2015 OpenFOAM Foundation
-    Copyright (C) 2022-2023 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -37,16 +37,17 @@ bool Foam::UOPstream::bufferIPCsend()
 }
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * Protected Static Member Functions * * * * * * * * * * //
 
-bool Foam::UOPstream::write
+bool Foam::UPstream::mpi_send
 (
     const UPstream::commsTypes commsType,
+    const void* buf,
+    std::streamsize count,
+    const UPstream::dataTypes dataTypeId,
     const int toProcNo,
-    const char* buf,
-    const std::streamsize bufSize,
     const int tag,
-    const label communicator,
+    const int communicator,
     UPstream::Request* req,
     const UPstream::sendModes sendMode
 )
diff --git a/src/Pstream/dummy/UPstreamBroadcast.C b/src/Pstream/dummy/UPstreamBroadcast.C
index 079512f255ee5777047a973b7aec9f8751ef8b0f..0e87b5b50bc7ac98913afefbfdc0d6e25d1b64c2 100644
--- a/src/Pstream/dummy/UPstreamBroadcast.C
+++ b/src/Pstream/dummy/UPstreamBroadcast.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,17 +27,17 @@ License
 
 #include "UPstream.H"
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * Protected Static Member Functions * * * * * * * * * * //
 
-bool Foam::UPstream::broadcast
+bool Foam::UPstream::mpi_broadcast
 (
-    char* buf,
-    const std::streamsize bufSize,
-    const label comm,
-    const int rootProcNo
+    void* buf,
+    std::streamsize count,
+    const UPstream::dataTypes dataTypeId,
+    const int communicator
 )
 {
-    // Nothing to do - ignore
+    // Treat like serial
     return true;
 }
 
diff --git a/src/Pstream/dummy/UPstreamCommunicator.C b/src/Pstream/dummy/UPstreamCommunicator.C
index e7c713f85c5dee460d74bd7863be5e3fb2f7a2f1..29055a6da2d2579cd16174039dcc8de271e1ded4 100644
--- a/src/Pstream/dummy/UPstreamCommunicator.C
+++ b/src/Pstream/dummy/UPstreamCommunicator.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2024 OpenCFD Ltd.
+    Copyright (C) 2024-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -38,7 +38,7 @@ Foam::UPstream::Communicator::Communicator() noexcept
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 Foam::UPstream::Communicator
-Foam::UPstream::Communicator::lookup(const label comm)
+Foam::UPstream::Communicator::lookup(const int comm)
 {
     return UPstream::Communicator(nullptr);
 }
@@ -56,4 +56,10 @@ void Foam::UPstream::Communicator::reset() noexcept
 {}
 
 
+int Foam::UPstream::Communicator::size() const
+{
+    return 0;
+}
+
+
 // ************************************************************************* //
diff --git a/src/Pstream/dummy/UPstreamGatherScatter.C b/src/Pstream/dummy/UPstreamGatherScatter.C
index 9034fc75f39e4c6b9eb77ee84265a5f6c28a2fdc..4d4e3992ef5cbb68fba1dcaaadf47329198872ca 100644
--- a/src/Pstream/dummy/UPstreamGatherScatter.C
+++ b/src/Pstream/dummy/UPstreamGatherScatter.C
@@ -26,91 +26,76 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "UPstream.H"
-#include <cstring>  // memmove
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#undef  Pstream_CommonRoutines
-#define Pstream_CommonRoutines(Type)                                          \
-                                                                              \
-void Foam::UPstream::mpiGather                                                \
-(                                                                             \
-    const Type* sendData,                                                     \
-    Type* recvData,                                                           \
-    int count,                                                                \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    if (sendData && recvData)                                                 \
-    {                                                                         \
-        std::memmove(recvData, sendData, count*sizeof(Type));                 \
-    }                                                                         \
-}                                                                             \
-                                                                              \
-                                                                              \
-void Foam::UPstream::mpiScatter                                               \
-(                                                                             \
-    const Type* sendData,                                                     \
-    Type* recvData,                                                           \
-    int count,                                                                \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    if (sendData && recvData)                                                 \
-    {                                                                         \
-        std::memmove(recvData, sendData, count*sizeof(Type));                 \
-    }                                                                         \
-}                                                                             \
-                                                                              \
-                                                                              \
-void Foam::UPstream::mpiAllGather                                             \
-(                                                                             \
-    Type* allData,                                                            \
-    int count,                                                                \
-    const label comm                                                          \
-)                                                                             \
-{}                                                                            \
-                                                                              \
-                                                                              \
-void Foam::UPstream::mpiGatherv                                               \
-(                                                                             \
-    const Type* sendData,                                                     \
-    int sendCount,                                                            \
-                                                                              \
-    Type* recvData,                                                           \
-    const UList<int>& recvCounts,                                             \
-    const UList<int>& recvOffsets,                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    /* recvCounts[0] may be invalid - use sendCount instead */                \
-    std::memmove(recvData, sendData, sendCount*sizeof(Type));                 \
-}                                                                             \
-                                                                              \
-void Foam::UPstream::mpiScatterv                                              \
-(                                                                             \
-    const Type* sendData,                                                     \
-    const UList<int>& sendCounts,                                             \
-    const UList<int>& sendOffsets,                                            \
-                                                                              \
-    Type* recvData,                                                           \
-    int recvCount,                                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    std::memmove(recvData, sendData, recvCount*sizeof(Type));                 \
-}
-
-
-//TDB: Pstream_CommonRoutines(bool);
-Pstream_CommonRoutines(char);
-Pstream_CommonRoutines(int32_t);
-Pstream_CommonRoutines(int64_t);
-Pstream_CommonRoutines(uint32_t);
-Pstream_CommonRoutines(uint64_t);
-Pstream_CommonRoutines(float);
-Pstream_CommonRoutines(double);
-
-#undef Pstream_CommonRoutines
+void Foam::UPstream::mpi_gather
+(
+    const void* sendData,
+    void* recvData,
+    int count,
+    const UPstream::dataTypes dataTypeId,
+
+    const int communicator,
+    UPstream::Request* req
+)
+{}
+
+
+void Foam::UPstream::mpi_scatter
+(
+    const void* sendData,
+    void* recvData,
+    int count,
+    const UPstream::dataTypes dataTypeId,
+
+    const int communicator,
+    UPstream::Request* req
+)
+{}
+
+
+void Foam::UPstream::mpi_allgather
+(
+    void* allData,
+    int count,
+    const UPstream::dataTypes dataTypeId,
+
+    const int communicator,
+    UPstream::Request* req
+)
+{}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+void Foam::UPstream::mpi_gatherv
+(
+    const void* sendData,
+    int sendCount,
+    void* recvData,
+    const UList<int>& recvCounts,
+    const UList<int>& recvOffsets,
+
+    const UPstream::dataTypes dataTypeId,
+    const int communicator
+)
+{}
+
+
+void Foam::UPstream::mpi_scatterv
+(
+    const void* sendData,
+    const UList<int>& sendCounts,
+    const UList<int>& sendOffsets,
+
+    void* recvData,
+    int recvCount,
+
+    const UPstream::dataTypes dataTypeId,
+    const int communicator
+)
+{}
+
 
 // ************************************************************************* //
diff --git a/src/Pstream/dummy/UPstreamReduce.C b/src/Pstream/dummy/UPstreamReduce.C
index 9572d0e52d19ac24a88308aaff3cfaa8e0e7fbd5..610b06e3579fa65b6d8097155f26a3d521beb950 100644
--- a/src/Pstream/dummy/UPstreamReduce.C
+++ b/src/Pstream/dummy/UPstreamReduce.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2023 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,186 +28,60 @@ License
 #include "Pstream.H"
 #include "PstreamReduceOps.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
 
 // Special reductions for bool
 
-void Foam::UPstream::reduceAnd(bool& value, const label comm)
+void Foam::UPstream::reduceAnd(bool& value, const int communicator)
 {}
 
-void Foam::UPstream::reduceOr(bool& value, const label comm)
+void Foam::UPstream::reduceOr(bool& value, const int communicator)
 {}
 
 
 void Foam::reduce
 (
     bool& value,
-    const andOp<bool>&,
+    Foam::andOp<bool>,
     const int tag,
-    const label comm
+    const int communicator
 )
 {}
 
 void Foam::reduce
 (
     bool& value,
-    const orOp<bool>&,
+    Foam::orOp<bool>,
     const int tag,
-    const label comm
+    const int communicator
 )
 {}
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Common reductions
-
-#undef  Pstream_CommonReductions
-#define Pstream_CommonReductions(Native)                                      \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const minOp<Native>&,                                                     \
-    const int tag,                                                            \
-    const label comm                                                          \
-)                                                                             \
-{}                                                                            \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const maxOp<Native>&,                                                     \
-    const int tag,                                                            \
-    const label comm                                                          \
-)                                                                             \
-{}                                                                            \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const sumOp<Native>&,                                                     \
-    const int tag,                                                            \
-    const label comm                                                          \
-)                                                                             \
-{}                                                                            \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const minOp<Native>&,                                                     \
-    const int tag,                                                            \
-    const label comm                                                          \
-)                                                                             \
-{}                                                                            \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const maxOp<Native>&,                                                     \
-    const int tag,                                                            \
-    const label comm                                                          \
-)                                                                             \
-{}                                                                            \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const sumOp<Native>&,                                                     \
-    const int tag,                                                            \
-    const label comm                                                          \
-)                                                                             \
-{}
-
+// * * * * * * * * * * Protected Static Member Functions * * * * * * * * * * //
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Floating-point reductions
-
-#undef  Pstream_FloatReductions
-#define Pstream_FloatReductions(Native)                                       \
-                                                                              \
-Pstream_CommonReductions(Native);                                             \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const sumOp<Native>&,                                                     \
-    const int tag,                                                            \
-    const label comm,                                                         \
-    UPstream::Request& req                                                    \
-)                                                                             \
-{}                                                                            \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const sumOp<Native>&,                                                     \
-    const int tag,                                                            \
-    const label comm,                                                         \
-    UPstream::Request& req                                                    \
-)                                                                             \
-{}                                                                            \
-                                                                              \
-void Foam::sumReduce                                                          \
-(                                                                             \
-    Native& value,                                                            \
-    label& count,                                                             \
-    const int tag,                                                            \
-    const label comm                                                          \
-)                                                                             \
+void Foam::UPstream::mpi_reduce
+(
+    void* values,
+    int count,
+    const UPstream::dataTypes dataTypeId,
+    const UPstream::opCodes opCodeId,
+    const int communicator,
+    UPstream::Request* req
+)
 {}
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Bitwise reductions
-
-#undef  Pstream_BitwiseReductions
-#define Pstream_BitwiseReductions(Native)                                     \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const bitOrOp<Native>&,                                                   \
-    const int tag,                                                            \
-    const label comm                                                          \
-)                                                                             \
-{}                                                                            \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const bitOrOp<Native>&,                                                   \
-    const int tag,                                                            \
-    const label comm                                                          \
-)                                                                             \
+void Foam::UPstream::mpi_allreduce
+(
+    void* values,
+    int count,
+    const UPstream::dataTypes dataTypeId,
+    const UPstream::opCodes opCodeId,
+    const int communicator,
+    UPstream::Request* req
+)
 {}
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-Pstream_CommonReductions(int32_t);
-Pstream_CommonReductions(int64_t);
-Pstream_CommonReductions(uint32_t);
-Pstream_CommonReductions(uint64_t);
-
-Pstream_FloatReductions(float);
-Pstream_FloatReductions(double);
-
-Pstream_BitwiseReductions(unsigned char);
-Pstream_BitwiseReductions(unsigned int);
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#undef Pstream_CommonReductions
-#undef Pstream_FloatReductions
-#undef Pstream_BitwiseReductions
-
-
 // ************************************************************************* //
diff --git a/src/Pstream/dummy/UPstreamWindow.C b/src/Pstream/dummy/UPstreamWindow.C
index 4c8e5b7906145f9989fef10819812bdf58e77e23..9af10b6e9119722f4564681db99ed74fc7f12d15 100644
--- a/src/Pstream/dummy/UPstreamWindow.C
+++ b/src/Pstream/dummy/UPstreamWindow.C
@@ -47,4 +47,10 @@ void Foam::UPstream::Window::reset() noexcept
 {}
 
 
+int Foam::UPstream::Window::size() const
+{
+    return 0;
+}
+
+
 // ************************************************************************* //
diff --git a/src/Pstream/mpi/PstreamGlobals.C b/src/Pstream/mpi/PstreamGlobals.C
index b7aa206aea7f0afa884b9bfcb3db4446e4b6e12a..20a6868c7231c42e87febcc7906e015de9bcd4bd 100644
--- a/src/Pstream/mpi/PstreamGlobals.C
+++ b/src/Pstream/mpi/PstreamGlobals.C
@@ -34,6 +34,9 @@ Foam::DynamicList<bool> Foam::PstreamGlobals::pendingMPIFree_;
 Foam::DynamicList<MPI_Comm> Foam::PstreamGlobals::MPICommunicators_;
 Foam::DynamicList<MPI_Request> Foam::PstreamGlobals::outstandingRequests_;
 
+Foam::PstreamGlobals::DataTypeCountLookupTable
+Foam::PstreamGlobals::dataTypesCount_(1);
+
 Foam::PstreamGlobals::DataTypeLookupTable
 Foam::PstreamGlobals::MPIdataTypes_(MPI_DATATYPE_NULL);
 
@@ -70,6 +73,12 @@ void Foam::PstreamGlobals::initCommunicator(const label index)
 
 void Foam::PstreamGlobals::initDataTypes()
 {
+    static_assert
+    (
+        PstreamGlobals::DataTypeCountLookupTable::max_size()
+     == (int(UPstream::dataTypes::DataTypes_end)+1),
+        "Data count lookup table size != number of dataTypes enumerations"
+    );
     static_assert
     (
         PstreamGlobals::DataTypeLookupTable::max_size()
@@ -77,15 +86,21 @@ void Foam::PstreamGlobals::initDataTypes()
         "Lookup table size != number of dataTypes enumerations"
     );
 
-    // From enumeration to MPI datatype
+    // From enumeration to MPI datatype for fundamental types
+    // (count is always 1)
     #undef  defineType
-    #define defineType(Idx, BaseType) \
-    MPIdataTypes_[int(UPstream::dataTypes::Idx)] = BaseType;
+    #define defineType(Idx, BaseType)                                         \
+    {                                                                         \
+        dataTypesCount_[int(UPstream::dataTypes::Idx)] = 1;                   \
+        MPIdataTypes_[int(UPstream::dataTypes::Idx)] = BaseType;              \
+    }
 
-    // Intrinsic Types [8]:
+    // Fundamental Types [10]:
     defineType(type_byte,   MPI_BYTE);
+    defineType(type_int16,  MPI_INT16_T);
     defineType(type_int32,  MPI_INT32_T);
     defineType(type_int64,  MPI_INT64_T);
+    defineType(type_uint16, MPI_UINT16_T);
     defineType(type_uint32, MPI_UINT32_T);
     defineType(type_uint64, MPI_UINT64_T);
     defineType(type_float,  MPI_FLOAT);
@@ -98,6 +113,7 @@ void Foam::PstreamGlobals::initDataTypes()
     #undef  defineUserType
     #define defineUserType(Idx, Count, BaseType, Name)                        \
     {                                                                         \
+        dataTypesCount_[int(UPstream::dataTypes::Idx)] = Count;               \
         auto& dt = MPIdataTypes_[int(UPstream::dataTypes::Idx)];              \
         MPI_Type_contiguous(Count, BaseType, &dt);                            \
         MPI_Type_set_name(dt, Name);                                          \
@@ -121,11 +137,11 @@ void Foam::PstreamGlobals::deinitDataTypes()
     // User types only
     auto first =
     (
-        MPIdataTypes_.begin() + int(UPstream::dataTypes::UserTypes_begin)
+        MPIdataTypes_.begin() + int(UPstream::dataTypes::User_begin)
     );
     const auto last =
     (
-        MPIdataTypes_.begin() + int(UPstream::dataTypes::UserTypes_end)
+        MPIdataTypes_.begin() + int(UPstream::dataTypes::User_end)
     );
 
     for (; first != last; ++first)
@@ -200,20 +216,20 @@ void Foam::PstreamGlobals::printDataTypes(bool all)
         std::cerr << "enumerated data types:\n";
         print
         (
-            UPstream::dataTypes::DataTypes_begin,
-            UPstream::dataTypes::DataTypes_end
+            UPstream::dataTypes::Basic_begin,
+            UPstream::dataTypes::Basic_end
         );
     }
     else
     {
         // User types only.
         std::cerr << "enumerated user-defined data types:\n";
-        print
-        (
-            UPstream::dataTypes::UserTypes_begin,
-            UPstream::dataTypes::UserTypes_end
-        );
     }
+    print
+    (
+        UPstream::dataTypes::User_begin,
+        UPstream::dataTypes::User_end
+    );
 }
 
 
diff --git a/src/Pstream/mpi/PstreamGlobals.H b/src/Pstream/mpi/PstreamGlobals.H
index bf46434ad788e1b16eb3cb1f1d4658906491988b..e895883992f36ba72b7166a6fc1bc84780c37f43 100644
--- a/src/Pstream/mpi/PstreamGlobals.H
+++ b/src/Pstream/mpi/PstreamGlobals.H
@@ -63,18 +63,28 @@ extern DynamicList<MPI_Comm> MPICommunicators_;
 //- Outstanding non-blocking operations.
 extern DynamicList<MPI_Request> outstandingRequests_;
 
-typedef Foam::FixedList<MPI_Datatype, 15> DataTypeLookupTable;
+// The fundamental count for each UPstream::dataTypes entry
+typedef Foam::FixedList<int, 17> DataTypeCountLookupTable;
 
-//- MPI data types corresponding to some fundamental and OpenFOAM types.
+//- Fundamental count for each valid UPstream::dataTypes entry
+//- Indexed by UPstream::dataTypes enum
+extern DataTypeCountLookupTable dataTypesCount_;
+
+// For UPstream::dataTypes lookup, includes space for last 'invalid' entry
+typedef Foam::FixedList<MPI_Datatype, 17> DataTypeLookupTable;
+
+//- MPI data types corresponding to fundamental and OpenFOAM types.
 //- Indexed by UPstream::dataTypes enum
 extern DataTypeLookupTable MPIdataTypes_;
 
+// For UPstream::opCodes lookup, includes space for last 'invalid' entry
 typedef Foam::FixedList<MPI_Op, 13> OpCodesLookupTable;
 
 //- MPI operation types, indexed by UPstream::opCodes enum
 extern OpCodesLookupTable MPIopCodes_;
 
 
+
 // * * * * * * * * * * * * * * * Communicators * * * * * * * * * * * * * * * //
 
 //- Initialize bookkeeping for MPI communicator index
@@ -203,6 +213,25 @@ inline void push_request
 }
 
 
+// * * * * * * * * * * * * * * Convenience Methods * * * * * * * * * * * * * //
+
+//- Broadcast a single int64 value.
+//
+//  Ensures consistent data types. Used within the following:
+//  - UIPBstream::bufferIPCrecv()
+//  - UOPBstream::bufferIPCsend()
+//  - UOPBstream::send(Foam::zero, ...)
+
+inline bool broadcast_int64(int64_t& value, int comm)
+{
+    return
+    (
+        MPI_SUCCESS
+     == MPI_Bcast(&value, 1, MPI_INT64_T, 0, MPICommunicators_[comm])
+    );
+}
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace PstreamGlobals
diff --git a/src/Pstream/mpi/UIPBstreamRead.C b/src/Pstream/mpi/UIPBstreamRead.C
index 5080583396cd19d300eae994d0617a803f4c19ea..93db0ff80f94ecc481dcd3b8e79a13d11aa146af 100644
--- a/src/Pstream/mpi/UIPBstreamRead.C
+++ b/src/Pstream/mpi/UIPBstreamRead.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2024 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,8 +26,8 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "UIPstream.H"
-#include "PstreamGlobals.H"
 #include "IOstreams.H"
+#include "PstreamGlobals.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -37,33 +37,32 @@ void Foam::UIPBstream::bufferIPCrecv()
     // 1. for the data size
     // 2. for the data itself
 
-    // Expected message size, similar to MPI_Probe
-    // Same type must be expected in UOPBstream::bufferIPCsend()
-    std::streamsize bufSize(0);
-
     // Broadcast #1 - data size
-    if
-    (
-        !UPstream::broadcast
-        (
-            reinterpret_cast<char*>(&bufSize),
-            sizeof(std::streamsize),
-            comm_,
-            fromProcNo_  //< is actually rootProcNo
-        )
-    )
+    // Same data type must be used in UOPBstream::bufferIPCsend()
+
+    int64_t count(0);
+    if (!PstreamGlobals::broadcast_int64(count, comm_))
     {
         FatalErrorInFunction
-            << "MPI_Bcast failure receiving buffer size" << nl
+            << "Broadcast failure receiving buffer size" << nl
+            << " comm:" << comm_ << nl
             << Foam::abort(FatalError);
     }
 
-    if (UPstream::debug)
+    // This is not actually possible - sender uses List::size()
+    //
+    // if (FOAM_UNLIKELY(count > int64_t(UList<char>::max_size())))
+    // {
+    //     FatalErrorInFunction
+    //         << "Broadcast list size larger than UList<char>::max_size()"
+    //         << Foam::abort(FatalError);
+    // }
+
+    if (FOAM_UNLIKELY(UPstream::debug))
     {
-        Perr<< "UOPBstream IPC read buffer :"
-            << " root:" << fromProcNo_
+        Perr<< "UIPBstream IPC read buffer :"
             << " comm:" << comm_
-            << " probed size:" << label(bufSize)
+            << " probed size:" << label(count)
             << " wanted size:" << recvBuf_.capacity()
             << Foam::endl;
     }
@@ -71,33 +70,33 @@ void Foam::UIPBstream::bufferIPCrecv()
 
     // Set buffer size, avoiding any copying and resize doubling etc.
     recvBuf_.clear();
-    if (recvBuf_.capacity() < label(bufSize))
+    if (recvBuf_.capacity() < label(count))
     {
-        recvBuf_.setCapacity_nocopy(label(bufSize));
+        recvBuf_.setCapacity_nocopy(label(count));
     }
-    recvBuf_.resize_nocopy(label(bufSize));
+    recvBuf_.resize_nocopy(label(count));
 
     // This is the only real information we can trust
-    messageSize_ = label(bufSize);
+    messageSize_ = label(count);
 
 
     // Broadcast #2 - data content
     // - skip if there is no data to receive
     if
     (
-        (bufSize > 0)
-     && !UPstream::broadcast
+        (count > 0)  // ie, not empty
+     && !UPstream::mpi_broadcast
         (
             recvBuf_.data(),
-            recvBuf_.size(),  // same as bufSize
-            comm_,
-            fromProcNo_  //< is actually rootProcNo
+            recvBuf_.size(),  // same as count
+            UPstream::dataTypes::type_byte,
+            comm_
         )
     )
     {
         FatalErrorInFunction
-            << "MPI_Bcast failure receiving buffer data:"
-            << recvBuf_.size() << nl
+            << "Broadcast failure receiving buffer data:"
+            << recvBuf_.size() << " comm:" << comm_ << nl
             << Foam::abort(FatalError);
     }
 
@@ -108,29 +107,4 @@ void Foam::UIPBstream::bufferIPCrecv()
 }
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-std::streamsize Foam::UIPBstream::read
-(
-    const int rootProcNo,
-    char* buf,
-    const std::streamsize bufSize,
-    const label comm
-)
-{
-    if
-    (
-        !UPstream::broadcast(buf, bufSize, comm, rootProcNo)
-    )
-    {
-        FatalErrorInFunction
-            << "MPI_Bcast failure receiving data:" << label(bufSize) << nl
-            << Foam::abort(FatalError);
-        return 0;
-    }
-
-    return bufSize;
-}
-
-
 // ************************************************************************* //
diff --git a/src/Pstream/mpi/UIPstreamRead.C b/src/Pstream/mpi/UIPstreamRead.C
index 4f94257e712752c2351c2389772fb258e89fd919..050995e952bb176376fd771111451663faaff305 100644
--- a/src/Pstream/mpi/UIPstreamRead.C
+++ b/src/Pstream/mpi/UIPstreamRead.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2019-2024 OpenCFD Ltd.
+    Copyright (C) 2019-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -35,41 +35,47 @@ License
 // - as of 2023-06 appears to be broken with INTELMPI + PMI-2 (slurm)
 //   and perhaps other places so currently avoid
 
-#undef Pstream_use_MPI_Get_count
-
-// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+// * * * * * * * * * * Protected Static Member Functions * * * * * * * * * * //
 
 // General blocking/non-blocking MPI receive
-static std::streamsize UPstream_mpi_receive
+std::streamsize Foam::UPstream::mpi_receive
 (
-    const Foam::UPstream::commsTypes commsType,
-    char* buf,
-    const std::streamsize bufSize,
+    const UPstream::commsTypes commsType,
+    void* buf,                      // Type checking done by caller
+    std::streamsize count,
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
     const int fromProcNo,
     const int tag,
-    const Foam::label communicator,
-    Foam::UPstream::Request* req
+    const int communicator,
+    UPstream::Request* req
 )
 {
-    using namespace Foam;
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
 
     PstreamGlobals::reset_request(req);
 
+    // Could check if nonBlocking and request are consistently specified...
+
+
     // TODO: some corrective action, at least when not nonBlocking
     #if 0
     // No warnings here, just on the sender side.
-    if (bufSize > std::streamsize(INT_MAX))
+    if (count > std::streamsize(INT_MAX))
     {
-        Perr<< "UIPstream::read() : from rank " << fromProcNo
-            << " exceeds INT_MAX bytes" << Foam::endl;
+        Perr<< "[mpi_recv] from rank " << fromProcNo
+            << " exceeds INT_MAX values of "
+            << PstreamGlobals::dataType_name(datatype)
+            << Foam::endl;
+
         error::printStack(Perr);
     }
     #endif
 
     if (FOAM_UNLIKELY(PstreamGlobals::warnCommunicator(communicator)))
     {
-        Perr<< "UIPstream::read : starting read from:" << fromProcNo
-            << " size:" << label(bufSize)
+        Perr<< "[mpi_recv] : starting recv from:" << fromProcNo
+            << " type:" << int(dataTypeId)
+            << " count:" << label(count)
             << " tag:" << tag << " comm:" << communicator
             << " commsType:" << UPstream::commsTypeNames[commsType]
             << " warnComm:" << UPstream::warnComm
@@ -78,8 +84,9 @@ static std::streamsize UPstream_mpi_receive
     }
     else if (FOAM_UNLIKELY(UPstream::debug))
     {
-        Perr<< "UIPstream::read : starting read from:" << fromProcNo
-            << " size:" << label(bufSize)
+        Perr<< "[mpi_recv] : starting recv from:" << fromProcNo
+            << " type:" << int(dataTypeId)
+            << " count:" << label(count)
             << " tag:" << tag << " comm:" << communicator
             << " commsType:" << UPstream::commsTypeNames[commsType]
             << Foam::endl;
@@ -103,68 +110,75 @@ static std::streamsize UPstream_mpi_receive
             returnCode = MPI_Recv
             (
                 buf,
-                bufSize,
-                MPI_BYTE,
+                count,
+                datatype,
                 fromProcNo,
                 tag,
                 PstreamGlobals::MPICommunicators_[communicator],
-                &status
+               &status
             );
         }
 
         profilingPstream::addGatherTime();
 
-        if (returnCode != MPI_SUCCESS)
+        if (FOAM_UNLIKELY(returnCode != MPI_SUCCESS))
         {
             FatalErrorInFunction
-                << "MPI_Recv cannot receive incoming message"
+                << "[mpi_recv] : cannot receive message from:"
+                << fromProcNo
+                << " type:" << int(dataTypeId)
+                << " count:" << label(count) << " tag:" << tag
                 << Foam::abort(FatalError);
             return 0;
         }
         else if (FOAM_UNLIKELY(UPstream::debug))
         {
-            Perr<< "UIPstream::read : finished recv from:"
+            Perr<< "[mpi_recv] : finished recv from:"
                 << fromProcNo
-                << " size:" << label(bufSize) << " tag:" << tag
+                << " type:" << int(dataTypeId)
+                << " count:" << label(count) << " tag:" << tag
                 << Foam::endl;
         }
 
-        // Check size of message read
-        #ifdef Pstream_use_MPI_Get_count
-        int count(0);
-        MPI_Get_count(&status, MPI_BYTE, &count);
-        #else
-        MPI_Count count(0);
-        MPI_Get_elements_x(&status, MPI_BYTE, &count);
-        #endif
+        // Check size of message read (number of basic elements)
+        MPI_Count num_recv(0);
+        MPI_Get_elements_x(&status, datatype, &num_recv);
 
         // Errors
-        if (count == MPI_UNDEFINED || int64_t(count) < 0)
+        if (FOAM_UNLIKELY(num_recv == MPI_UNDEFINED || int64_t(num_recv) < 0))
         {
             FatalErrorInFunction
-                << "MPI_Get_count() or MPI_Get_elements_x() : "
-                   "returned undefined or negative value"
+                << "[mpi_recv] : receive from:" << fromProcNo
+                << " type:" << int(dataTypeId)
+                << " received count is undefined or negative value"
                 << Foam::abort(FatalError);
         }
-        else if (int64_t(count) > int64_t(UList<char>::max_size()))
+        else
+        {
+            // From number of basic elements to number of 'datatype'
+            num_recv /= PstreamGlobals::dataTypesCount_[int(dataTypeId)];
+        }
+
+        if (FOAM_UNLIKELY(int64_t(num_recv) > int64_t(UList<char>::max_size())))
         {
             FatalErrorInFunction
-                << "MPI_Get_count() or MPI_Get_elements_x() : "
-                   "count is larger than UList<char>::max_size() bytes"
+                << "[mpi_recv] : receive from:" << fromProcNo
+                << " type:" << int(dataTypeId)
+                << " received count is larger than UList<T>::max_size()"
                 << Foam::abort(FatalError);
         }
-
-
-        if (bufSize < std::streamsize(count))
+        else if (FOAM_UNLIKELY(count < std::streamsize(num_recv)))
         {
             FatalErrorInFunction
-                << "buffer (" << label(bufSize)
-                << ") not large enough for incoming message ("
-                << label(count) << ')'
+                << "[mpi_recv] : receive from:" << fromProcNo
+                << " type:" << int(dataTypeId)
+                << " count:" << label(count)
+                << " buffer is too small for incoming message ("
+                << label(num_recv) << ')'
                 << Foam::abort(FatalError);
         }
 
-        return std::streamsize(count);
+        return std::streamsize(num_recv);
     }
     else if (commsType == UPstream::commsTypes::nonBlocking)
     {
@@ -174,19 +188,22 @@ static std::streamsize UPstream_mpi_receive
             returnCode = MPI_Irecv
             (
                 buf,
-                bufSize,
-                MPI_BYTE,
+                count,
+                datatype,
                 fromProcNo,
                 tag,
                 PstreamGlobals::MPICommunicators_[communicator],
-                &request
+               &request
             );
         }
 
-        if (returnCode != MPI_SUCCESS)
+        if (FOAM_UNLIKELY(returnCode != MPI_SUCCESS))
         {
             FatalErrorInFunction
-                << "MPI_Irecv cannot start non-blocking receive"
+                << "[mpi_recv] : cannot start non-blocking receive from:"
+                << fromProcNo
+                << " type:" << int(dataTypeId)
+                << " count:" << label(count)
                 << Foam::abort(FatalError);
 
             return 0;
@@ -198,16 +215,17 @@ static std::streamsize UPstream_mpi_receive
 
         if (FOAM_UNLIKELY(UPstream::debug))
         {
-            Perr<< "UIPstream::read : started non-blocking recv from:"
+            Perr<< "[mpi_recv] : started non-blocking recv from:"
                 << fromProcNo
-                << " size:" << label(bufSize) << " tag:" << tag
+                << " type:" << int(dataTypeId)
+                << " count:" << label(count) << " tag:" << tag
                 << " request:" <<
                 (req ? label(-1) : PstreamGlobals::outstandingRequests_.size())
                 << Foam::endl;
         }
 
         // Assume the message will be completely received.
-        return bufSize;
+        return count;
     }
 
     FatalErrorInFunction
@@ -264,63 +282,64 @@ void Foam::UIPstream::bufferIPCrecv()
 
         profilingPstream::addProbeTime();
 
-
-        #ifdef Pstream_use_MPI_Get_count
-        int count(0);
-        MPI_Get_count(&status, MPI_BYTE, &count);
-        #else
-        MPI_Count count(0);
-        MPI_Get_elements_x(&status, MPI_BYTE, &count);
-        #endif
+        // Buffer of characters (bytes)
+        MPI_Count num_recv(0);
+        MPI_Get_elements_x(&status, MPI_BYTE, &num_recv);
 
         // Errors
-        if (count == MPI_UNDEFINED || int64_t(count) < 0)
+        if (FOAM_UNLIKELY(num_recv == MPI_UNDEFINED || int64_t(num_recv) < 0))
         {
             FatalErrorInFunction
-                << "MPI_Get_count() or MPI_Get_elements_x() : "
-                   "returned undefined or negative value"
+                << "UIPstream IPC read buffer from:" << fromProcNo_
+                << " received count is undefined or negative value"
                 << Foam::abort(FatalError);
         }
-        else if (int64_t(count) > int64_t(UList<char>::max_size()))
+
+        // Count is already in basic elements, no need to scale the result
+
+        if (FOAM_UNLIKELY(int64_t(num_recv) > int64_t(UList<char>::max_size())))
         {
             FatalErrorInFunction
-                << "MPI_Get_count() or MPI_Get_elements_x() : "
-                   "count is larger than UList<char>::max_size() bytes"
+                << "UIPstream IPC read buffer from:" << fromProcNo_
+                << " received count is larger than UList<T>::max_size()"
                 << Foam::abort(FatalError);
         }
 
         if (FOAM_UNLIKELY(UPstream::debug))
         {
-            Perr<< "UIPstream::UIPstream : probed size:"
-                << label(count) << Foam::endl;
+            Perr<< "UIPstream::bufferIPCrecv : probed size:"
+                << label(num_recv) << Foam::endl;
         }
 
-        recvBuf_.resize(label(count));
-        messageSize_ = label(count);
+        recvBuf_.resize(label(num_recv));
+        messageSize_ = label(num_recv);
     }
 
-    std::streamsize count = UPstream_mpi_receive
+    std::streamsize count = UPstream::mpi_receive
     (
         commsType(),
-        recvBuf_.data(),
-        messageSize_,   // The expected size
+        recvBuf_.data(),        // buffer
+        messageSize_,           // expected size
+        UPstream::dataTypes::type_byte,  // MPI_BYTE
         fromProcNo_,
         tag_,
         comm_,
         nullptr   // UPstream::Request
     );
 
-    if (count < 0)
+    // Errors
+    if (FOAM_UNLIKELY(count < 0))
     {
         FatalErrorInFunction
-            << "MPI_recv() with negative size??"
+            << "UIPstream IPC read buffer from:" << fromProcNo_
+            << " with negative size?"
             << Foam::abort(FatalError);
     }
-    else if (int64_t(count) > int64_t(UList<char>::max_size()))
+    else if (FOAM_UNLIKELY(int64_t(count) > int64_t(UList<char>::max_size())))
     {
         FatalErrorInFunction
-            << "MPI_recv() larger than "
-                "UList<char>::max_size() bytes"
+            << "UIPstream IPC read buffer from:" << fromProcNo_
+            << " received size is larger than UList<T>::max_size()"
             << Foam::abort(FatalError);
     }
 
@@ -335,30 +354,4 @@ void Foam::UIPstream::bufferIPCrecv()
 }
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-std::streamsize Foam::UIPstream::read
-(
-    const UPstream::commsTypes commsType,
-    const int fromProcNo,
-    char* buf,
-    const std::streamsize bufSize,
-    const int tag,
-    const label communicator,
-    UPstream::Request* req
-)
-{
-    return UPstream_mpi_receive
-    (
-        commsType,
-        buf,
-        bufSize,
-        fromProcNo,
-        tag,
-        communicator,
-        req
-    );
-}
-
-
 // ************************************************************************* //
diff --git a/src/Pstream/mpi/UOPBstreamWrite.C b/src/Pstream/mpi/UOPBstreamWrite.C
index f4c9412fca4e182564450d8b0cc75361ff92d255..90c96ab3a2d4539154bdd12f37e0f046e533c09e 100644
--- a/src/Pstream/mpi/UOPBstreamWrite.C
+++ b/src/Pstream/mpi/UOPBstreamWrite.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2023 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -39,55 +39,36 @@ bool Foam::UOPBstream::bufferIPCsend()
 
     PstreamGlobals::checkCommunicator(comm_, toProcNo_);
 
-    // Same type must be expected in UIPBstream::bufferIPCrecv()
-    std::streamsize bufSize(sendBuf_.size());
-
-    // TODO: some corrective action
-    #if 0
-    if (bufSize > std::streamsize(INT_MAX))
-    {
-        Perr<< "UOPBstream::write() :"
-            << " exceeds INT_MAX bytes" << Foam::endl;
-        error::printStack(Perr);
-    }
-    #endif
-
     // Broadcast #1 - data size
-    if
-    (
-        !UPstream::broadcast
-        (
-            reinterpret_cast<char*>(&bufSize),
-            sizeof(std::streamsize),
-            comm_,
-            toProcNo_  //< is actually rootProcNo
-        )
-    )
+    // Same data type must be used in UIPBstream::bufferIPCrecv()
+
+    int64_t count(sendBuf_.size());
+    if (!PstreamGlobals::broadcast_int64(count, comm_))
     {
         FatalErrorInFunction
-            << "MPI_Bcast failure sending buffer size:" << bufSize << nl
+            << "Broadcast failure sending buffer size:"
+            << label(count) << " comm:" << comm_ << nl
             << Foam::abort(FatalError);
         return false;
     }
 
-
     // Broadcast #2 - data content
     // - skip if there is no data to send
     if
     (
-        (bufSize > 0)
-     && !UPstream::broadcast
+        (count > 0)  // ie, not empty
+     && !UPstream::mpi_broadcast
         (
             sendBuf_.data(),
-            sendBuf_.size(),  // same as bufSize
-            comm_,
-            toProcNo_  //< is actually rootProcNo
+            sendBuf_.size(),  // same as count
+            UPstream::dataTypes::type_byte,
+            comm_
         )
     )
     {
         FatalErrorInFunction
-            << "MPI_Bcast failure sending buffer data:"
-            << sendBuf_.size() << nl
+            << "Broadcast failure sending buffer data:"
+            << sendBuf_.size() << " comm:" << comm_ << nl
             << Foam::abort(FatalError);
         return false;
     }
@@ -98,26 +79,10 @@ bool Foam::UOPBstream::bufferIPCsend()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-bool Foam::UOPBstream::write
-(
-    const int rootProcNo,
-    const char* buf,
-    const std::streamsize bufSize,
-    const label comm
-)
+void Foam::UOPBstream::send(Foam::zero, const int communicator)
 {
-    if
-    (
-        !UPstream::broadcast(const_cast<char*>(buf), bufSize, comm, rootProcNo)
-    )
-    {
-        FatalErrorInFunction
-            << "MPI_Bcast failure sending buffer data:" << label(bufSize) << nl
-            << Foam::abort(FatalError);
-        return false;
-    }
-
-    return true;
+    int64_t count(0);
+    PstreamGlobals::broadcast_int64(count, communicator);
 }
 
 
diff --git a/src/Pstream/mpi/UOPstreamWrite.C b/src/Pstream/mpi/UOPstreamWrite.C
index d2e1da2ec65f255d3d215793843e079a6f015829..dca49157c2737294eff70b07b209f2bfd81723ef 100644
--- a/src/Pstream/mpi/UOPstreamWrite.C
+++ b/src/Pstream/mpi/UOPstreamWrite.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2019-2023 OpenCFD Ltd.
+    Copyright (C) 2019-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -46,36 +46,47 @@ bool Foam::UOPstream::bufferIPCsend()
 }
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * Protected Static Member Functions * * * * * * * * * * //
 
-bool Foam::UOPstream::write
+// General blocking/non-blocking MPI send
+bool Foam::UPstream::mpi_send
 (
     const UPstream::commsTypes commsType,
+    const void* buf,                       // Type checking done by caller
+    std::streamsize count,
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
     const int toProcNo,
-    const char* buf,
-    const std::streamsize bufSize,
     const int tag,
-    const label communicator,
+    const int communicator,
     UPstream::Request* req,
     const UPstream::sendModes sendMode
 )
 {
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
+
     PstreamGlobals::reset_request(req);
 
+    // Could check if nonBlocking and request are consistently specified...
+
+
     // TODO: some corrective action, at least when not nonBlocking
     #if 0
-    if (bufSize > std::streamsize(INT_MAX))
+    if (count > std::streamsize(INT_MAX))
     {
-        Perr<< "UOPstream::write() : to rank " << toProcNo
-            << " exceeds INT_MAX bytes" << Foam::endl;
+        Perr<< "[mpi_send] : to rank " << toProcNo
+            << " type:" << int(dataTypeId)
+            << " exceeds INT_MAX values"
+            << Foam::endl;
+
         error::printStack(Perr);
     }
     #endif
 
     if (FOAM_UNLIKELY(PstreamGlobals::warnCommunicator(communicator)))
     {
-        Perr<< "UOPstream::write : starting write to:" << toProcNo
-            << " size:" << label(bufSize)
+        Perr<< "[mpi_send] : starting send to:" << toProcNo
+            << " type:" << int(dataTypeId)
+            << " count:" << label(count)
             << " tag:" << tag << " comm:" << communicator
             << " commType:" << UPstream::commsTypeNames[commsType]
             << " warnComm:" << UPstream::warnComm
@@ -84,8 +95,9 @@ bool Foam::UOPstream::write
     }
     else if (FOAM_UNLIKELY(UPstream::debug))
     {
-        Perr<< "UOPstream::write : starting write to:" << toProcNo
-            << " size:" << label(bufSize)
+        Perr<< "[mpi_send] : starting send to:" << toProcNo
+            << " type:" << int(dataTypeId)
+            << " count:" << label(count)
             << " tag:" << tag << " comm:" << communicator
             << " commType:" << UPstream::commsTypeNames[commsType]
             << Foam::endl;
@@ -101,9 +113,9 @@ bool Foam::UOPstream::write
     {
         returnCode = MPI_Bsend
         (
-            const_cast<char*>(buf),
-            bufSize,
-            MPI_BYTE,
+            buf,
+            count,
+            datatype,
             toProcNo,
             tag,
             PstreamGlobals::MPICommunicators_[communicator]
@@ -114,9 +126,9 @@ bool Foam::UOPstream::write
 
         if (FOAM_UNLIKELY(UPstream::debug))
         {
-            Perr<< "UOPstream::write : finished buffered send to:"
+            Perr<< "[mpi_send] : finished buffered send to:"
                 << toProcNo
-                << " size:" << label(bufSize) << " tag:" << tag
+                << " count:" << label(count) << " tag:" << tag
                 << Foam::endl;
         }
     }
@@ -126,9 +138,9 @@ bool Foam::UOPstream::write
         {
             returnCode = MPI_Ssend
             (
-                const_cast<char*>(buf),
-                bufSize,
-                MPI_BYTE,
+                buf,
+                count,
+                datatype,
                 toProcNo,
                 tag,
                 PstreamGlobals::MPICommunicators_[communicator]
@@ -138,9 +150,9 @@ bool Foam::UOPstream::write
         {
             returnCode = MPI_Send
             (
-                const_cast<char*>(buf),
-                bufSize,
-                MPI_BYTE,
+                buf,
+                count,
+                datatype,
                 toProcNo,
                 tag,
                 PstreamGlobals::MPICommunicators_[communicator]
@@ -152,9 +164,10 @@ bool Foam::UOPstream::write
 
         if (FOAM_UNLIKELY(UPstream::debug))
         {
-            Perr<< "UOPstream::write : finished send to:"
+            Perr<< "[mpi_send] : finished send to:"
                 << toProcNo
-                << " size:" << label(bufSize) << " tag:" << tag
+                << " type:" << int(dataTypeId)
+                << " count:" << label(count) << " tag:" << tag
                 << Foam::endl;
         }
     }
@@ -166,9 +179,9 @@ bool Foam::UOPstream::write
         {
             returnCode = MPI_Issend
             (
-                const_cast<char*>(buf),
-                bufSize,
-                MPI_BYTE,
+                buf,
+                count,
+                datatype,
                 toProcNo,
                 tag,
                 PstreamGlobals::MPICommunicators_[communicator],
@@ -179,9 +192,9 @@ bool Foam::UOPstream::write
         {
             returnCode = MPI_Isend
             (
-                const_cast<char*>(buf),
-                bufSize,
-                MPI_BYTE,
+                buf,
+                count,
+                datatype,
                 toProcNo,
                 tag,
                 PstreamGlobals::MPICommunicators_[communicator],
@@ -191,9 +204,10 @@ bool Foam::UOPstream::write
 
         if (FOAM_UNLIKELY(UPstream::debug))
         {
-            Perr<< "UOPstream::write : started non-blocking send to:"
+            Perr<< "[mpi_send] : started non-blocking send to:"
                 << toProcNo
-                << " size:" << label(bufSize) << " tag:" << tag
+                << " type:" << int(dataTypeId)
+                << " count:" << label(count) << " tag:" << tag
                 << " request:" <<
                 (req ? label(-1) : PstreamGlobals::outstandingRequests_.size())
                 << Foam::endl;
@@ -207,6 +221,7 @@ bool Foam::UOPstream::write
         FatalErrorInFunction
             << "Unsupported communications type " << int(commsType)
             << Foam::abort(FatalError);
+        return false;
     }
 
     return (returnCode == MPI_SUCCESS);
diff --git a/src/Pstream/mpi/UPstream.C b/src/Pstream/mpi/UPstream.C
index a3bfe3ab4296730979bc254c236f2dd175fa948c..1b051b072fb2d20c3583dd8e591edaf3ae14b557 100644
--- a/src/Pstream/mpi/UPstream.C
+++ b/src/Pstream/mpi/UPstream.C
@@ -1253,14 +1253,14 @@ Foam::UPstream::probeMessage
         MPI_Get_elements_x(&status, MPI_BYTE, &num_recv);
 
         // Errors
-        if (num_recv == MPI_UNDEFINED || int64_t(num_recv) < 0)
+        if (FOAM_UNLIKELY(num_recv == MPI_UNDEFINED || int64_t(num_recv) < 0))
         {
             FatalErrorInFunction
                 << "MPI_Get_elements_x() : "
                    "returned undefined or negative value"
                 << Foam::abort(FatalError);
         }
-        else if (int64_t(num_recv) > int64_t(INT_MAX))
+        else if (FOAM_UNLIKELY(int64_t(num_recv) > int64_t(INT_MAX)))
         {
             FatalErrorInFunction
                 << "MPI_Get_elements_x() : "
diff --git a/src/Pstream/mpi/UPstreamBroadcast.C b/src/Pstream/mpi/UPstreamBroadcast.C
index 1b3669d3a4121c95a28b332d5ebd6d1e307e8aec..91f4b1abfc66f671379f7f4c81019e2fd027b4f7 100644
--- a/src/Pstream/mpi/UPstreamBroadcast.C
+++ b/src/Pstream/mpi/UPstreamBroadcast.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2023 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,51 +29,62 @@ License
 #include "PstreamGlobals.H"
 #include "profilingPstream.H"
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * Protected Static Member Functions * * * * * * * * * * //
 
-bool Foam::UPstream::broadcast
+bool Foam::UPstream::mpi_broadcast
 (
-    char* buf,
-    const std::streamsize bufSize,
-    const label comm,
-    const int rootProcNo
+    void* buf,                      // Type checking done by caller
+    std::streamsize count,
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
+    const int communicator          // Index into MPICommunicators_
 )
 {
-    if (!UPstream::is_parallel(comm))
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
+
+    if (!count || !UPstream::is_parallel(communicator))
     {
         // Nothing to do - ignore
         return true;
     }
 
-    //Needed?  PstreamGlobals::checkCommunicator(comm, rootProcNo);
+    //Needed?  PstreamGlobals::checkCommunicator(communicator, 0);
 
-    if (FOAM_UNLIKELY(PstreamGlobals::warnCommunicator(comm)))
+    // Without MPI_Bcast_c()
+    if (FOAM_UNLIKELY(count > std::streamsize(INT_MAX)))
     {
-        Perr<< "UPstream::broadcast : root:" << rootProcNo
-            << " comm:" << comm
-            << " size:" << label(bufSize)
-            << " warnComm:" << UPstream::warnComm
-            << Foam::endl;
-        error::printStack(Perr);
+        FatalErrorInFunction
+            << "Broadcast size " << label(count)
+            << " exceeds INT_MAX bytes" << Foam::endl
+            << Foam::abort(FatalError);
+        return false;
     }
-    else if (FOAM_UNLIKELY(UPstream::debug))
+
+    if (FOAM_UNLIKELY(UPstream::debug))
     {
-        Perr<< "UPstream::broadcast : root:" << rootProcNo
-            << " comm:" << comm
-            << " size:" << label(bufSize)
+        Perr<< "[mpi_broadcast] :"
+            << " type:" << int(dataTypeId)
+            << " count:" << label(count)
+            << " comm:" << communicator
             << Foam::endl;
     }
 
+    int returnCode = MPI_SUCCESS;
+
     profilingPstream::beginTiming();
 
-    const int returnCode = MPI_Bcast
-    (
-        buf,
-        bufSize,
-        MPI_BYTE,
-        rootProcNo,
-        PstreamGlobals::MPICommunicators_[comm]
-    );
+    {
+        // Regular broadcast
+        // OR: PstreamDetail::broadcast0(buf, count, datatype, communicator);
+
+        returnCode = MPI_Bcast
+        (
+            buf,
+            count,
+            datatype,
+            0,  // (root rank) == UPstream::masterNo()
+            PstreamGlobals::MPICommunicators_[communicator]
+        );
+    }
 
     profilingPstream::addBroadcastTime();
 
diff --git a/src/Pstream/mpi/UPstreamCommunicator.C b/src/Pstream/mpi/UPstreamCommunicator.C
index 9040f2f0dc24345c5cfeede063b583e4c680e0eb..adff0a7ea300c3327f14c5419eaf1bd7a0213caf 100644
--- a/src/Pstream/mpi/UPstreamCommunicator.C
+++ b/src/Pstream/mpi/UPstreamCommunicator.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2024 OpenCFD Ltd.
+    Copyright (C) 2024-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -39,7 +39,7 @@ Foam::UPstream::Communicator::Communicator() noexcept
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 Foam::UPstream::Communicator
-Foam::UPstream::Communicator::lookup(const label comm)
+Foam::UPstream::Communicator::lookup(const int comm)
 {
     if (comm < 0 || comm >= PstreamGlobals::MPICommunicators_.size())
     {
@@ -70,4 +70,27 @@ void Foam::UPstream::Communicator::reset() noexcept
 }
 
 
+int Foam::UPstream::Communicator::size() const
+{
+    int val = 0;
+
+    MPI_Comm comm = PstreamUtils::Cast::to_mpi(*this);
+
+    if (MPI_COMM_SELF == comm)
+    {
+        return 1;
+    }
+    else if
+    (
+        (MPI_COMM_NULL == comm)
+     || (MPI_SUCCESS != MPI_Comm_size(comm, &val))
+    )
+    {
+        val = 0;
+    }
+
+    return val;
+}
+
+
 // ************************************************************************* //
diff --git a/src/Pstream/mpi/UPstreamGatherScatter.C b/src/Pstream/mpi/UPstreamGatherScatter.C
index 36cac86dd427d9df5a82961127c467d29b5de79c..561a1d41c982ef631a16c06bbb83e78a4187570e 100644
--- a/src/Pstream/mpi/UPstreamGatherScatter.C
+++ b/src/Pstream/mpi/UPstreamGatherScatter.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2023 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,109 +26,235 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "Pstream.H"
+#include "PstreamGlobals.H"
 #include "UPstreamWrapping.H"
 
-#include <cinttypes>
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
+static inline bool is_basic_dataType(Foam::UPstream::dataTypes id) noexcept
+{
+    return
+    (
+        int(id) >= int(Foam::UPstream::dataTypes::Basic_begin)
+     && int(id)  < int(Foam::UPstream::dataTypes::Basic_end)
+    );
+}
+
+namespace
+{
+
+using namespace Foam;
+
+// Local function to print some error information
+inline void printErrorNonIntrinsic
+(
+    const char* context,
+    UPstream::dataTypes dataTypeId
+)
+{
+    FatalError
+        << "Bad input for " << context << ": likely a programming problem\n"
+        << "    Non-intrinsic data (" << int(dataTypeId) << ")\n"
+        << Foam::endl;
+}
+
+} // End anonymous namespace
+
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#undef  Pstream_CommonRoutines
-#define Pstream_CommonRoutines(Native, TaggedType)                            \
-                                                                              \
-void Foam::UPstream::mpiGather                                                \
-(                                                                             \
-    const Native* sendData,                                                   \
-    Native* recvData,                                                         \
-    int count,                                                                \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::gather                                                     \
-    (                                                                         \
-        sendData, recvData, count,                                            \
-        TaggedType, comm                                                      \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-                                                                              \
-void Foam::UPstream::mpiScatter                                               \
-(                                                                             \
-    const Native* sendData,                                                   \
-    Native* recvData,                                                         \
-    int count,                                                                \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::scatter                                                    \
-    (                                                                         \
-        sendData, recvData, count,                                            \
-        TaggedType, comm                                                      \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-                                                                              \
-void Foam::UPstream::mpiAllGather                                             \
-(                                                                             \
-    Native* allData,                                                          \
-    int count,                                                                \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allGather                                                  \
-    (                                                                         \
-        allData, count,                                                       \
-        TaggedType, comm                                                      \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::UPstream::mpiGatherv                                               \
-(                                                                             \
-    const Native* sendData,                                                   \
-    int sendCount,                                                            \
-                                                                              \
-    Native* recvData,                                                         \
-    const UList<int>& recvCounts,                                             \
-    const UList<int>& recvOffsets,                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::gatherv                                                    \
-    (                                                                         \
-        sendData, sendCount,                                                  \
-        recvData, recvCounts, recvOffsets,                                    \
-        TaggedType, comm                                                      \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::UPstream::mpiScatterv                                              \
-(                                                                             \
-    const Native* sendData,                                                   \
-    const UList<int>& sendCounts,                                             \
-    const UList<int>& sendOffsets,                                            \
-                                                                              \
-    Native* recvData,                                                         \
-    int recvCount,                                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::scatterv                                                   \
-    (                                                                         \
-        sendData, sendCounts, sendOffsets,                                    \
-        recvData, recvCount,                                                  \
-        TaggedType, comm                                                      \
-    );                                                                        \
+void Foam::UPstream::mpi_gather
+(
+    const void* sendData,       // Type checking done by caller
+    void* recvData,             // Type checking done by caller
+    int count,
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
+
+    const int communicator,     // Index into MPICommunicators_
+    UPstream::Request* req
+)
+{
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
+
+    if (FOAM_UNLIKELY(UPstream::debug))
+    {
+        Perr<< "[mpi_gather] : "
+            << " type:" << int(dataTypeId) << " count:" << count
+            << " comm:" << communicator
+            << Foam::endl;
+    }
+
+    {
+        // Regular gather
+
+        PstreamDetail::gather
+        (
+            sendData,
+            recvData,
+            count,
+            datatype,
+            communicator,
+            req
+        );
+    }
 }
 
 
-//TDB: Pstream_CommonRoutines(bool, MPI_C_BOOL);
-Pstream_CommonRoutines(char, MPI_BYTE);
-Pstream_CommonRoutines(int32_t, MPI_INT32_T);
-Pstream_CommonRoutines(int64_t, MPI_INT64_T);
-Pstream_CommonRoutines(uint32_t, MPI_UINT32_T);
-Pstream_CommonRoutines(uint64_t, MPI_UINT64_T);
-Pstream_CommonRoutines(float,   MPI_FLOAT);
-Pstream_CommonRoutines(double,  MPI_DOUBLE);
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+void Foam::UPstream::mpi_scatter
+(
+    const void* sendData,       // Type checking done by caller
+    void* recvData,             // Type checking done by caller
+    int count,
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
+
+    const int communicator,     // Index into MPICommunicators_
+    UPstream::Request* req
+)
+{
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
+
+    if (FOAM_UNLIKELY(UPstream::debug))
+    {
+        Perr<< "[mpi_scatter] : "
+            << " type:" << int(dataTypeId) << " count:" << count
+            << " comm:" << communicator
+            << Foam::endl;
+    }
+
+    {
+        // Regular scatter
+
+        PstreamDetail::scatter
+        (
+            sendData,
+            recvData,
+            count,
+            datatype,
+            communicator,
+            req
+        );
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+void Foam::UPstream::mpi_allgather
+(
+    void* allData,        // Type checking done by caller
+    int count,
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
+
+    const int communicator,     // Index into MPICommunicators_
+    UPstream::Request* req
+)
+{
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
+
+    if (FOAM_UNLIKELY(UPstream::debug))
+    {
+        Perr<< "[mpi_allgather] : "
+            << " type:" << int(dataTypeId) << " count:" << count
+            << " comm:" << communicator
+            << Foam::endl;
+    }
+
+    {
+        // Regular all gather
+
+        PstreamDetail::allGather
+        (
+            allData,
+            count,
+            datatype,
+            communicator,
+            req
+        );
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+void Foam::UPstream::mpi_gatherv
+(
+    const void* sendData,
+    int sendCount,
+    void* recvData,
+    const UList<int>& recvCounts,
+    const UList<int>& recvOffsets,
+
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
+    const int communicator
+)
+{
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
+
+    if
+    (
+        FOAM_UNLIKELY
+        (
+            !is_basic_dataType(dataTypeId)
+        )
+    )
+    {
+        FatalErrorInFunction;
+        printErrorNonIntrinsic("MPI_Gatherv()", dataTypeId);
+        FatalError << Foam::abort(FatalError);
+    }
+
+    {
+        PstreamDetail::gatherv
+        (
+            sendData, sendCount,
+            recvData, recvCounts, recvOffsets,
+            datatype, communicator
+        );
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+void Foam::UPstream::mpi_scatterv
+(
+    const void* sendData,
+    const UList<int>& sendCounts,
+    const UList<int>& sendOffsets,
+
+    void* recvData,
+    int recvCount,
+
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
+    const int communicator
+)
+{
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
+
+    if
+    (
+        FOAM_UNLIKELY
+        (
+            !is_basic_dataType(dataTypeId)
+        )
+    )
+    {
+        FatalErrorInFunction;
+        printErrorNonIntrinsic("MPI_Scatterv()", dataTypeId);
+        FatalError << Foam::abort(FatalError);
+    }
+
+    {
+        PstreamDetail::scatterv
+        (
+            sendData, sendCounts, sendOffsets,
+            recvData, recvCount,
+            datatype, communicator
+        );
+    }
+}
 
-#undef Pstream_CommonRoutines
 
 // ************************************************************************* //
diff --git a/src/Pstream/mpi/UPstreamReduce.C b/src/Pstream/mpi/UPstreamReduce.C
index d9e96a89ceb13cd211c858a34345ed50bf0cd092..3ade1de388ebd1c44420aac082dc645012ab06cb 100644
--- a/src/Pstream/mpi/UPstreamReduce.C
+++ b/src/Pstream/mpi/UPstreamReduce.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2022-2023 OpenCFD Ltd.
+    Copyright (C) 2022-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -31,261 +31,257 @@ License
 
 #include <cinttypes>
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
 
 // Special reductions for bool
 
-void Foam::UPstream::reduceAnd(bool& value, const label comm)
+void Foam::UPstream::reduceAnd(bool& value, const int communicator)
 {
-    PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LAND, comm);
+    PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LAND, communicator);
 }
 
 
-void Foam::UPstream::reduceOr(bool& value, const label comm)
+void Foam::UPstream::reduceOr(bool& value, const int communicator)
 {
-    PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LOR, comm);
+    PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LOR, communicator);
 }
 
 
 void Foam::reduce
 (
     bool& value,
-    const andOp<bool>&,
+    Foam::andOp<bool>,
     const int tag,  /* (unused) */
-    const label comm
+    const int communicator
 )
 {
-    PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LAND, comm);
+    UPstream::reduceAnd(value, communicator);
 }
 
 
 void Foam::reduce
 (
     bool& value,
-    const orOp<bool>&,
+    Foam::orOp<bool>,
     const int tag,  /* (unused) */
-    const label comm
+    const int communicator
 )
 {
-    PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LOR, comm);
+    UPstream::reduceOr(value, communicator);
 }
 
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Common reductions
-
-#undef  Pstream_CommonReductions
-#define Pstream_CommonReductions(Native, TaggedType)                          \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const minOp<Native>&,                                                     \
-    const int tag,  /* (unused) */                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        values, size, TaggedType, MPI_MIN, comm                               \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const maxOp<Native>&,                                                     \
-    const int tag,  /* (unused) */                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        values, size, TaggedType, MPI_MAX, comm                               \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const sumOp<Native>&,                                                     \
-    const int tag,  /* (unused) */                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        values, size, TaggedType, MPI_SUM, comm                               \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const minOp<Native>&,                                                     \
-    const int tag,  /* (unused) */                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        &value, 1, TaggedType, MPI_MIN, comm                                  \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const maxOp<Native>&,                                                     \
-    const int tag,  /* (unused) */                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        &value, 1, TaggedType, MPI_MAX, comm                                  \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const sumOp<Native>&,                                                     \
-    const int tag,  /* (unused) */                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        &value, 1, TaggedType, MPI_SUM, comm                                  \
-    );                                                                        \
+static inline bool is_basic_dataType(Foam::UPstream::dataTypes id) noexcept
+{
+    return
+    (
+        int(id) >= int(Foam::UPstream::dataTypes::Basic_begin)
+     && int(id)  < int(Foam::UPstream::dataTypes::Basic_end)
+    );
+}
+
+static inline bool is_reduce_opCode(Foam::UPstream::opCodes id) noexcept
+{
+    return
+    (
+        int(id) >= int(Foam::UPstream::opCodes::Basic_begin)
+     && int(id)  < int(Foam::UPstream::opCodes::Basic_end)
+    );
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Floating-point reductions
-
-#undef  Pstream_FloatReductions
-#define Pstream_FloatReductions(Native, TaggedType)                           \
-                                                                              \
-Pstream_CommonReductions(Native, TaggedType);                                 \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const sumOp<Native>&,                                                     \
-    const int tag,  /* (unused) */                                            \
-    const label comm,                                                         \
-    UPstream::Request& req                                                    \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        values, size, TaggedType, MPI_SUM, comm, &req                         \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const sumOp<Native>&,                                                     \
-    const int tag,  /* (unused) */                                            \
-    const label comm,                                                         \
-    UPstream::Request& req                                                    \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        &value, 1, TaggedType, MPI_SUM, comm, &req                            \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::sumReduce                                                          \
-(                                                                             \
-    Native& value,                                                            \
-    label& count,                                                             \
-    const int tag,  /* (unused) */                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    if (UPstream::is_parallel(comm))                                          \
-    {                                                                         \
-        Native values[2];                                                     \
-        values[0] = static_cast<Native>(count);                               \
-        values[1] = value;                                                    \
-                                                                              \
-        PstreamDetail::allReduce<Native>                                      \
-        (                                                                     \
-            values, 2, TaggedType, MPI_SUM, comm                              \
-        );                                                                    \
-                                                                              \
-        count = static_cast<label>(values[0]);                                \
-        value = values[1];                                                    \
-    }                                                                         \
+namespace
+{
+
+using namespace Foam;
+
+// Local function to print some error information
+void printErrorMessage
+(
+    const void* values,
+    const UPstream::dataTypes datatype_id,
+    const UPstream::opCodes opcode_id
+)
+{
+    FatalError
+        << "Bad input for reduce(): likely a programming problem\n";
+
+    if (!is_basic_dataType(datatype_id))
+    {
+        FatalError<< "    Non-basic data tyoe (" << int(datatype_id) << ")\n";
+    }
+
+    if (!is_reduce_opCode(opcode_id))
+    {
+        FatalError<< "    Invalid reduce op (" << int(opcode_id) << ")\n";
+    }
+
+    if (values == nullptr)
+    {
+        FatalError<< "    nullptr for values\n";
+    }
+    FatalError<< Foam::endl;
 }
 
+} // End anonymous namespace
+
+
+// * * * * * * * * * * Protected Static Member Functions * * * * * * * * * * //
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// Bitwise reductions
-
-#undef  Pstream_BitwiseReductions
-#define Pstream_BitwiseReductions(Native, TaggedType)                         \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native values[],                                                          \
-    const int size,                                                           \
-    const bitOrOp<Native>&,                                                   \
-    const int tag,  /* (unused) */                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        values, size, TaggedType, MPI_BOR, comm                               \
-    );                                                                        \
-}                                                                             \
-                                                                              \
-void Foam::reduce                                                             \
-(                                                                             \
-    Native& value,                                                            \
-    const bitOrOp<Native>&,                                                   \
-    const int tag,  /* (unused) */                                            \
-    const label comm                                                          \
-)                                                                             \
-{                                                                             \
-    PstreamDetail::allReduce<Native>                                          \
-    (                                                                         \
-        &value, 1, TaggedType, MPI_BOR, comm                                  \
-    );                                                                        \
-}                                                                             \
-
-\
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-Pstream_CommonReductions(int32_t, MPI_INT32_T);
-Pstream_CommonReductions(int64_t, MPI_INT64_T);
-Pstream_CommonReductions(uint32_t, MPI_UINT32_T);
-Pstream_CommonReductions(uint64_t, MPI_UINT64_T);
-
-Pstream_FloatReductions(float, MPI_FLOAT);
-Pstream_FloatReductions(double, MPI_DOUBLE);
-
-Pstream_BitwiseReductions(unsigned char, MPI_UNSIGNED_CHAR);
-Pstream_BitwiseReductions(unsigned int, MPI_UNSIGNED);
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#undef Pstream_CommonReductions
-#undef Pstream_FloatReductions
-#undef Pstream_BitwiseReductions
+// The intel-mpi version of MPI_Reduce() does not accept IN_PLACE
+// operations (issue #3331)
+// Assume the same may be true for ms-mpi
+#if defined(I_MPI_VERSION) || defined(MSMPI_VER)
+#define Foam_broken_vendor_INPLACE_REDUCE
+#else
+#undef  Foam_broken_vendor_INPLACE_REDUCE
+#endif
+
+void Foam::UPstream::mpi_reduce
+(
+    void* values,                          // Type checking done by caller
+    int count,
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
+    const UPstream::opCodes opCodeId,      // Proper code passed by caller
+    const int communicator,                // Index into MPICommunicators_
+    UPstream::Request* req
+)
+{
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
+    MPI_Op optype = PstreamGlobals::getOpCode(opCodeId);
+
+    if (!count || !UPstream::is_parallel(communicator))
+    {
+        // Nothing to do - ignore
+        return;
+    }
+    if
+    (
+        FOAM_UNLIKELY
+        (
+            !is_basic_dataType(dataTypeId)
+         || !is_reduce_opCode(opCodeId)
+         || (values == nullptr)
+        )
+    )
+    {
+        FatalErrorInFunction;
+        printErrorMessage(values, dataTypeId, opCodeId);
+        FatalError << Foam::abort(FatalError);
+    }
+
+    if (FOAM_UNLIKELY(UPstream::debug))
+    {
+        Perr<< "[mpi_reduce] : "
+            << " op:" << int(opCodeId)
+            << " type:" << int(dataTypeId) << " count:" << count
+            << " comm:" << communicator
+            << Foam::endl;
+    }
+
+    // Workaround for broken in-place handling.
+    // Use a local buffer to send the data from.
+
+    #ifdef Foam_broken_vendor_INPLACE_REDUCE
+    static std::unique_ptr<char[]> work;
+    static int work_len(0);
+
+    const int num_bytes = [=](int n)
+    {
+        int size = 1;
+        MPI_Type_size(datatype, &size);
+        return (size * n);
+    }(count);
+
+    if (work_len < num_bytes)
+    {
+        // Min length to avoid many initial re-allocations
+        work_len = std::max(256, num_bytes);
+        work.reset();
+        work = std::make_unique<char[]>(work_len);
+    }
+    void* sendData = work.get();
+
+    std::memcpy(sendData, values, num_bytes);
+    #else
+    void* sendData(nullptr);
+    #endif
+
+
+    {
+        // Regular reduce
+
+        PstreamDetail::reduce0
+        (
+            sendData,
+            values,
+            count,
+            datatype,
+            optype,
+            communicator,
+            req
+        );
+    }
+}
+
+
+void Foam::UPstream::mpi_allreduce
+(
+    void* values,                          // Type checking done by caller
+    int count,
+    const UPstream::dataTypes dataTypeId,  // Proper type passed by caller
+    const UPstream::opCodes opCodeId,      // Proper code passed by caller
+    const int communicator,                // Index into MPICommunicators_
+    UPstream::Request* req
+)
+{
+    MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
+    MPI_Op optype = PstreamGlobals::getOpCode(opCodeId);
+
+    if (!count || !UPstream::is_parallel(communicator))
+    {
+        // Nothing to do - ignore
+        return;
+    }
+    if
+    (
+        FOAM_UNLIKELY
+        (
+            !is_basic_dataType(dataTypeId)
+         || !is_reduce_opCode(opCodeId)
+         || (values == nullptr)
+        )
+    )
+    {
+        FatalErrorInFunction;
+        printErrorMessage(values, dataTypeId, opCodeId);
+        FatalError << Foam::abort(FatalError);
+    }
+
+    if (FOAM_UNLIKELY(UPstream::debug))
+    {
+        Perr<< "[mpi_allreduce] : "
+            << " op:" << int(opCodeId)
+            << " type:" << int(dataTypeId) << " count:" << count
+            << " comm:" << communicator
+            << Foam::endl;
+    }
+
+    {
+        // Regular allReduce
+
+        PstreamDetail::allReduce
+        (
+            values,
+            count,
+            datatype,
+            optype,
+            communicator,
+            req
+        );
+    }
+}
 
 
 // ************************************************************************* //
diff --git a/src/Pstream/mpi/UPstreamWindow.C b/src/Pstream/mpi/UPstreamWindow.C
index 8bcce43014d910a105350a6baeb094f2a53e23e6..0657c86096aeb036b67160668138b38dd3aaff10 100644
--- a/src/Pstream/mpi/UPstreamWindow.C
+++ b/src/Pstream/mpi/UPstreamWindow.C
@@ -50,4 +50,29 @@ void Foam::UPstream::Window::reset() noexcept
 }
 
 
+int Foam::UPstream::Window::size() const
+{
+    int val = 0;
+
+    MPI_Win win = PstreamUtils::Cast::to_mpi(*this);
+    MPI_Group group;
+
+    // Get num of ranks from the group information
+    if
+    (
+        (MPI_WIN_NULL != win)
+     && (MPI_SUCCESS == MPI_Win_get_group(win, &group))
+    )
+    {
+        if (MPI_SUCCESS != MPI_Group_size(group, &val))
+        {
+            val = 0;
+        }
+        MPI_Group_free(&group);
+    }
+
+    return val;
+}
+
+
 // ************************************************************************* //
diff --git a/src/Pstream/mpi/UPstreamWrapping.H b/src/Pstream/mpi/UPstreamWrapping.H
index b98c99f314f2c2a521016c7f4117be46df886f42..2587d840dc2a9de4369b622114e7e3a798fef461 100644
--- a/src/Pstream/mpi/UPstreamWrapping.H
+++ b/src/Pstream/mpi/UPstreamWrapping.H
@@ -62,6 +62,7 @@ bool broadcast0
 template<class Type>
 void reduce0
 (
+    const Type* sendData,   // Use nullptr for in-place operation
     Type* values,
     int count,
     MPI_Datatype datatype,
@@ -70,7 +71,7 @@ void reduce0
     UPstream::Request* req = nullptr    // Non-null for non-blocking
 );
 
-// MPI_Allreduce or MPI_Iallreduce
+// MPI_Allreduce or MPI_Iallreduce : in-place operation
 template<class Type>
 void allReduce
 (
diff --git a/src/Pstream/mpi/UPstreamWrapping.txx b/src/Pstream/mpi/UPstreamWrapping.txx
index 057c0e6025fe25709699ddcb0d42194fc75cc018..fdcc5d22183b93002567311730ca4fec62560f33 100644
--- a/src/Pstream/mpi/UPstreamWrapping.txx
+++ b/src/Pstream/mpi/UPstreamWrapping.txx
@@ -74,6 +74,7 @@ bool Foam::PstreamDetail::broadcast0
 template<class Type>
 void Foam::PstreamDetail::reduce0
 (
+    const Type* sendData,
     Type* values,
     int count,
     MPI_Datatype datatype,
@@ -92,6 +93,13 @@ void Foam::PstreamDetail::reduce0
         return;
     }
 
+    const void* send_buffer = sendData;
+    if (sendData == nullptr || (sendData == values))
+    {
+        // Appears to be an in-place request
+        send_buffer = MPI_IN_PLACE;
+    }
+
     if (FOAM_UNLIKELY(PstreamGlobals::warnCommunicator(communicator)))
     {
         if (immediate)
@@ -102,22 +110,12 @@ void Foam::PstreamDetail::reduce0
         {
             Perr<< "** MPI_Reduce (blocking):";
         }
-        if constexpr (std::is_void_v<Type>)
+        if (sendData == nullptr || (sendData == values))
         {
-            Perr<< count << " values";
-        }
-        else
-        {
-            if (count == 1)
-            {
-                Perr<< (*values);
-            }
-            else
-            {
-                Perr<< UList<Type>(values, count);
-            }
+            Perr<< " [inplace]";
         }
-        Perr<< " with comm:" << communicator
+        Perr<< " count:" << count
+            << " comm:" << communicator
             << " warnComm:" << UPstream::warnComm << endl;
         error::printStack(Perr);
     }
@@ -135,7 +133,7 @@ void Foam::PstreamDetail::reduce0
         returnCode =
             MPI_Ireduce
             (
-                MPI_IN_PLACE,  // recv is also send
+                send_buffer,
                 values,
                 count,
                 datatype,
@@ -156,7 +154,7 @@ void Foam::PstreamDetail::reduce0
         returnCode =
             MPI_Reduce
             (
-                MPI_IN_PLACE,  // recv is also send
+                send_buffer,
                 values,
                 count,
                 datatype,
@@ -174,24 +172,9 @@ void Foam::PstreamDetail::reduce0
         FatalErrorInFunction<< "MPI Reduce ";
         if (immediate) FatalError<< "(non-blocking) ";
 
-        FatalError<< "failed for ";
-
-        if constexpr (std::is_void_v<Type>)
-        {
-            FatalError<< count << " values";
-        }
-        else
-        {
-            if (count == 1)
-            {
-                FatalError<< (*values);
-            }
-            else
-            {
-                FatalError<< UList<Type>(values, count);
-            }
-        }
-        FatalError<< Foam::abort(FatalError);
+        FatalError
+            << "failed for count:" << count
+            << Foam::abort(FatalError);
     }
 }
 
@@ -997,7 +980,7 @@ void Foam::PstreamDetail::gather
 
     const bool immediate = (req);
 
-    if (!UPstream::is_rank(communicator) || !count)
+    if (!count || !UPstream::is_rank(communicator))
     {
         return;
     }
@@ -1115,7 +1098,7 @@ void Foam::PstreamDetail::scatter
 
     const bool immediate = (req);
 
-    if (!UPstream::is_rank(communicator) || !count)
+    if (!count || !UPstream::is_rank(communicator))
     {
         return;
     }
@@ -1243,9 +1226,14 @@ void Foam::PstreamDetail::gatherv
     }
     else if (!UPstream::is_parallel(communicator))
     {
-        // recvCounts[0] may be invalid - use sendCount instead
-        if (sendData && recvData)
+        if constexpr (std::is_void_v<Type>)
         {
+            // Cannot copy data here since we don't know the number of bytes
+            // - must be done by the caller.
+        }
+        else if (sendData && recvData)
+        {
+            // recvCounts[0] may be invalid - use sendCount instead
             std::memmove(recvData, sendData, sendCount*sizeof(Type));
         }
         return;
@@ -1385,7 +1373,15 @@ void Foam::PstreamDetail::scatterv
     }
     else if (!UPstream::is_parallel(communicator))
     {
-        std::memmove(recvData, sendData, recvCount*sizeof(Type));
+        if constexpr (std::is_void_v<Type>)
+        {
+            // Cannot copy data here since we don't know the number of bytes
+            // - must be done by the caller.
+        }
+        else if (sendData && recvData)
+        {
+            std::memmove(recvData, sendData, recvCount*sizeof(Type));
+        }
         return;
     }
 
diff --git a/src/dynamicMesh/motionSolvers/displacement/pointSmoothing/hexMeshSmootherMotionSolver.C b/src/dynamicMesh/motionSolvers/displacement/pointSmoothing/hexMeshSmootherMotionSolver.C
index d8964afef6d473e5f2c29f484b4173baebb4c1d1..2b28c6e06d2e1a8b3a723e8594a4e27ae84670fa 100644
--- a/src/dynamicMesh/motionSolvers/displacement/pointSmoothing/hexMeshSmootherMotionSolver.C
+++ b/src/dynamicMesh/motionSolvers/displacement/pointSmoothing/hexMeshSmootherMotionSolver.C
@@ -464,7 +464,7 @@ Foam::labelList Foam::hexMeshSmootherMotionSolver::countZeroOrPos
         }
     }
 
-    Pstream::listCombineReduce(n, plusEqOp<label>());
+    Pstream::listReduce(n, sumOp<label>());
     return n;
 }
 
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.C
index 73501db8cf9852d788b938841e9606ffc8214fdb..380bc5080325ee944345c18b0fcac58886465d3e 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.C
@@ -440,7 +440,7 @@ Foam::scalar Foam::hexRef8::getLevel0EdgeLength() const
 
     // Get the minimum per level over all processors. Note minimum so if
     // cells are not cubic we use the smallest edge side.
-    Pstream::listCombineReduce(typEdgeLenSqr, minEqOp<scalar>());
+    Pstream::listReduce(typEdgeLenSqr, minOp<scalar>());
 
     if (debug)
     {
@@ -474,7 +474,7 @@ Foam::scalar Foam::hexRef8::getLevel0EdgeLength() const
         }
     }
 
-    Pstream::listCombineReduce(maxEdgeLenSqr, maxEqOp<scalar>());
+    Pstream::listReduce(maxEdgeLenSqr, maxOp<scalar>());
 
     if (debug)
     {
diff --git a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
index 839d102a171ffd708b3cd0dd51084d0494c50df8..2c5e8ec4197886b4d896801ccb2713792e53f0b6 100644
--- a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
+++ b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
@@ -1108,7 +1108,7 @@ void Foam::fvMeshSubset::reset
         // Get patch sizes (up to nextPatchID).
         // Note that up to nextPatchID the globalPatchMap is an identity so
         // no need to index through that.
-        Pstream::listCombineReduce(globalPatchSizes, plusEqOp<label>());
+        Pstream::listReduce(globalPatchSizes, sumOp<label>());
 
         // Now all processors have all the patchnames.
         // Decide: if all processors have the same patch names and size is zero
diff --git a/src/functionObjects/field/Curle/Curle.C b/src/functionObjects/field/Curle/Curle.C
index 6b53be072347faaa564cdd1971bc2ffd2f709cca..0ee78d920037d28ef35e47fd4c2dc9a1893945c9 100644
--- a/src/functionObjects/field/Curle/Curle.C
+++ b/src/functionObjects/field/Curle/Curle.C
@@ -222,7 +222,7 @@ bool Foam::functionObjects::Curle::execute()
 
     pDash /= 4*mathematical::pi;
 
-    Pstream::listCombineReduce(pDash, plusEqOp<scalar>());
+    Pstream::listReduce(pDash, sumOp<scalar>());
 
     if (surfaceWriterPtr_)
     {
diff --git a/src/functionObjects/field/columnAverage/columnAverageTemplates.C b/src/functionObjects/field/columnAverage/columnAverageTemplates.C
index 2bba02a3dc32112295fbe26ae61e47ce7bf29dae..aa7cc893e9b368f5acbb9f4071bbad245be21df0 100644
--- a/src/functionObjects/field/columnAverage/columnAverageTemplates.C
+++ b/src/functionObjects/field/columnAverage/columnAverageTemplates.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018-2024 OpenCFD Ltd.
+    Copyright (C) 2018-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -88,8 +88,8 @@ bool Foam::functionObjects::columnAverage::columnAverageField
         }
 
         // Global sum
-        Pstream::listCombineReduce(regionField, plusEqOp<Type>());
-        Pstream::listCombineReduce(regionCount, plusEqOp<label>());
+        Pstream::listReduce(regionField, sumOp<Type>());
+        Pstream::listReduce(regionCount, sumOp<label>());
 
         forAll(regionField, regioni)
         {
diff --git a/src/functionObjects/field/extractEulerianParticles/extractEulerianParticles/extractEulerianParticles.C b/src/functionObjects/field/extractEulerianParticles/extractEulerianParticles/extractEulerianParticles.C
index c8e2c76cb505851c14def8c44476d0cfa89cf543..bba3209e6397eb5c1afff010093b4fb8e4a8b541 100644
--- a/src/functionObjects/field/extractEulerianParticles/extractEulerianParticles/extractEulerianParticles.C
+++ b/src/functionObjects/field/extractEulerianParticles/extractEulerianParticles/extractEulerianParticles.C
@@ -329,7 +329,7 @@ void Foam::functionObjects::extractEulerianParticles::calculateAddressing
 
     // Create map from new regions to slots in particles list
     // - filter through new-to-new addressing to identify new particles
-    Pstream::listCombineReduce(newToNewRegion, maxEqOp<label>());
+    Pstream::listReduce(newToNewRegion, maxOp<label>());
 
     label nParticle = -1;
     labelHashSet newRegions;
@@ -348,7 +348,7 @@ void Foam::functionObjects::extractEulerianParticles::calculateAddressing
 
     // Accumulate old region data or create a new particle if there is no
     // mapping from the old-to-new region
-    Pstream::listCombineReduce(oldToNewRegion, maxEqOp<label>());
+    Pstream::listReduce(oldToNewRegion, maxOp<label>());
 
     List<eulerianParticle> newParticles(newRegionToParticleMap.size());
     forAll(oldToNewRegion, oldRegioni)
diff --git a/src/functionObjects/field/histogram/histogramModels/equalBinWidth/equalBinWidth.C b/src/functionObjects/field/histogram/histogramModels/equalBinWidth/equalBinWidth.C
index 790e6213c540f37518df43040f3495b52aeb0642..e8d40cb54e47dc277562b9eb04fde2415837df66 100644
--- a/src/functionObjects/field/histogram/histogramModels/equalBinWidth/equalBinWidth.C
+++ b/src/functionObjects/field/histogram/histogramModels/equalBinWidth/equalBinWidth.C
@@ -155,8 +155,8 @@ bool Foam::histogramModels::equalBinWidth::write(const bool log)
             dataCount[bini]++;
         }
     }
-    Pstream::listCombineGather(dataNormalised, plusEqOp<scalar>());
-    Pstream::listCombineGather(dataCount, plusEqOp<label>());
+    Pstream::listGather(dataNormalised, sumOp<scalar>());
+    Pstream::listGather(dataCount, sumOp<label>());
 
 
     // Write histogram data
diff --git a/src/functionObjects/field/histogram/histogramModels/unequalBinWidth/unequalBinWidth.C b/src/functionObjects/field/histogram/histogramModels/unequalBinWidth/unequalBinWidth.C
index 658c54bd135806c335160d08724ae39ccb5f02f6..aec3f84f0b1e65d1fe9a78a6c23713ff6a85f364 100644
--- a/src/functionObjects/field/histogram/histogramModels/unequalBinWidth/unequalBinWidth.C
+++ b/src/functionObjects/field/histogram/histogramModels/unequalBinWidth/unequalBinWidth.C
@@ -129,8 +129,8 @@ bool Foam::histogramModels::unequalBinWidth::write(const bool log)
             }
         }
     }
-    Pstream::listCombineGather(dataNormalised, plusEqOp<scalar>());
-    Pstream::listCombineGather(dataCount, plusEqOp<label>());
+    Pstream::listGather(dataNormalised, sumOp<scalar>());
+    Pstream::listGather(dataCount, sumOp<label>());
 
 
     // Write histogram data
diff --git a/src/functionObjects/forces/propellerInfo/propellerInfo.C b/src/functionObjects/forces/propellerInfo/propellerInfo.C
index b080d929a36f502667bb78ac1fb0ffd9533d562f..18a47b728a05ce1465c4c978a8555e225fedf588 100644
--- a/src/functionObjects/forces/propellerInfo/propellerInfo.C
+++ b/src/functionObjects/forces/propellerInfo/propellerInfo.C
@@ -791,7 +791,7 @@ Foam::tmp<Foam::Field<Type>> Foam::functionObjects::propellerInfo::interpolate
         }
     }
 
-    Pstream::listCombineReduce(field, maxEqOp<Type>());
+    Pstream::listReduce(field, maxOp<Type>());
 
     return tfield;
 }
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleZoneInfo/ParticleZoneInfo.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleZoneInfo/ParticleZoneInfo.C
index 522e94c35bcd0eccaaeef03ab4009b4f68ea6b78..dcd6e8effecd5d2a83818bb5176551c43c3d782c 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleZoneInfo/ParticleZoneInfo.C
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleZoneInfo/ParticleZoneInfo.C
@@ -365,7 +365,7 @@ void Foam::ParticleZoneInfo<CloudType>::write()
     {
         // Find number of particles per proc
         labelList allMaxIDs(maxIDs_);
-        Pstream::listCombineReduce(allMaxIDs, maxEqOp<label>());
+        Pstream::listReduce(allMaxIDs, maxOp<label>());
 
         // Combine into single list
         label n = returnReduce(data_.size(), sumOp<label>());
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/CellZoneInjection/CellZoneInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/CellZoneInjection/CellZoneInjection.C
index 5ee1a9e6ff77be4ac6064cb19b2ceb9b71bb9745..5e2ed632cc9c8bbb9f3eaf81a08ca3fc31798e1b 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/CellZoneInjection/CellZoneInjection.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/CellZoneInjection/CellZoneInjection.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2015-2023 OpenCFD Ltd.
+    Copyright (C) 2015-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -121,7 +121,7 @@ void Foam::CellZoneInjection<CloudType>::setPositions
         globalPositions.range(myProci)
     ) = positions;
 
-    Pstream::listCombineReduce(allPositions, minEqOp<point>());
+    Pstream::listReduce(allPositions, minOp<point>());
 
     // Gather local cell tet and tet-point Ids, but leave non-local ids set -1
     SubList<label>
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.C b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.C
index 440103171a753c35acd36ce7845b15a4c91adcd4..5a52be2cb19339ec49c536adc68103680278c2fb 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2015-2020 OpenCFD Ltd.
+    Copyright (C) 2015-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -372,28 +372,28 @@ void Foam::LocalInteraction<CloudType>::info()
     labelListList npe(nEscape_);
     forAll(npe, i)
     {
-        Pstream::listCombineGather(npe[i], plusEqOp<label>());
+        Pstream::listGather(npe[i], sumOp<label>());
         npe[i] = npe[i] + npe0[i];
     }
 
     scalarListList mpe(massEscape_);
     forAll(mpe, i)
     {
-        Pstream::listCombineGather(mpe[i], plusEqOp<scalar>());
+        Pstream::listGather(mpe[i], sumOp<scalar>());
         mpe[i] = mpe[i] + mpe0[i];
     }
 
     labelListList nps(nStick_);
     forAll(nps, i)
     {
-        Pstream::listCombineGather(nps[i], plusEqOp<label>());
+        Pstream::listGather(nps[i], sumOp<label>());
         nps[i] = nps[i] + nps0[i];
     }
 
     scalarListList mps(massStick_);
     forAll(nps, i)
     {
-        Pstream::listCombineGather(mps[i], plusEqOp<scalar>());
+        Pstream::listGather(mps[i], sumOp<scalar>());
         mps[i] = mps[i] + mps0[i];
     }
 
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/RecycleInteraction/RecycleInteraction.C b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/RecycleInteraction/RecycleInteraction.C
index 78501a00a22a731c7101135fe8e9c966d37166e6..e185e16034a2c72861165281aea32cb4c142da09 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/RecycleInteraction/RecycleInteraction.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/RecycleInteraction/RecycleInteraction.C
@@ -379,28 +379,28 @@ void Foam::RecycleInteraction<CloudType>::info()
 
     forAll(npr, i)
     {
-        Pstream::listCombineGather(npr[i], plusEqOp<label>());
+        Pstream::listGather(npr[i], sumOp<label>());
         npr[i] = npr[i] + npr0[i];
     }
 
     scalarListList mpr(massRemoved_);
     forAll(mpr, i)
     {
-        Pstream::listCombineGather(mpr[i], plusEqOp<scalar>());
+        Pstream::listGather(mpr[i], sumOp<scalar>());
         mpr[i] = mpr[i] + mpr0[i];
     }
 
     labelListList npi(nInjected_);
     forAll(npi, i)
     {
-        Pstream::listCombineGather(npi[i], plusEqOp<label>());
+        Pstream::listGather(npi[i], sumOp<label>());
         npi[i] = npi[i] + npi0[i];
     }
 
     scalarListList mpi(massInjected_);
     forAll(mpi, i)
     {
-        Pstream::listCombineGather(mpi[i], plusEqOp<scalar>());
+        Pstream::listGather(mpi[i], sumOp<scalar>());
         mpi[i] = mpi[i] + mpi0[i];
     }
 
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.C b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.C
index 5f9f1033a7e523860dee5154eab2180613bc3b00..00ca30c613cd93d744124b98f43fe51c566596f3 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.C
@@ -285,28 +285,28 @@ void Foam::StandardWallInteraction<CloudType>::info()
 
     forAll(npe, i)
     {
-        Pstream::listCombineGather(npe[i], plusEqOp<label>());
+        Pstream::listGather(npe[i], sumOp<label>());
         npe[i] = npe[i] + npe0[i];
     }
 
     scalarListList mpe(massEscape_);
     forAll(mpe, i)
     {
-        Pstream::listCombineGather(mpe[i], plusEqOp<scalar>());
+        Pstream::listGather(mpe[i], sumOp<scalar>());
         mpe[i] = mpe[i] + mpe0[i];
     }
 
     labelListList nps(nStick_);
     forAll(nps, i)
     {
-        Pstream::listCombineGather(nps[i], plusEqOp<label>());
+        Pstream::listGather(nps[i], sumOp<label>());
         nps[i] = nps[i] + nps0[i];
     }
 
     scalarListList mps(massStick_);
     forAll(nps, i)
     {
-        Pstream::listCombineGather(mps[i], plusEqOp<scalar>());
+        Pstream::listGather(mps[i], sumOp<scalar>());
         mps[i] = mps[i] + mps0[i];
     }
 
diff --git a/src/lumpedPointMotion/movement/lumpedPointMovement.C b/src/lumpedPointMotion/movement/lumpedPointMovement.C
index 524e2be769fd92fd4f754f9f23c95aa6ad2f1f15..f31f4dc907e52a191a1406ecc53770f8cff4097b 100644
--- a/src/lumpedPointMotion/movement/lumpedPointMovement.C
+++ b/src/lumpedPointMotion/movement/lumpedPointMovement.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2016-2024 OpenCFD Ltd.
+    Copyright (C) 2016-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -878,7 +878,7 @@ Foam::List<Foam::scalar> Foam::lumpedPointMovement::areas
         }
     }
 
-    Pstream::listCombineReduce(zoneAreas, plusEqOp<scalar>());
+    Pstream::listReduce(zoneAreas, sumOp<scalar>());
 
     return zoneAreas;
 }
@@ -1006,8 +1006,8 @@ bool Foam::lumpedPointMovement::forcesAndMoments
         Info<<"No pressure field" << endl;
     }
 
-    Pstream::listCombineReduce(forces, plusEqOp<vector>());
-    Pstream::listCombineReduce(moments, plusEqOp<vector>());
+    Pstream::listReduce(forces, sumOp<vector>());
+    Pstream::listReduce(moments, sumOp<vector>());
 
     return true;
 }
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C
index ed4e8cc9679a3023c0537c782d62715cebe5f83f..5e3bafccad8cc3d94cf57e1ad4800c61abec6ca6 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C
@@ -2050,7 +2050,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::meshRefinement::balance
             labelList nProcCells(distributor.countCells(distribution));
             Pout<< "Wanted distribution:" << nProcCells << endl;
 
-            Pstream::listCombineReduce(nProcCells, plusEqOp<label>());
+            Pstream::listReduce(nProcCells, sumOp<label>());
 
             Pout<< "Wanted resulting decomposition:" << endl;
             forAll(nProcCells, proci)
@@ -3611,7 +3611,7 @@ const
             nCells[cellLevel[celli]]++;
         }
 
-        Pstream::listCombineGather(nCells, plusEqOp<label>());
+        Pstream::listGather(nCells, sumOp<label>());
 
         /// Pstream::broadcast(nCells);
         if (Pstream::master())
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementBaffles.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementBaffles.C
index 3afa51b1e3741b43694666cd956d65a883a4ecae..2c92d2f05910370e8341348adc6cafca2b9a06eb 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementBaffles.C
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementBaffles.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2014 OpenFOAM Foundation
-    Copyright (C) 2015-2024 OpenCFD Ltd.
+    Copyright (C) 2015-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -867,7 +867,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::createZoneBaffles
 
         if (nTotalBaffles > 0)
         {
-            Pstream::listCombineReduce(nBaffles, plusEqOp<label>());
+            Pstream::listReduce(nBaffles, sumOp<label>());
 
             Info<< nl
                 << setf(ios_base::left)
@@ -2001,7 +2001,7 @@ void Foam::meshRefinement::findCellZoneTopo
     // - region numbers are identical on all processors
     // - keepRegion is identical ,,
     // - cellZones are identical ,,
-    Pstream::listCombineReduce(regionToCellZone, maxEqOp<label>());
+    Pstream::listReduce(regionToCellZone, maxOp<label>());
 
 
     // Find the region containing the keepPoint
@@ -2051,7 +2051,7 @@ void Foam::meshRefinement::findCellZoneTopo
         // - cellZones are identical ,,
         // This done at top of loop to account for geometric matching
         // not being synchronised.
-        Pstream::listCombineReduce(regionToCellZone, maxEqOp<label>());
+        Pstream::listReduce(regionToCellZone, maxOp<label>());
 
 
         bool changed = false;
diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C
index bdb55c6faf16afb367b58550a65a7741606c9d9c..6381b3733c698bb18ac097652c3886d7db959ec1 100644
--- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C
+++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2015 OpenFOAM Foundation
-    Copyright (C) 2015-2024 OpenCFD Ltd.
+    Copyright (C) 2015-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -3403,9 +3403,9 @@ void Foam::snappyRefineDriver::deleteSmallRegions
         nCellsPerRegion[regioni]++;
         nCellsPerZone[zonei]++;
     }
-    Pstream::listCombineReduce(nCellsPerRegion, plusEqOp<label>());
-    Pstream::listCombineReduce(regionToZone, maxEqOp<label>());
-    Pstream::listCombineReduce(nCellsPerZone, plusEqOp<label>());
+    Pstream::listReduce(nCellsPerRegion, sumOp<label>());
+    Pstream::listReduce(regionToZone, maxOp<label>());
+    Pstream::listReduce(nCellsPerZone, sumOp<label>());
 
 
     // Mark small regions. Note that all processors have the same information
diff --git a/src/meshTools/topoSet/faceZoneSources/planeToFaceZone/planeToFaceZone.C b/src/meshTools/topoSet/faceZoneSources/planeToFaceZone/planeToFaceZone.C
index 273cbfd8acc5bc6c9cda3fd71e77209440d5f7ad..e9132b3e5ae1beb325cdc23d1a84d7ccb9b8f31e 100644
--- a/src/meshTools/topoSet/faceZoneSources/planeToFaceZone/planeToFaceZone.C
+++ b/src/meshTools/topoSet/faceZoneSources/planeToFaceZone/planeToFaceZone.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2020 OpenFOAM Foundation
-    Copyright (C) 2020-2022 OpenCFD Ltd.
+    Copyright (C) 2020-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -258,7 +258,7 @@ void Foam::planeToFaceZone::combine(faceZoneSet& fzSet, const bool add) const
             {
                 ++ regionNFaces[regioni];
             }
-            Pstream::listCombineReduce(regionNFaces, plusEqOp<label>());
+            Pstream::listReduce(regionNFaces, sumOp<label>());
 
             Info<< "    Found " << nRegions << " contiguous regions with "
                 << regionNFaces << " faces" << endl;
@@ -281,8 +281,8 @@ void Foam::planeToFaceZone::combine(faceZoneSet& fzSet, const bool add) const
                 regionWeights[regioni] += w;
                 regionCentres[regioni] += w*c;
             }
-            Pstream::listCombineGather(regionWeights, plusEqOp<scalar>());
-            Pstream::listCombineGather(regionCentres, plusEqOp<point>());
+            Pstream::listGather(regionWeights, sumOp<scalar>());
+            Pstream::listGather(regionCentres, sumOp<point>());
 
             if (Pstream::master())
             {
diff --git a/src/optimisation/adjointOptimisation/adjoint/optimisation/updateMethod/MMA/MMA.C b/src/optimisation/adjointOptimisation/adjoint/optimisation/updateMethod/MMA/MMA.C
index 4c29943d2d3c7d9712714a7871ecbea187e81800..2777f8d42579e18a1366c630236596f2e7adbe3a 100644
--- a/src/optimisation/adjointOptimisation/adjoint/optimisation/updateMethod/MMA/MMA.C
+++ b/src/optimisation/adjointOptimisation/adjoint/optimisation/updateMethod/MMA/MMA.C
@@ -597,7 +597,7 @@ void Foam::MMA::computeNewtonDirection()
     if (globalSum_)
     {
         reduce(lhs, sumOp<scalarSquareMatrix>());
-        Pstream::listCombineAllGather(rhs, plusEqOp<scalar>());
+        Pstream::listReduce(rhs, sumOp<scalar>());
     }
 
     // Add remaining parts from deltaLamdaYTilda and the deltaZ eqn
diff --git a/src/optimisation/adjointOptimisation/adjoint/parameterization/NURBS/NURBS3DVolume/NURBS3DVolume/NURBS3DVolume.C b/src/optimisation/adjointOptimisation/adjoint/parameterization/NURBS/NURBS3DVolume/NURBS3DVolume/NURBS3DVolume.C
index e467948c4a63f46a6787106ec709e87da6861590..052396e975aacb98055ad7e4ade783207d3d96e2 100644
--- a/src/optimisation/adjointOptimisation/adjoint/parameterization/NURBS/NURBS3DVolume/NURBS3DVolume/NURBS3DVolume.C
+++ b/src/optimisation/adjointOptimisation/adjoint/parameterization/NURBS/NURBS3DVolume/NURBS3DVolume/NURBS3DVolume.C
@@ -1181,7 +1181,7 @@ Foam::vectorField Foam::NURBS3DVolume::computeControlPointSensitivities
     }
 
     // Sum contributions from all processors
-    Pstream::listCombineReduce(controlPointDerivs, plusEqOp<vector>());
+    Pstream::listReduce(controlPointDerivs, sumOp<vector>());
 
     return controlPointDerivs;
 }
@@ -1266,7 +1266,7 @@ Foam::vectorField Foam::NURBS3DVolume::computeControlPointSensitivities
         }
     }
     // Sum contributions from all processors
-    Pstream::listCombineReduce(controlPointDerivs, plusEqOp<vector>());
+    Pstream::listReduce(controlPointDerivs, sumOp<vector>());
 
     return controlPointDerivs;
 }
diff --git a/src/overset/cellCellStencil/cellVolumeWeight/cellVolumeWeightCellCellStencil.C b/src/overset/cellCellStencil/cellVolumeWeight/cellVolumeWeightCellCellStencil.C
index fd04966eff9905c5ee35652e41f1593012adc9d1..602d31b07523501704673f08e2961ce73cf5cf57 100644
--- a/src/overset/cellCellStencil/cellVolumeWeight/cellVolumeWeightCellCellStencil.C
+++ b/src/overset/cellCellStencil/cellVolumeWeight/cellVolumeWeightCellCellStencil.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2014-2023 OpenCFD Ltd.
+    Copyright (C) 2014-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -227,7 +227,7 @@ void Foam::cellCellStencils::cellVolumeWeight::findHoles
     {
         // Synchronise region status on processors
         // (could instead swap status through processor patches)
-        Pstream::listCombineReduce(regionType, maxEqOp<label>());
+        Pstream::listReduce(regionType, maxOp<label>());
 
         // Communicate region status through interpolative cells
         labelList cellRegionType(labelUIndList(regionType, cellRegion));
@@ -602,7 +602,7 @@ bool Foam::cellCellStencils::cellVolumeWeight::update()
     {
         nCellsPerZone[zoneID[cellI]]++;
     }
-    Pstream::listCombineReduce(nCellsPerZone, plusEqOp<label>());
+    Pstream::listReduce(nCellsPerZone, sumOp<label>());
 
     Info<< typeName << " : detected " << nZones
         << " mesh regions" << nl << endl;
diff --git a/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.C b/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.C
index f606f5bdd440b046afaa3ea44e462809e7e0db25..c09703ec5478dacba0ff170a5d955efa485f37f0 100644
--- a/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.C
+++ b/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2017-2023 OpenCFD Ltd.
+    Copyright (C) 2017-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -1107,7 +1107,7 @@ void Foam::cellCellStencils::inverseDistance::findHoles
     {
         // Synchronise region status on processors
         // (could instead swap status through processor patches)
-        Pstream::listCombineReduce(regionType, maxEqOp<label>());
+        Pstream::listReduce(regionType, maxOp<label>());
 
         DebugInfo<< FUNCTION_NAME << " : Gathered region type" << endl;
 
@@ -1801,7 +1801,7 @@ bool Foam::cellCellStencils::inverseDistance::update()
     {
         nCellsPerZone[zoneID[cellI]]++;
     }
-    Pstream::listCombineReduce(nCellsPerZone, plusEqOp<label>());
+    Pstream::listReduce(nCellsPerZone, sumOp<label>());
 
     const boundBox& allBb = mesh_.bounds();
 
diff --git a/src/overset/cellCellStencil/trackingInverseDistance/trackingInverseDistanceCellCellStencil.C b/src/overset/cellCellStencil/trackingInverseDistance/trackingInverseDistanceCellCellStencil.C
index 73d421c58f5d03578a4e1f5578b85adf1f65ae44..07f3c25436206b5cef9da23c030200f215a306a7 100644
--- a/src/overset/cellCellStencil/trackingInverseDistance/trackingInverseDistanceCellCellStencil.C
+++ b/src/overset/cellCellStencil/trackingInverseDistance/trackingInverseDistanceCellCellStencil.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2017-2023 OpenCFD Ltd.
+    Copyright (C) 2017-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -519,7 +519,7 @@ Foam::cellCellStencils::trackingInverseDistance::trackingInverseDistance
     {
         nCellsPerZone[zoneID[celli]]++;
     }
-    Pstream::listCombineReduce(nCellsPerZone, plusEqOp<label>());
+    Pstream::listReduce(nCellsPerZone, sumOp<label>());
 
     meshParts_.setSize(nZones);
     forAll(meshParts_, zonei)
diff --git a/src/overset/regionsToCell/findRefCells.C b/src/overset/regionsToCell/findRefCells.C
index 0704f355ba093f907750dbb1099314a6bf8f8d7e..fc5f942847b979a68802f19579ac437a4e51c8f0 100644
--- a/src/overset/regionsToCell/findRefCells.C
+++ b/src/overset/regionsToCell/findRefCells.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2016 OpenCFD Ltd.
+    Copyright (C) 2016,2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -188,7 +188,7 @@ void Foam::setRefCells
             }
         }
 
-        Pstream::listCombineReduce(hasRef, plusEqOp<label>());
+        Pstream::listReduce(hasRef, sumOp<label>());
 
         forAll(hasRef, regionI)
         {
diff --git a/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C b/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C
index b91df7c6d69ee78770603c95ae7ef8d540be51d5..f1fa4f415cb8192db1e1d9acfd88316d1b22d4ae 100644
--- a/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C
+++ b/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2017-2024 OpenCFD Ltd.
+    Copyright (C) 2017-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -420,8 +420,8 @@ void Foam::multiLevelDecomp::decompose
             );
 
             label nPoints = returnReduce(domainPoints.size(), sumOp<label>());
+            Pstream::listReduce(nOutsideConnections, sumOp<label>());
 
-            Pstream::listCombineReduce(nOutsideConnections, plusEqOp<label>());
             label nPatches = 0;
             label nFaces = 0;
             for (const label nConnect : nOutsideConnections)
@@ -528,11 +528,7 @@ void Foam::multiLevelDecomp::decompose
                 }
 
                 reduce(nPoints, sumOp<label>());
-                Pstream::listCombineReduce
-                (
-                    nOutsideConnections,
-                    plusEqOp<label>()
-                );
+                Pstream::listReduce(nOutsideConnections, sumOp<label>());
 
                 label nPatches = 0;
                 label nFaces = 0;
diff --git a/src/regionModels/regionModel/singleLayerRegion/singleLayerRegion.C b/src/regionModels/regionModel/singleLayerRegion/singleLayerRegion.C
index 94f659840043eccb87125cc83866e4528807e5d9..207d1c0a486ce4c3ed3b7476ddd0a6e067dd11e0 100644
--- a/src/regionModels/regionModel/singleLayerRegion/singleLayerRegion.C
+++ b/src/regionModels/regionModel/singleLayerRegion/singleLayerRegion.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2020 OpenCFD Ltd.
+    Copyright (C) 2020-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -144,7 +144,7 @@ void Foam::regionModels::singleLayerRegion::initialise()
         }
     }
 
-    Pstream::listCombineReduce(passivePatchIDs_, maxEqOp<label>());
+    Pstream::listReduce(passivePatchIDs_, maxOp<label>());
 
     magSf.field() = 0.5*(magSf + passiveMagSf);
     magSf.correctBoundaryConditions();
diff --git a/src/sampling/sampledSet/cloud/cloudSet.C b/src/sampling/sampledSet/cloud/cloudSet.C
index 42045d473ce83c5fbf58c4eea4ab914407c21748..3447facc9b8ae662246223d60d971ba1b54f0d2f 100644
--- a/src/sampling/sampledSet/cloud/cloudSet.C
+++ b/src/sampling/sampledSet/cloud/cloudSet.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2016 OpenCFD Ltd.
+    Copyright (C) 2016-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -84,8 +84,8 @@ void Foam::cloudSet::calcSamples
             minFoundProc[i] = foundProc[i];
         }
     }
-    Pstream::listCombineReduce(minFoundProc, minEqOp<label>());
-    Pstream::listCombineReduce(maxFoundProc, maxEqOp<label>());
+    Pstream::listReduce(minFoundProc, minOp<label>());
+    Pstream::listReduce(maxFoundProc, maxOp<label>());
 
 
     DynamicField<point> missingPoints(sampleCoords_.size());
diff --git a/src/sampling/surface/distanceSurface/distanceSurfaceFilter.C b/src/sampling/surface/distanceSurface/distanceSurfaceFilter.C
index 58d3892748a161150d5688f935812ec07932b034..739a802f4eea684d653be62997343d96fd0ce63c 100644
--- a/src/sampling/surface/distanceSurface/distanceSurfaceFilter.C
+++ b/src/sampling/surface/distanceSurface/distanceSurfaceFilter.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2020-2022 OpenCFD Ltd.
+    Copyright (C) 2020-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -142,8 +142,8 @@ void Foam::distanceSurface::filterKeepLargestRegion
         }
     }
 
-    // Sum totals from all processors
-    Pstream::listCombineGather(nCutsPerRegion, plusEqOp<label>());
+    // Sum totals from all processors (onto the master)
+    Pstream::listGather(nCutsPerRegion, sumOp<label>());
 
 
     // Define which regions to keep
@@ -242,8 +242,8 @@ void Foam::distanceSurface::filterKeepNearestRegions
         }
     }
 
-    // Sum totals from all processors
-    Pstream::listCombineGather(nCutsPerRegion, plusEqOp<label>());
+    // Sum totals from all processors (onto the master)
+    Pstream::listGather(nCutsPerRegion, sumOp<label>());
 
     // Get nearest
     Pstream::listCombineGather(nearest, minFirstEqOp<scalar>());
@@ -355,8 +355,8 @@ void Foam::distanceSurface::filterRegionProximity
         areaRegion[regioni] += (faceArea);
     }
 
-    Pstream::listCombineGather(distRegion, plusEqOp<scalar>());
-    Pstream::listCombineGather(areaRegion, plusEqOp<scalar>());
+    Pstream::listGather(distRegion, sumOp<scalar>());
+    Pstream::listGather(areaRegion, sumOp<scalar>());
 
     if (Pstream::master())
     {
diff --git a/src/sampling/surface/isoSurface/isoSurfacePoint.C b/src/sampling/surface/isoSurface/isoSurfacePoint.C
index 020a0465a2b266ffb00dc90a59f97238d7947646..b450c9b0f51405c4042afb7bb3391d60cffc2d4e 100644
--- a/src/sampling/surface/isoSurface/isoSurfacePoint.C
+++ b/src/sampling/surface/isoSurface/isoSurfacePoint.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2015-2024 OpenCFD Ltd.
+    Copyright (C) 2015-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -256,7 +256,7 @@ void Foam::isoSurfacePoint::syncUnseparatedPoints
         }
 
         // Globally consistent
-        Pstream::listCombineReduce(sharedPts, minEqOp<point>());
+        Pstream::listReduce(sharedPts, minOp<point>());
 
         // Now we will all have the same information. Merge it back with
         // my local information.
diff --git a/src/thermophysicalModels/radiation/radiationModels/solarLoad/faceReflecting/faceReflecting.C b/src/thermophysicalModels/radiation/radiationModels/solarLoad/faceReflecting/faceReflecting.C
index 32fa503e548ca5469a3caa62b63391b94d846513..53236148ec1ef28d3bea2816a88dacedf0d5614a 100644
--- a/src/thermophysicalModels/radiation/radiationModels/solarLoad/faceReflecting/faceReflecting.C
+++ b/src/thermophysicalModels/radiation/radiationModels/solarLoad/faceReflecting/faceReflecting.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018-2022 OpenCFD Ltd.
+    Copyright (C) 2018-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -327,7 +327,7 @@ void Foam::faceReflecting::calculate()
     // Distribute ray indexes to all proc's
     // Make sure all the processors have the same information
 
-    Pstream::listCombineReduce(refDisDirsIndex, maxEqOp<label>());
+    Pstream::listReduce(refDisDirsIndex, maxOp<label>());
     Pstream::mapCombineReduce(refFacesDirIndex, minEqOp<label>());
 
     const scalar maxBounding =
diff --git a/src/thermophysicalModels/radiation/radiationModels/viewFactor/viewFactor.C b/src/thermophysicalModels/radiation/radiationModels/viewFactor/viewFactor.C
index d434b37a90ffe0efa8dc17d8aaacd1b625a4c598..79267e4c80cbb58f95b0364df79a38b0c91521d5 100644
--- a/src/thermophysicalModels/radiation/radiationModels/viewFactor/viewFactor.C
+++ b/src/thermophysicalModels/radiation/radiationModels/viewFactor/viewFactor.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2016-2022 OpenCFD Ltd.
+    Copyright (C) 2016-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -969,9 +969,9 @@ void Foam::radiation::viewFactor::calculate()
                 qrExt[compactGlobalIds[i]] = compactCoarseHo[i];
             }
 
-            Pstream::listCombineReduce(T4, maxEqOp<scalar>());
-            Pstream::listCombineReduce(E, maxEqOp<scalar>());
-            Pstream::listCombineReduce(qrExt, maxEqOp<scalar>());
+            Pstream::listReduce(T4, maxOp<scalar>());
+            Pstream::listReduce(E, maxOp<scalar>());
+            Pstream::listReduce(qrExt, maxOp<scalar>());
 
             if (Pstream::master())
             {