ENH: fvMeshDistribute: uses topological rather than geometric point merging

Patch contributed by Mattijs Janssens
This commit is contained in:
Henry Weller
2018-03-23 17:02:18 +00:00
committed by Andrew Heather
parent 83d935d517
commit 7ac5d76773
2 changed files with 200 additions and 41 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015-2018 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2015-2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -42,6 +42,7 @@ License
#include "fvMeshTools.H" #include "fvMeshTools.H"
#include "labelPairHashes.H" #include "labelPairHashes.H"
#include "ListOps.H" #include "ListOps.H"
#include "globalIndex.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -688,25 +689,54 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::repatch
// merge those points. // merge those points.
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
( (
const labelList& pointToGlobalMaster,
labelListList& constructPointMap labelListList& constructPointMap
) )
{ {
// Find out which sets of points get merged and create a map from // Find out which sets of points get merged and create a map from
// mesh point to unique point. // mesh point to unique point.
Map<label> pointToMaster
( label nShared = 0;
fvMeshAdder::findSharedPoints forAll(pointToGlobalMaster, pointi)
( {
mesh_, if (pointToGlobalMaster[pointi] != -1)
mergeTol_ {
) nShared++;
); }
}
Map<label> globalMasterToLocalMaster(2*nShared);
Map<label> pointToMaster(2*nShared);
forAll(pointToGlobalMaster, pointi)
{
label globali = pointToGlobalMaster[pointi];
if (globali != -1)
{
Map<label>::const_iterator iter = globalMasterToLocalMaster.find
(
globali
);
if (iter == globalMasterToLocalMaster.end())
{
// Found first point. Designate as master
globalMasterToLocalMaster.insert(globali, pointi);
pointToMaster.insert(pointi, pointi);
}
else
{
pointToMaster.insert(pointi, iter());
}
}
}
if (returnReduce(pointToMaster.size(), sumOp<label>()) == 0) if (returnReduce(pointToMaster.size(), sumOp<label>()) == 0)
{ {
return nullptr; return nullptr;
} }
polyTopoChange meshMod(mesh_); polyTopoChange meshMod(mesh_);
fvMeshAdder::mergePoints(mesh_, pointToMaster, meshMod); fvMeshAdder::mergePoints(mesh_, pointToMaster, meshMod);
@ -750,16 +780,19 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
} }
// Construct the local environment of all boundary faces. void Foam::fvMeshDistribute::getCouplingData
void Foam::fvMeshDistribute::getNeighbourData
( (
const labelList& distribution, const labelList& distribution,
labelList& sourceFace, labelList& sourceFace,
labelList& sourceProc, labelList& sourceProc,
labelList& sourcePatch, labelList& sourcePatch,
labelList& sourceNewNbrProc labelList& sourceNewNbrProc,
labelList& sourcePointMaster
) const ) const
{ {
// Construct the coupling information for all (boundary) faces and
// points
label nBnd = mesh_.nFaces() - mesh_.nInternalFaces(); label nBnd = mesh_.nFaces() - mesh_.nInternalFaces();
sourceFace.setSize(nBnd); sourceFace.setSize(nBnd);
sourceProc.setSize(nBnd); sourceProc.setSize(nBnd);
@ -890,13 +923,62 @@ void Foam::fvMeshDistribute::getNeighbourData
} }
} }
} }
// Collect coupled (collocated) points
sourcePointMaster.setSize(mesh_.nPoints());
sourcePointMaster = -1;
{
// Assign global master point
const globalIndex globalPoints(mesh_.nPoints());
const globalMeshData& gmd = mesh_.globalData();
const indirectPrimitivePatch& cpp = gmd.coupledPatch();
const labelList& meshPoints = cpp.meshPoints();
const mapDistribute& slavesMap = gmd.globalCoPointSlavesMap();
const labelListList& slaves = gmd.globalCoPointSlaves();
labelList elems(slavesMap.constructSize(), -1);
forAll(meshPoints, pointi)
{
const labelList& slots = slaves[pointi];
if (slots.size())
{
// pointi is a master. Assign a unique label.
label globalPointi = globalPoints.toGlobal(meshPoints[pointi]);
elems[pointi] = globalPointi;
forAll(slots, i)
{
label sloti = slots[i];
if (sloti >= meshPoints.size())
{
// Filter out local collocated points. We don't want
// to merge these
elems[slots[i]] = globalPointi;
}
}
}
}
// Push slave-slot data back to slaves
slavesMap.reverseDistribute(elems.size(), elems, false);
// Extract back onto mesh
forAll(meshPoints, pointi)
{
sourcePointMaster[meshPoints[pointi]] = elems[pointi];
}
}
} }
// Subset the neighbourCell/neighbourProc fields // Subset the neighbourCell/neighbourProc fields
void Foam::fvMeshDistribute::subsetBoundaryData void Foam::fvMeshDistribute::subsetCouplingData
( (
const fvMesh& mesh, const fvMesh& mesh,
const labelList& pointMap,
const labelList& faceMap, const labelList& faceMap,
const labelList& cellMap, const labelList& cellMap,
@ -909,11 +991,13 @@ void Foam::fvMeshDistribute::subsetBoundaryData
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourcePatch, const labelList& sourcePatch,
const labelList& sourceNewNbrProc, const labelList& sourceNewNbrProc,
const labelList& sourcePointMaster,
labelList& subFace, labelList& subFace,
labelList& subProc, labelList& subProc,
labelList& subPatch, labelList& subPatch,
labelList& subNewNbrProc labelList& subNewNbrProc,
labelList& subPointMaster
) )
{ {
subFace.setSize(mesh.nFaces() - mesh.nInternalFaces()); subFace.setSize(mesh.nFaces() - mesh.nInternalFaces());
@ -959,6 +1043,9 @@ void Foam::fvMeshDistribute::subsetBoundaryData
subNewNbrProc[newBFacei] = sourceNewNbrProc[oldBFacei]; subNewNbrProc[newBFacei] = sourceNewNbrProc[oldBFacei];
} }
} }
subPointMaster = UIndirectList<label>(sourcePointMaster, pointMap);
} }
@ -1042,9 +1129,9 @@ Foam::labelList Foam::fvMeshDistribute::mapBoundaryData
( (
const primitiveMesh& mesh, // mesh after adding const primitiveMesh& mesh, // mesh after adding
const mapAddedPolyMesh& map, const mapAddedPolyMesh& map,
const labelList& boundaryData0, // mesh before adding const labelList& boundaryData0, // on mesh before adding
const label nInternalFaces1, const label nInternalFaces1,
const labelList& boundaryData1 // added mesh const labelList& boundaryData1 // on added mesh
) )
{ {
labelList newBoundaryData(mesh.nFaces() - mesh.nInternalFaces()); labelList newBoundaryData(mesh.nFaces() - mesh.nInternalFaces());
@ -1076,6 +1163,41 @@ Foam::labelList Foam::fvMeshDistribute::mapBoundaryData
} }
Foam::labelList Foam::fvMeshDistribute::mapPointData
(
const primitiveMesh& mesh, // mesh after adding
const mapAddedPolyMesh& map,
const labelList& boundaryData0, // on mesh before adding
const labelList& boundaryData1 // on added mesh
)
{
labelList newBoundaryData(mesh.nPoints());
forAll(boundaryData0, oldPointi)
{
label newPointi = map.oldPointMap()[oldPointi];
// Point still exists (is necessary?)
if (newPointi >= 0)
{
newBoundaryData[newPointi] = boundaryData0[oldPointi];
}
}
forAll(boundaryData1, addedPointi)
{
label newPointi = map.addedPointMap()[addedPointi];
if (newPointi >= 0)
{
newBoundaryData[newPointi] = boundaryData1[addedPointi];
}
}
return newBoundaryData;
}
// Remove cells. Add all exposed faces to patch oldInternalPatchi // Remove cells. Add all exposed faces to patch oldInternalPatchi
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
( (
@ -1297,6 +1419,7 @@ void Foam::fvMeshDistribute::sendMesh
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourcePatch, const labelList& sourcePatch,
const labelList& sourceNewNbrProc, const labelList& sourceNewNbrProc,
const labelList& sourcePointMaster,
Ostream& toDomain Ostream& toDomain
) )
{ {
@ -1433,7 +1556,8 @@ void Foam::fvMeshDistribute::sendMesh
<< sourceFace << sourceFace
<< sourceProc << sourceProc
<< sourcePatch << sourcePatch
<< sourceNewNbrProc; << sourceNewNbrProc
<< sourcePointMaster;
if (debug) if (debug)
@ -1456,6 +1580,7 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
labelList& domainSourceProc, labelList& domainSourceProc,
labelList& domainSourcePatch, labelList& domainSourcePatch,
labelList& domainSourceNewNbrProc, labelList& domainSourceNewNbrProc,
labelList& domainSourcePointMaster,
Istream& fromNbr Istream& fromNbr
) )
{ {
@ -1474,7 +1599,8 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
>> domainSourceFace >> domainSourceFace
>> domainSourceProc >> domainSourceProc
>> domainSourcePatch >> domainSourcePatch
>> domainSourceNewNbrProc; >> domainSourceNewNbrProc
>> domainSourcePointMaster;
// Construct fvMesh // Construct fvMesh
auto domainMeshPtr = autoPtr<fvMesh>::New auto domainMeshPtr = autoPtr<fvMesh>::New
@ -1709,13 +1835,15 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
labelList sourceFace; labelList sourceFace;
labelList sourceProc; labelList sourceProc;
labelList sourceNewNbrProc; labelList sourceNewNbrProc;
getNeighbourData labelList sourcePointMaster;
getCouplingData
( (
distribution, distribution,
sourceFace, sourceFace,
sourceProc, sourceProc,
sourcePatch, sourcePatch,
sourceNewNbrProc sourceNewNbrProc,
sourcePointMaster
); );
@ -1924,11 +2052,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
labelList procSourceProc; labelList procSourceProc;
labelList procSourcePatch; labelList procSourcePatch;
labelList procSourceNewNbrProc; labelList procSourceNewNbrProc;
labelList procSourcePointMaster;
subsetBoundaryData subsetCouplingData
( (
subsetter.subMesh(), subsetter.subMesh(),
subsetter.faceMap(), // from subMesh to mesh subsetter.pointMap(), // from subMesh to mesh
subsetter.faceMap(), // ,, ,,
subsetter.cellMap(), // ,, ,, subsetter.cellMap(), // ,, ,,
distribution, // old mesh distribution distribution, // old mesh distribution
@ -1940,15 +2070,16 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
sourceProc, sourceProc,
sourcePatch, sourcePatch,
sourceNewNbrProc, sourceNewNbrProc,
sourcePointMaster,
procSourceFace, procSourceFace,
procSourceProc, procSourceProc,
procSourcePatch, procSourcePatch,
procSourceNewNbrProc procSourceNewNbrProc,
procSourcePointMaster
); );
// Send to neighbour // Send to neighbour
sendMesh sendMesh
( (
@ -1963,6 +2094,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
procSourceProc, procSourceProc,
procSourcePatch, procSourcePatch,
procSourceNewNbrProc, procSourceNewNbrProc,
procSourcePointMaster,
str str
); );
@ -2121,10 +2254,12 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
labelList domainSourceProc; labelList domainSourceProc;
labelList domainSourcePatch; labelList domainSourcePatch;
labelList domainSourceNewNbrProc; labelList domainSourceNewNbrProc;
labelList domainSourcePointMaster;
subsetBoundaryData subsetCouplingData
( (
mesh_, // new mesh mesh_, // new mesh
subMap().pointMap(), // from new to original mesh
subMap().faceMap(), // from new to original mesh subMap().faceMap(), // from new to original mesh
subMap().cellMap(), subMap().cellMap(),
@ -2137,17 +2272,20 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
sourceProc, sourceProc,
sourcePatch, sourcePatch,
sourceNewNbrProc, sourceNewNbrProc,
sourcePointMaster,
domainSourceFace, domainSourceFace,
domainSourceProc, domainSourceProc,
domainSourcePatch, domainSourcePatch,
domainSourceNewNbrProc domainSourceNewNbrProc,
domainSourcePointMaster
); );
sourceFace.transfer(domainSourceFace); sourceFace.transfer(domainSourceFace);
sourceProc.transfer(domainSourceProc); sourceProc.transfer(domainSourceProc);
sourcePatch.transfer(domainSourcePatch); sourcePatch.transfer(domainSourcePatch);
sourceNewNbrProc.transfer(domainSourceNewNbrProc); sourceNewNbrProc.transfer(domainSourceNewNbrProc);
sourcePointMaster.transfer(domainSourcePointMaster);
} }
@ -2205,6 +2343,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
labelList domainSourceProc; labelList domainSourceProc;
labelList domainSourcePatch; labelList domainSourcePatch;
labelList domainSourceNewNbrProc; labelList domainSourceNewNbrProc;
labelList domainSourcePointMaster;
autoPtr<fvMesh> domainMeshPtr; autoPtr<fvMesh> domainMeshPtr;
@ -2241,6 +2380,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
domainSourceProc, domainSourceProc,
domainSourcePatch, domainSourcePatch,
domainSourceNewNbrProc, domainSourceNewNbrProc,
domainSourcePointMaster,
str str
); );
fvMesh& domainMesh = domainMeshPtr(); fvMesh& domainMesh = domainMeshPtr();
@ -2508,6 +2648,15 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
domainMesh.nInternalFaces(), domainMesh.nInternalFaces(),
domainSourceNewNbrProc domainSourceNewNbrProc
); );
// Update pointMaster data
sourcePointMaster = mapPointData
(
mesh_,
map(),
sourcePointMaster,
domainSourcePointMaster
);
// Update all addressing so xxProcAddressing points to correct // Update all addressing so xxProcAddressing points to correct
// item in masterMesh. // item in masterMesh.
@ -2621,6 +2770,10 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
} }
// See if any originally shared points need to be merged. Note: does
// parallel comms. After this points and edges should again be consistent.
mergeSharedPoints(sourcePointMaster, constructPointMap);
// Add processorPatches // Add processorPatches
// ~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~
@ -2650,16 +2803,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// Change patches. Since this might change ordering of coupled faces // Change patches. Since this might change ordering of coupled faces
// we also need to adapt our constructMaps. // we also need to adapt our constructMaps.
// NOTE: there is one very particular problem with this structure.
// We first create the processor patches and use these to merge out
// shared points (see mergeSharedPoints below). So temporarily points
// and edges do not match!
repatch(newPatchID, constructFaceMap); repatch(newPatchID, constructFaceMap);
// See if any geometrically shared points need to be merged. Note: does
// parallel comms. After this points and edges should again be consistent.
mergeSharedPoints(constructPointMap);
// Bit of hack: processorFvPatchField does not get reset since created // Bit of hack: processorFvPatchField does not get reset since created
// from nothing so explicitly reset. // from nothing so explicitly reset.
initPatchFields<volScalarField, processorFvPatchField<scalar>> initPatchFields<volScalarField, processorFvPatchField<scalar>>

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -163,11 +163,11 @@ class fvMeshDistribute
labelListList& constructFaceMap labelListList& constructFaceMap
); );
//- Merge any shared points that are geometrically shared. Needs //- Merge any local points that were remotely coupled.
// parallel valid mesh - uses globalMeshData.
// constructPointMap is adapted for the new point labels. // constructPointMap is adapted for the new point labels.
autoPtr<mapPolyMesh> mergeSharedPoints autoPtr<mapPolyMesh> mergeSharedPoints
( (
const labelList& pointToGlobalMaster,
labelListList& constructPointMap labelListList& constructPointMap
); );
@ -175,19 +175,21 @@ class fvMeshDistribute
// Coupling information // Coupling information
//- Construct the local environment of all boundary faces. //- Construct the local environment of all boundary faces.
void getNeighbourData void getCouplingData
( (
const labelList& distribution, const labelList& distribution,
labelList& sourceFace, labelList& sourceFace,
labelList& sourceProc, labelList& sourceProc,
labelList& sourcePatch, labelList& sourcePatch,
labelList& sourceNewProc labelList& sourceNewProc,
labelList& sourcePointMaster
) const; ) const;
// Subset the neighbourCell/neighbourProc fields // Subset the neighbourCell/neighbourProc fields
static void subsetBoundaryData static void subsetCouplingData
( (
const fvMesh& mesh, const fvMesh& mesh,
const labelList& pointMap,
const labelList& faceMap, const labelList& faceMap,
const labelList& cellMap, const labelList& cellMap,
@ -200,11 +202,13 @@ class fvMeshDistribute
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourcePatch, const labelList& sourcePatch,
const labelList& sourceNewProc, const labelList& sourceNewProc,
const labelList& sourcePointMaster,
labelList& subFace, labelList& subFace,
labelList& subProc, labelList& subProc,
labelList& subPatch, labelList& subPatch,
labelList& subNewProc labelList& subNewProc,
labelList& subPointMaster
); );
//- Find cells on mesh whose faceID/procID match the neighbour //- Find cells on mesh whose faceID/procID match the neighbour
@ -237,6 +241,14 @@ class fvMeshDistribute
const labelList& boundaryData1 // added mesh const labelList& boundaryData1 // added mesh
); );
//- Map point data to new mesh (resulting from adding two meshes)
static labelList mapPointData
(
const primitiveMesh& mesh, // mesh after adding
const mapAddedPolyMesh& map,
const labelList& boundaryData0, // on mesh before adding
const labelList& boundaryData1 // on added mesh
);
// Other // Other
@ -276,6 +288,7 @@ class fvMeshDistribute
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourcePatch, const labelList& sourcePatch,
const labelList& sourceNewProc, const labelList& sourceNewProc,
const labelList& sourcePointMaster,
Ostream& toDomain Ostream& toDomain
); );
//- Send subset of fields //- Send subset of fields
@ -300,6 +313,7 @@ class fvMeshDistribute
labelList& domainSourceProc, labelList& domainSourceProc,
labelList& domainSourcePatch, labelList& domainSourcePatch,
labelList& domainSourceNewProc, labelList& domainSourceNewProc,
labelList& domainSourcePointMaster,
Istream& fromNbr Istream& fromNbr
); );