mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add parallel sync checks for finite-area
- reduce the amount of communication when checking zones and patches by performing the synchonization check on the gathered strings (master only) and reduce or broadcast the result. STYLE: simplify coupled() checks depending only on parRun
This commit is contained in:
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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<wordList> allNames(Pstream::nProcs());
|
||||
allNames[Pstream::myProcNo()] = names;
|
||||
Pstream::allGatherList(allNames);
|
||||
// Check and report error(s) on master
|
||||
|
||||
List<wordList> 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<bool>());
|
||||
|
||||
return hasError;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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<ZoneType, MeshType>::checkParallelSync
|
||||
|
||||
bool hasError = false;
|
||||
|
||||
// Collect all names
|
||||
List<wordList> allNames(Pstream::nProcs());
|
||||
allNames[Pstream::myProcNo()] = this->names();
|
||||
Pstream::allGatherList(allNames);
|
||||
const wordList localNames(this->names());
|
||||
const wordList localTypes(this->types());
|
||||
|
||||
List<wordList> 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)
|
||||
|
||||
@ -395,25 +395,35 @@ void Foam::fvMeshDistribute::getFieldNames
|
||||
|
||||
|
||||
// Check all procs have same names
|
||||
if (syncPar)
|
||||
if (syncPar && Pstream::parRun())
|
||||
{
|
||||
List<wordList> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<processorFaPatch>(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<bool>());
|
||||
|
||||
return hasError;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::faBoundaryMesh::checkDefinition(const bool report) const
|
||||
{
|
||||
label nextPatchStart = mesh().nInternalEdges();
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user