diff --git a/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.H b/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.H index eab7f25e9d..4aeee50e46 100644 --- a/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.H +++ b/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.H @@ -138,14 +138,7 @@ public: //- Return true if running parallel virtual bool coupled() const { - if (Pstream::parRun()) - { - return true; - } - else - { - return false; - } + return Pstream::parRun(); } //- Does the patch field perform the transformation diff --git a/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.H b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.H index 6e15443d96..fc63899af6 100644 --- a/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.H +++ b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.H @@ -142,14 +142,7 @@ public: //- Return true if running parallel virtual bool coupled() const { - if (Pstream::parRun()) - { - return true; - } - else - { - return false; - } + return Pstream::parRun(); } //- Does the patch field perform the transformation diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C index 507c223107..f328814447 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C +++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C @@ -959,8 +959,8 @@ bool Foam::polyBoundaryMesh::checkParallelSync(const bool report) const bool hasError = false; // Collect non-proc patches and check proc patches are last. - wordList names(bm.size()); - wordList types(bm.size()); + wordList localNames(bm.size()); + wordList localTypes(bm.size()); label nonProci = 0; @@ -970,65 +970,67 @@ bool Foam::polyBoundaryMesh::checkParallelSync(const bool report) const { if (nonProci != patchi) { - // There is processor patch in between normal patches. + // A processor patch in between normal patches! hasError = true; if (debug || report) { Pout<< " ***Problem with boundary patch " << patchi - << " named " << bm[patchi].name() - << " of type " << bm[patchi].type() - << ". The patch seems to be preceeded by processor" - << " patches. This is can give problems." - << endl; + << " name:" << bm[patchi].name() + << " type:" << bm[patchi].type() + << " - seems to be preceeded by processor patches." + << " This is usually a problem." << endl; } } else { - names[nonProci] = bm[patchi].name(); - types[nonProci] = bm[patchi].type(); - nonProci++; + localNames[nonProci] = bm[patchi].name(); + localTypes[nonProci] = bm[patchi].type(); + ++nonProci; } } } - names.setSize(nonProci); - types.setSize(nonProci); + localNames.resize(nonProci); + localTypes.resize(nonProci); - List allNames(Pstream::nProcs()); - allNames[Pstream::myProcNo()] = names; - Pstream::allGatherList(allNames); + // Check and report error(s) on master - List allTypes(Pstream::nProcs()); - allTypes[Pstream::myProcNo()] = types; - Pstream::allGatherList(allTypes); + const globalIndex procAddr + ( + // Don't need to collect master itself + (Pstream::master() ? 0 : nonProci), + globalIndex::gatherOnly{} + ); - // Have every processor check but print error on master - // (in processor sequence). + const wordList allNames(procAddr.gather(localNames)); + const wordList allTypes(procAddr.gather(localTypes)); - for (const int proci : Pstream::subProcs()) + // Automatically restricted to master + for (const int proci : procAddr.subProcs()) { - if - ( - (allNames[proci] != allNames.first()) - || (allTypes[proci] != allTypes.first()) - ) + const auto procNames(allNames.slice(procAddr.range(proci))); + const auto procTypes(allTypes.slice(procAddr.range(proci))); + + if (procNames != localNames || procTypes != localTypes) { hasError = true; - if (debug || (report && Pstream::master())) + if (debug || report) { Info<< " ***Inconsistent patches across processors, " - "processor 0 has patch names:" - << allNames.first() - << " patch types:" << allTypes.first() - << " processor " << proci - << " has patch names:" << allNames[proci] - << " patch types:" << allTypes[proci] + "processor0 has patch names:" << localNames + << " patch types:" << localTypes + << " processor" << proci + << " has patch names:" << procNames + << " patch types:" << procTypes << endl; } } } + // Reduce (not broadcast) to respect local out-of-order errors (first loop) + reduce(hasError, orOp()); + return hasError; } diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H index 1ba87a5362..765b89bed3 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H +++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H @@ -274,11 +274,12 @@ public: labelHashSet& nonGroupPatches ) const; - //- Check whether all procs have all patches and in same order. Return - // true if in error. + //- Check whether all procs have all patches and in same order. + // \return True if in error. bool checkParallelSync(const bool report = false) const; - //- Check boundary definition. Return true if in error. + //- Check boundary definition. + // \return True if in error. bool checkDefinition(const bool report = false) const; //- Correct polyBoundaryMesh after moving points diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H index 726e41b35b..aa8cce2933 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H +++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H @@ -255,14 +255,7 @@ public: //- Return true only if this is a parallel run virtual bool coupled() const { - if (Pstream::parRun()) - { - return true; - } - else - { - return false; - } + return Pstream::parRun(); } //- Return processor number diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C index ccef0ba495..8c1e0cd003 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C +++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C @@ -31,6 +31,7 @@ License #include "DynamicList.H" #include "Pstream.H" #include "PtrListOps.H" +#include "globalIndex.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -760,41 +761,47 @@ bool Foam::ZoneMesh::checkParallelSync bool hasError = false; - // Collect all names - List allNames(Pstream::nProcs()); - allNames[Pstream::myProcNo()] = this->names(); - Pstream::allGatherList(allNames); + const wordList localNames(this->names()); + const wordList localTypes(this->types()); - List allTypes(Pstream::nProcs()); - allTypes[Pstream::myProcNo()] = this->types(); - Pstream::allGatherList(allTypes); + // Check and report error(s) on master - // Have every processor check but only master print error. + const globalIndex procAddr + ( + // Don't need to collect master itself + (Pstream::master() ? 0 : localNames.size()), + globalIndex::gatherOnly{} + ); - for (label proci = 1; proci < allNames.size(); ++proci) + const wordList allNames(procAddr.gather(localNames)); + const wordList allTypes(procAddr.gather(localTypes)); + + // Automatically restricted to master + for (const int proci : procAddr.subProcs()) { - if - ( - (allNames[proci] != allNames[0]) - || (allTypes[proci] != allTypes[0]) - ) + const auto procNames(allNames.slice(procAddr.range(proci))); + const auto procTypes(allTypes.slice(procAddr.range(proci))); + + if (procNames != localNames || procTypes != localTypes) { hasError = true; - if (debug || (report && Pstream::master())) + if (debug || report) { Info<< " ***Inconsistent zones across processors, " - "processor 0 has zone names:" << allNames[0] - << " zone types:" << allTypes[0] - << " processor " << proci << " has zone names:" - << allNames[proci] - << " zone types:" << allTypes[proci] + "processor 0 has zone names:" << localNames + << " zone types:" << localTypes + << " processor " << proci + << " has zone names:" << procNames + << " zone types:" << procTypes << endl; } } } - // Check contents + Pstream::broadcast(hasError); + + // Check local contents if (!hasError) { for (const ZoneType& zn : zones) diff --git a/src/dynamicMesh/fvMeshDistribute/fvMeshDistributeTemplates.C b/src/dynamicMesh/fvMeshDistribute/fvMeshDistributeTemplates.C index 38958bda5d..faaf42a9fc 100644 --- a/src/dynamicMesh/fvMeshDistribute/fvMeshDistributeTemplates.C +++ b/src/dynamicMesh/fvMeshDistribute/fvMeshDistributeTemplates.C @@ -395,25 +395,35 @@ void Foam::fvMeshDistribute::getFieldNames // Check all procs have same names - if (syncPar) + if (syncPar && Pstream::parRun()) { - List allNames(Pstream::nProcs()); - allNames[Pstream::myProcNo()] = list; - Pstream::allGatherList(allNames); + // Check and report error(s) on master - for (const int proci : Pstream::subProcs()) + const globalIndex procAddr + ( + // Don't need to collect master itself + (Pstream::master() ? 0 : list.size()), + globalIndex::gatherOnly{} + ); + + const wordList allNames(procAddr.gather(list)); + + // Automatically restricted to master + for (const int proci : procAddr.subProcs()) { - if (allNames[proci] != allNames[0]) + const auto procNames(allNames.slice(procAddr.range(proci))); + + if (procNames != list) { FatalErrorInFunction - << "When checking for equal " - << GeoField::typeName + << "When checking for equal " << GeoField::typeName << " :" << nl - << "processor0 has:" << allNames[0] << endl - << "processor" << proci << " has:" << allNames[proci] << nl + << "processor0 has:" << list << nl + << "processor" << proci << " has:" << procNames << nl << GeoField::typeName << " need to be synchronised on all processors." << exit(FatalError); + break; } } } diff --git a/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.C b/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.C index ac28ba3822..5e3af56280 100644 --- a/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.C +++ b/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.C @@ -28,7 +28,9 @@ License #include "faBoundaryMesh.H" #include "faMesh.H" +#include "globalIndex.H" #include "primitiveMesh.H" +#include "processorFaPatch.H" #include "PtrListOps.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -625,6 +627,94 @@ Foam::label Foam::faBoundaryMesh::whichPatch(const label edgeIndex) const } +bool Foam::faBoundaryMesh::checkParallelSync(const bool report) const +{ + if (!Pstream::parRun()) + { + return false; + } + + const faBoundaryMesh& bm = *this; + + bool hasError = false; + + // Collect non-proc patches and check proc patches are last. + wordList localNames(bm.size()); + wordList localTypes(bm.size()); + + label nonProci = 0; + + forAll(bm, patchi) + { + if (!isA(bm[patchi])) + { + if (nonProci != patchi) + { + // A processor patch in between normal patches! + hasError = true; + + if (debug || report) + { + Pout<< " ***Problem with boundary patch " << patchi + << " name:" << bm[patchi].name() + << " type:" << bm[patchi].type() + << " - seems to be preceeded by processor patches." + << " This is usually a problem." << endl; + } + } + else + { + localNames[nonProci] = bm[patchi].name(); + localTypes[nonProci] = bm[patchi].type(); + ++nonProci; + } + } + } + localNames.resize(nonProci); + localTypes.resize(nonProci); + + // Check and report error(s) on master + + const globalIndex procAddr + ( + // Don't need to collect master itself + (Pstream::master() ? 0 : nonProci), + globalIndex::gatherOnly{} + ); + + const wordList allNames(procAddr.gather(localNames)); + const wordList allTypes(procAddr.gather(localTypes)); + + // Automatically restricted to master + for (const int proci : procAddr.subProcs()) + { + const auto procNames(allNames.slice(procAddr.range(proci))); + const auto procTypes(allTypes.slice(procAddr.range(proci))); + + if (procNames != localNames || procTypes != localTypes) + { + hasError = true; + + if (debug || report) + { + Info<< " ***Inconsistent patches across processors, " + "processor0 has patch names:" << localNames + << " patch types:" << localTypes + << " processor" << proci + << " has patch names:" << procNames + << " patch types:" << procTypes + << endl; + } + } + } + + // Reduce (not broadcast) to respect local out-of-order errors (first loop) + reduce(hasError, orOp()); + + return hasError; +} + + bool Foam::faBoundaryMesh::checkDefinition(const bool report) const { label nextPatchStart = mesh().nInternalEdges(); diff --git a/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.H b/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.H index c6ecd2ba39..1f17979b57 100644 --- a/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.H +++ b/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.H @@ -210,8 +210,13 @@ public: void setGroup(const word& groupName, const labelUList& patchIDs); //- Check boundary definition + // \return True if in error. bool checkDefinition(const bool report = false) const; + //- Check whether all procs have all patches and in same order. + // \return True if in error. + bool checkParallelSync(const bool report = false) const; + // Edit diff --git a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H index dcd279dabf..10d01e42a1 100644 --- a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H +++ b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H @@ -151,14 +151,7 @@ public: //- Return true if running parallel virtual bool coupled() const { - if (Pstream::parRun()) - { - return true; - } - else - { - return false; - } + return Pstream::parRun(); } //- Return neighbour field given internal field diff --git a/src/finiteArea/fields/faePatchFields/constraint/processor/processorFaePatchField.H b/src/finiteArea/fields/faePatchFields/constraint/processor/processorFaePatchField.H index 017eabd5a1..3b6c5f8585 100644 --- a/src/finiteArea/fields/faePatchFields/constraint/processor/processorFaePatchField.H +++ b/src/finiteArea/fields/faePatchFields/constraint/processor/processorFaePatchField.H @@ -139,22 +139,13 @@ public: virtual ~processorFaePatchField(); - // Member functions + // Member Functions - // Access - - //- Return true if running parallel - virtual bool coupled() const - { - if (Pstream::parRun()) - { - return true; - } - else - { - return false; - } - } + //- Return true if running parallel + virtual bool coupled() const + { + return Pstream::parRun(); + } }; diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H index cb71010001..029683e8bb 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H @@ -171,21 +171,14 @@ public: ~processorFvPatchField() = default; - // Member functions + // Member Functions // Access //- Return true if running parallel virtual bool coupled() const { - if (Pstream::parRun()) - { - return true; - } - else - { - return false; - } + return Pstream::parRun(); } //- Return neighbour field given internal field diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/processor/processorFvsPatchField.H b/src/finiteVolume/fields/fvsPatchFields/constraint/processor/processorFvsPatchField.H index a38e08868d..481d1aac6a 100644 --- a/src/finiteVolume/fields/fvsPatchFields/constraint/processor/processorFvsPatchField.H +++ b/src/finiteVolume/fields/fvsPatchFields/constraint/processor/processorFvsPatchField.H @@ -136,22 +136,13 @@ public: virtual ~processorFvsPatchField(); - // Member functions + // Member Functions - // Access - - //- Return true if running parallel - virtual bool coupled() const - { - if (Pstream::parRun()) - { - return true; - } - else - { - return false; - } - } + //- Return true if running parallel + virtual bool coupled() const + { + return Pstream::parRun(); + } }; diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.H b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.H index 6c29f5f2bb..59c762dfb1 100644 --- a/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.H +++ b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.H @@ -137,22 +137,13 @@ public: virtual ~processorCyclicFvsPatchField(); - // Member functions + // Member Functions - // Access - - //- Return true if running parallel - virtual bool coupled() const - { - if (Pstream::parRun()) - { - return true; - } - else - { - return false; - } - } + //- Return true if running parallel + virtual bool coupled() const + { + return Pstream::parRun(); + } };