Commit d27d69e3 authored by Henry Weller's avatar Henry Weller Committed by mattijs
Browse files

reconstructParMesh: Use tree method to improve speed and scaling

Based on development contributed by Paul Edwards, Intel.

Conflicts:
	applications/utilities/parallelProcessing/reconstructParMesh/reconstructParMesh.C
parent 24d1e50f
......@@ -87,8 +87,11 @@ static void renumber
autoPtr<faceCoupleInfo> determineCoupledFaces
(
const bool fullMatch,
const label proci,
const label masterMeshProcStart,
const label masterMeshProcEnd,
const polyMesh& masterMesh,
const label meshToAddProcStart,
const label meshToAddProcEnd,
const polyMesh& meshToAdd,
const scalar mergeDist
)
......@@ -113,7 +116,6 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
const polyBoundaryMesh& masterPatches = masterMesh.boundaryMesh();
const string toProcString("to" + name(proci));
DynamicList<label> masterFaces
(
......@@ -121,24 +123,35 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
- masterMesh.nInternalFaces()
);
forAll(masterPatches, patchi)
{
const polyPatch& pp = masterPatches[patchi];
if
(
isA<processorPolyPatch>(pp)
&& (
pp.name().rfind(toProcString)
== (pp.name().size()-toProcString.size())
)
)
if (isA<processorPolyPatch>(pp))
{
label meshFacei = pp.start();
forAll(pp, i)
for
(
label proci=meshToAddProcStart;
proci<meshToAddProcEnd;
proci++
)
{
masterFaces.append(meshFacei++);
const string toProcString("to" + name(proci));
if (
pp.name().rfind(toProcString)
== (pp.name().size()-toProcString.size())
)
{
label meshFacei = pp.start();
forAll(pp, i)
{
masterFaces.append(meshFacei++);
}
break;
}
}
}
}
masterFaces.shrink();
......@@ -163,17 +176,30 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
{
bool isConnected = false;
for (label mergedProci = 0; mergedProci < proci; mergedProci++)
for
(
label mergedProci=masterMeshProcStart;
!isConnected && (mergedProci < masterMeshProcEnd);
mergedProci++
)
{
const word fromProcString
for
(
processorPolyPatch::newName(proci, mergedProci)
);
if (pp.name() == fromProcString)
label proci = meshToAddProcStart;
proci < meshToAddProcEnd;
proci++
)
{
isConnected = true;
break;
const word fromProcString
(
processorPolyPatch::newName(proci, mergedProci)
);
if (pp.name() == fromProcString)
{
isConnected = true;
break;
}
}
}
......@@ -623,27 +649,28 @@ int main(int argc, char *argv[])
{
// Construct empty mesh.
Info<< "Constructing empty mesh to add to." << nl << endl;
fvMesh masterMesh
(
IOobject
(
regionName,
runTime.timeName(),
runTime,
IOobject::NO_READ
),
xferCopy(pointField()),
xferCopy(faceList()),
xferCopy(cellList())
);
// fvMesh** masterMesh = new fvMesh*[nProcs];
PtrList<fvMesh> masterMesh(nProcs);
for (label proci = 0; proci < nProcs; proci++)
for (label proci=0; proci<nProcs; proci++)
{
Info<< "Reading mesh to add from "
<< databases[proci].caseName()
<< " for time = " << databases[proci].timeName()
<< nl << endl;
masterMesh.set
(
proci,
new fvMesh
(
IOobject
(
regionName,
runTime.timeName(),
runTime,
IOobject::NO_READ
),
xferCopy(pointField()),
xferCopy(faceList()),
xferCopy(cellList())
)
);
fvMesh meshToAdd
(
......@@ -662,78 +689,169 @@ int main(int argc, char *argv[])
boundaryProcAddressing[proci] =
identity(meshToAdd.boundaryMesh().size());
// Find geometrically shared points/faces.
autoPtr<faceCoupleInfo> couples = determineCoupledFaces
(
fullMatch,
proci,
masterMesh,
proci,
masterMesh[proci],
proci,
proci,
meshToAdd,
mergeDist
);
// Add elements to mesh
Info<< "Adding to master mesh" << nl << endl;
autoPtr<mapAddedPolyMesh> map = fvMeshAdder::add
(
masterMesh,
masterMesh[proci],
meshToAdd,
couples
);
// Update all addressing so xxProcAddressing points to correct
// item in masterMesh.
// Processors that were already in masterMesh
for (label mergedI = 0; mergedI < proci; mergedI++)
{
renumber(map().oldCellMap(), cellProcAddressing[mergedI]);
renumber(map().oldFaceMap(), faceProcAddressing[mergedI]);
renumber(map().oldPointMap(), pointProcAddressing[mergedI]);
// Note: boundary is special since can contain -1.
renumber
(
map().oldPatchMap(),
boundaryProcAddressing[mergedI]
);
}
// Added processor
renumber(map().addedCellMap(), cellProcAddressing[proci]);
renumber(map().addedFaceMap(), faceProcAddressing[proci]);
renumber(map().addedPointMap(), pointProcAddressing[proci]);
renumber(map().addedPatchMap(), boundaryProcAddressing[proci]);
}
for (label step=2; step<nProcs*2; step*=2)
{
for (label proci=0; proci<nProcs; proci+=step)
{
label next = proci + step/2;
if(next >= nProcs)
{
continue;
}
Info<< "Merging mesh " << proci << " with " << next << endl;
// Find geometrically shared points/faces.
autoPtr<faceCoupleInfo> couples = determineCoupledFaces
(
fullMatch,
proci,
next,
masterMesh[proci],
next,
proci+step,
masterMesh[next],
mergeDist
);
// Add elements to mesh
autoPtr<mapAddedPolyMesh> map = fvMeshAdder::add
(
masterMesh[proci],
masterMesh[next],
couples
);
Info<< endl;
// Processors that were already in masterMesh
for (label mergedI=proci; mergedI<next; mergedI++)
{
renumber
(
map().oldCellMap(),
cellProcAddressing[mergedI]
);
renumber
(
map().oldFaceMap(),
faceProcAddressing[mergedI]
);
renumber
(
map().oldPointMap(),
pointProcAddressing[mergedI]
);
// Note: boundary is special since can contain -1.
renumber
(
map().oldPatchMap(),
boundaryProcAddressing[mergedI]
);
}
// Added processor
for
(
label addedI=next;
addedI<min(proci+step, nProcs);
addedI++
)
{
renumber
(
map().addedCellMap(),
cellProcAddressing[addedI]
);
renumber
(
map().addedFaceMap(),
faceProcAddressing[addedI]
);
renumber
(
map().addedPointMap(),
pointProcAddressing[addedI]
);
renumber
(
map().addedPatchMap(),
boundaryProcAddressing[addedI]
);
}
masterMesh.set(next, nullptr);
}
}
for (label proci=0; proci<nProcs; proci++)
{
Info<< "Reading mesh to add from "
<< databases[proci].caseName()
<< " for time = " << databases[proci].timeName()
<< nl << nl << endl;
}
// See if any points on the mastermesh have become connected
// because of connections through processor meshes.
mergeSharedPoints(mergeDist, masterMesh, pointProcAddressing);
mergeSharedPoints(mergeDist, masterMesh[0], pointProcAddressing);
// Save some properties on the reconstructed mesh
masterInternalFaces = masterMesh.nInternalFaces();
masterOwner = masterMesh.faceOwner();
masterInternalFaces = masterMesh[0].nInternalFaces();
masterOwner = masterMesh[0].faceOwner();
Info<< "\nWriting merged mesh to "
<< runTime.path()/runTime.timeName()
<< nl << endl;
if (!masterMesh.write())
if (!masterMesh[0].write())
{
FatalErrorInFunction
<< "Failed writing polyMesh."
<< exit(FatalError);
}
topoSet::removeFiles(masterMesh);
topoSet::removeFiles(masterMesh[0]);
if (writeCellDist)
{
writeCellDistance(runTime, masterMesh, cellProcAddressing);
writeCellDistance
(
runTime,
masterMesh[0],
cellProcAddressing
);
}
}
......@@ -810,7 +928,7 @@ int main(int argc, char *argv[])
// See reconstructPar for meaning of turning index.
forAll(faceProcAddr, procFacei)
{
label masterFacei = faceProcAddr[procFacei];
const label masterFacei = faceProcAddr[procFacei];
if
(
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment