mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: redistributePar: single-step. See #1211
- single-step for reconstructParMesh - no point merging for redistributePar -reconstruct
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -1658,7 +1658,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Mesh distribution engine (uses tolerance to reconstruct meshes)
|
||||
fvMeshDistribute distributor(mesh, mergeDist);
|
||||
fvMeshDistribute distributor(mesh);
|
||||
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -36,11 +36,25 @@ Description
|
||||
Writes point/face/cell procAddressing so afterwards reconstructPar can be
|
||||
used to reconstruct fields.
|
||||
|
||||
Note:
|
||||
- uses geometric matching tolerance (set with -mergeTol (at your option)
|
||||
Usage
|
||||
\b reconstructParMesh [OPTION]
|
||||
|
||||
If the parallel case does not have correct procBoundaries use the
|
||||
-fullMatch option which will check all boundary faces (bit slower).
|
||||
Options:
|
||||
- \par -fullMatch
|
||||
Does geometric matching on all boundary faces. Assumes no point
|
||||
ordering
|
||||
|
||||
- \par -procMatch
|
||||
Assumes processor patches already in face order but not point order.
|
||||
This is the pre v2106 default behaviour but might be removed if the new
|
||||
topological method works well
|
||||
|
||||
- \par -mergeTol \<tol\>
|
||||
Specifies non-default merge tolerance (fraction of mesh bounding box)
|
||||
for above options
|
||||
|
||||
The default is to assume all processor boundaries are correctly ordered
|
||||
(both faces and points) in which case no merge tolerance is needed.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -57,6 +71,7 @@ Description
|
||||
#include "polyTopoChange.H"
|
||||
#include "extrapolatedCalculatedFvPatchFields.H"
|
||||
#include "topoSet.H"
|
||||
#include "fvMeshTools.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -67,22 +82,6 @@ using namespace Foam;
|
||||
static const scalar defaultMergeTol = 1e-7;
|
||||
|
||||
|
||||
static void renumber
|
||||
(
|
||||
const labelList& map,
|
||||
labelList& elems
|
||||
)
|
||||
{
|
||||
forAll(elems, i)
|
||||
{
|
||||
if (elems[i] >= 0)
|
||||
{
|
||||
elems[i] = map[elems[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Determine which faces are coupled. Uses geometric merge distance.
|
||||
// Looks either at all boundaryFaces (fullMatch) or only at the
|
||||
// procBoundaries for proci. Assumes that masterMesh contains already merged
|
||||
@ -366,12 +365,11 @@ boundBox procBounds
|
||||
}
|
||||
|
||||
|
||||
void writeCellDistance
|
||||
void writeDistribution
|
||||
(
|
||||
Time& runTime,
|
||||
const fvMesh& masterMesh,
|
||||
const labelListList& cellProcAddressing
|
||||
|
||||
)
|
||||
{
|
||||
// Write the decomposition as labelList for use with 'manual'
|
||||
@ -446,6 +444,175 @@ void writeCellDistance
|
||||
}
|
||||
|
||||
|
||||
void writeMesh
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const labelListList& cellProcAddressing
|
||||
)
|
||||
{
|
||||
Info<< "\nWriting merged mesh to "
|
||||
<< mesh.time().path()/mesh.time().timeName()
|
||||
<< nl << endl;
|
||||
|
||||
if (!mesh.write())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Failed writing polyMesh."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
topoSet::removeFiles(mesh);
|
||||
}
|
||||
|
||||
|
||||
void writeMaps
|
||||
(
|
||||
const label masterInternalFaces,
|
||||
const labelUList& masterOwner,
|
||||
const polyMesh& procMesh,
|
||||
const labelUList& cellProcAddressing,
|
||||
const labelUList& faceProcAddressing,
|
||||
const labelUList& pointProcAddressing,
|
||||
const labelUList& boundaryProcAddressing
|
||||
)
|
||||
{
|
||||
// From processor point to reconstructed mesh point
|
||||
|
||||
Info<< "Writing pointProcAddressing to "
|
||||
<< procMesh.time().caseName()
|
||||
/procMesh.facesInstance()
|
||||
/polyMesh::meshSubDir
|
||||
<< endl;
|
||||
|
||||
labelIOList
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pointProcAddressing",
|
||||
procMesh.facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Do not register
|
||||
),
|
||||
pointProcAddressing
|
||||
).write();
|
||||
|
||||
|
||||
// From processor face to reconstructed mesh face
|
||||
|
||||
Info<< "Writing faceProcAddressing to "
|
||||
<< procMesh.time().caseName()
|
||||
/procMesh.facesInstance()
|
||||
/polyMesh::meshSubDir
|
||||
<< endl;
|
||||
|
||||
labelIOList faceProcAddr
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"faceProcAddressing",
|
||||
procMesh.facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Do not register
|
||||
),
|
||||
faceProcAddressing
|
||||
);
|
||||
|
||||
// Now add turning index to faceProcAddressing.
|
||||
// See reconstructPar for meaning of turning index.
|
||||
forAll(faceProcAddr, procFacei)
|
||||
{
|
||||
const label masterFacei = faceProcAddr[procFacei];
|
||||
|
||||
if
|
||||
(
|
||||
!procMesh.isInternalFace(procFacei)
|
||||
&& masterFacei < masterInternalFaces
|
||||
)
|
||||
{
|
||||
// proc face is now external but used to be internal face.
|
||||
// Check if we have owner or neighbour.
|
||||
|
||||
label procOwn = procMesh.faceOwner()[procFacei];
|
||||
label masterOwn = masterOwner[masterFacei];
|
||||
|
||||
if (cellProcAddressing[procOwn] == masterOwn)
|
||||
{
|
||||
// No turning. Offset by 1.
|
||||
faceProcAddr[procFacei]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Turned face.
|
||||
faceProcAddr[procFacei] = -1 - faceProcAddr[procFacei];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No turning. Offset by 1.
|
||||
faceProcAddr[procFacei]++;
|
||||
}
|
||||
}
|
||||
|
||||
faceProcAddr.write();
|
||||
|
||||
|
||||
// From processor cell to reconstructed mesh cell
|
||||
|
||||
Info<< "Writing cellProcAddressing to "
|
||||
<< procMesh.time().caseName()
|
||||
/procMesh.facesInstance()
|
||||
/polyMesh::meshSubDir
|
||||
<< endl;
|
||||
|
||||
labelIOList
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellProcAddressing",
|
||||
procMesh.facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Do not register
|
||||
),
|
||||
cellProcAddressing
|
||||
).write();
|
||||
|
||||
|
||||
|
||||
// From processor patch to reconstructed mesh patch
|
||||
|
||||
Info<< "Writing boundaryProcAddressing to "
|
||||
<< procMesh.time().caseName()
|
||||
/procMesh.facesInstance()
|
||||
/polyMesh::meshSubDir
|
||||
<< endl;
|
||||
|
||||
labelIOList
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"boundaryProcAddressing",
|
||||
procMesh.facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Do not register
|
||||
),
|
||||
boundaryProcAddressing
|
||||
).write();
|
||||
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addNote
|
||||
@ -470,6 +637,11 @@ int main(int argc, char *argv[])
|
||||
"Do (slower) geometric matching on all boundary faces"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"procMatch",
|
||||
"Do matching on processor faces only"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"cellDist",
|
||||
"Write cell distribution as a labelList - for use with 'manual' "
|
||||
@ -509,10 +681,29 @@ int main(int argc, char *argv[])
|
||||
Info<< "Operating on region " << regionName << nl << endl;
|
||||
}
|
||||
|
||||
const scalar mergeTol =
|
||||
args.getOrDefault<scalar>("mergeTol", defaultMergeTol);
|
||||
const bool fullMatch = args.found("fullMatch");
|
||||
const bool procMatch = args.found("procMatch");
|
||||
const bool writeCellDist = args.found("cellDist");
|
||||
|
||||
scalar writeTol = Foam::pow(10.0, -scalar(IOstream::defaultPrecision()));
|
||||
if (fullMatch)
|
||||
{
|
||||
Info<< "Doing geometric matching on all boundary faces." << nl << endl;
|
||||
}
|
||||
else if (procMatch)
|
||||
{
|
||||
Info<< "Doing geometric matching on correct procBoundaries only."
|
||||
<< nl << "This assumes a correct decomposition." << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Assuming correct, fully matched procBoundaries." << nl << endl;
|
||||
}
|
||||
|
||||
scalar mergeTol = args.getOrDefault<scalar>("mergeTol", defaultMergeTol);
|
||||
if (fullMatch || procMatch)
|
||||
{
|
||||
scalar writeTol =
|
||||
Foam::pow(10.0, -scalar(IOstream::defaultPrecision()));
|
||||
|
||||
Info<< "Merge tolerance : " << mergeTol << nl
|
||||
<< "Write tolerance : " << writeTol << endl;
|
||||
@ -522,26 +713,13 @@ int main(int argc, char *argv[])
|
||||
FatalErrorInFunction
|
||||
<< "Your current settings specify ASCII writing with "
|
||||
<< IOstream::defaultPrecision() << " digits precision." << endl
|
||||
<< "Your merging tolerance (" << mergeTol << ") is finer than this."
|
||||
<< endl
|
||||
<< "Your merging tolerance (" << mergeTol << ")"
|
||||
<< " is finer than this." << endl
|
||||
<< "Please change your writeFormat to binary"
|
||||
<< " or increase the writePrecision" << endl
|
||||
<< "or adjust the merge tolerance (-mergeTol)."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
const bool fullMatch = args.found("fullMatch");
|
||||
const bool writeCellDist = args.found("cellDist");
|
||||
|
||||
if (fullMatch)
|
||||
{
|
||||
Info<< "Doing geometric matching on all boundary faces." << nl << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Doing geometric matching on correct procBoundaries only."
|
||||
<< nl << "This assumes a correct decomposition." << endl;
|
||||
}
|
||||
|
||||
label nProcs = fileHandler().nProcs(args.path());
|
||||
@ -612,6 +790,21 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
// Addressing from processor to reconstructed case
|
||||
labelListList cellProcAddressing(nProcs);
|
||||
labelListList faceProcAddressing(nProcs);
|
||||
labelListList pointProcAddressing(nProcs);
|
||||
labelListList boundaryProcAddressing(nProcs);
|
||||
|
||||
|
||||
// Internal faces on the final reconstructed mesh
|
||||
label masterInternalFaces;
|
||||
|
||||
// Owner addressing on the final reconstructed mesh
|
||||
labelList masterOwner;
|
||||
|
||||
if (procMatch)
|
||||
{
|
||||
// Read point on individual processors to determine merge tolerance
|
||||
// (otherwise single cell domains might give problems)
|
||||
|
||||
@ -624,19 +817,6 @@ int main(int argc, char *argv[])
|
||||
<< endl;
|
||||
|
||||
|
||||
// Addressing from processor to reconstructed case
|
||||
labelListList cellProcAddressing(nProcs);
|
||||
labelListList faceProcAddressing(nProcs);
|
||||
labelListList pointProcAddressing(nProcs);
|
||||
labelListList boundaryProcAddressing(nProcs);
|
||||
|
||||
// Internal faces on the final reconstructed mesh
|
||||
label masterInternalFaces;
|
||||
|
||||
// Owner addressing on the final reconstructed mesh
|
||||
labelList masterOwner;
|
||||
|
||||
{
|
||||
// Construct empty mesh.
|
||||
// fvMesh** masterMesh = new fvMesh*[nProcs];
|
||||
PtrList<fvMesh> masterMesh(nProcs);
|
||||
@ -818,30 +998,188 @@ int main(int argc, char *argv[])
|
||||
masterInternalFaces = masterMesh[0].nInternalFaces();
|
||||
masterOwner = masterMesh[0].faceOwner();
|
||||
|
||||
|
||||
Info<< "\nWriting merged mesh to "
|
||||
<< runTime.path()/runTime.timeName()
|
||||
<< nl << endl;
|
||||
|
||||
if (!masterMesh[0].write())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Failed writing polyMesh."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
topoSet::removeFiles(masterMesh[0]);
|
||||
|
||||
// Write reconstructed mesh
|
||||
writeMesh(masterMesh[0], cellProcAddressing);
|
||||
if (writeCellDist)
|
||||
{
|
||||
writeCellDistance
|
||||
writeDistribution(runTime, masterMesh[0], cellProcAddressing);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load all meshes
|
||||
PtrList<fvMesh> fvMeshes(nProcs);
|
||||
for (label proci=0; proci<nProcs; proci++)
|
||||
{
|
||||
fvMeshes.set
|
||||
(
|
||||
runTime,
|
||||
masterMesh[0],
|
||||
cellProcAddressing
|
||||
proci,
|
||||
new fvMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
regionName,
|
||||
databases[proci].timeName(),
|
||||
databases[proci]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Construct pointers to meshes
|
||||
UPtrList<polyMesh> meshes(fvMeshes.size());
|
||||
forAll(fvMeshes, proci)
|
||||
{
|
||||
meshes.set(proci, &fvMeshes[proci]);
|
||||
}
|
||||
|
||||
// Collect statistics
|
||||
label nCells = 0;
|
||||
label nFaces = 0;
|
||||
label nPoints = 0;
|
||||
forAll(meshes, proci)
|
||||
{
|
||||
const polyMesh& mesh = meshes[proci];
|
||||
nCells += mesh.nCells();
|
||||
nFaces += mesh.nFaces();
|
||||
nPoints += mesh.nPoints();
|
||||
}
|
||||
|
||||
// Get pairs of patches to stitch. These pairs have to
|
||||
// - have ordered, opposite faces (so one to one correspondence)
|
||||
List<DynamicList<label>> localPatch;
|
||||
List<DynamicList<label>> remoteProc;
|
||||
List<DynamicList<label>> remotePatch;
|
||||
const label nGlobalPatches = polyMeshAdder::procPatchPairs
|
||||
(
|
||||
meshes,
|
||||
localPatch,
|
||||
remoteProc,
|
||||
remotePatch
|
||||
);
|
||||
|
||||
// Collect matching boundary faces on patches-to-stitch
|
||||
labelListList localBoundaryFace;
|
||||
labelListList remoteFaceProc;
|
||||
labelListList remoteBoundaryFace;
|
||||
polyMeshAdder::patchFacePairs
|
||||
(
|
||||
meshes,
|
||||
localPatch,
|
||||
remoteProc,
|
||||
remotePatch,
|
||||
localBoundaryFace,
|
||||
remoteFaceProc,
|
||||
remoteBoundaryFace
|
||||
);
|
||||
|
||||
// All matched faces assumed to have vertex0 matched
|
||||
labelListList remoteFaceStart(meshes.size());
|
||||
forAll(meshes, proci)
|
||||
{
|
||||
const labelList& procFaces = localBoundaryFace[proci];
|
||||
remoteFaceStart[proci].setSize(procFaces.size(), 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
labelListList patchMap(meshes.size());
|
||||
labelListList pointZoneMap(meshes.size());
|
||||
labelListList faceZoneMap(meshes.size());
|
||||
labelListList cellZoneMap(meshes.size());
|
||||
forAll(meshes, proci)
|
||||
{
|
||||
const polyMesh& mesh = meshes[proci];
|
||||
patchMap[proci] = identity(mesh.boundaryMesh().size());
|
||||
|
||||
// Remove excess patches
|
||||
patchMap[proci].setSize(nGlobalPatches);
|
||||
|
||||
pointZoneMap[proci] = identity(mesh.pointZones().size());
|
||||
faceZoneMap[proci] = identity(mesh.faceZones().size());
|
||||
cellZoneMap[proci] = identity(mesh.cellZones().size());
|
||||
}
|
||||
|
||||
|
||||
refPtr<fvMesh> masterMeshPtr;
|
||||
{
|
||||
// Do in-place addition on proc0.
|
||||
|
||||
const labelList oldFaceOwner(fvMeshes[0].faceOwner());
|
||||
|
||||
fvMeshAdder::add
|
||||
(
|
||||
0, // index of mesh to modify (== mesh_)
|
||||
fvMeshes,
|
||||
oldFaceOwner,
|
||||
|
||||
// Coupling info
|
||||
localBoundaryFace,
|
||||
remoteFaceProc,
|
||||
remoteBoundaryFace,
|
||||
|
||||
boundaryProcAddressing,
|
||||
cellProcAddressing,
|
||||
faceProcAddressing,
|
||||
pointProcAddressing
|
||||
);
|
||||
|
||||
// Remove zero-faces processor patches
|
||||
const polyBoundaryMesh& pbm = fvMeshes[0].boundaryMesh();
|
||||
labelList oldToNew(pbm.size(), -1);
|
||||
label newi = 0;
|
||||
// Non processor patches first
|
||||
forAll(pbm, patchi)
|
||||
{
|
||||
const auto& pp = pbm[patchi];
|
||||
if (!isA<processorPolyPatch>(pp) || pp.size())
|
||||
{
|
||||
oldToNew[patchi] = newi++;
|
||||
}
|
||||
}
|
||||
const label nNonProcPatches = newi;
|
||||
|
||||
// Move all deletable patches to the end
|
||||
forAll(oldToNew, patchi)
|
||||
{
|
||||
if (oldToNew[patchi] == -1)
|
||||
{
|
||||
oldToNew[patchi] = newi++;
|
||||
}
|
||||
}
|
||||
fvMeshTools::reorderPatches
|
||||
(
|
||||
fvMeshes[0],
|
||||
oldToNew,
|
||||
nNonProcPatches,
|
||||
false
|
||||
);
|
||||
|
||||
masterMeshPtr = fvMeshes[0];
|
||||
}
|
||||
|
||||
|
||||
const fvMesh& masterMesh = masterMeshPtr();
|
||||
|
||||
// Number of internal faces on the final reconstructed mesh
|
||||
masterInternalFaces = masterMesh.nInternalFaces();
|
||||
// Owner addressing on the final reconstructed mesh
|
||||
masterOwner = masterMesh.faceOwner();
|
||||
|
||||
// Write reconstructed mesh
|
||||
const word oldCaseName = masterMesh.time().caseName();
|
||||
const_cast<Time&>(masterMesh.time()).caseName() =
|
||||
runTime.caseName();
|
||||
|
||||
writeMesh(masterMesh, cellProcAddressing);
|
||||
if (writeCellDist)
|
||||
{
|
||||
writeDistribution(runTime, masterMesh, cellProcAddressing);
|
||||
}
|
||||
const_cast<Time&>(masterMesh.time()).caseName() = oldCaseName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Write the addressing
|
||||
|
||||
@ -863,143 +1201,16 @@ int main(int argc, char *argv[])
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// From processor point to reconstructed mesh point
|
||||
|
||||
Info<< "Writing pointProcAddressing to "
|
||||
<< databases[proci].caseName()
|
||||
/procMesh.facesInstance()
|
||||
/polyMesh::meshSubDir
|
||||
<< endl;
|
||||
|
||||
labelIOList
|
||||
writeMaps
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pointProcAddressing",
|
||||
procMesh.facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
masterInternalFaces,
|
||||
masterOwner,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Do not register
|
||||
),
|
||||
pointProcAddressing[proci]
|
||||
).write();
|
||||
|
||||
|
||||
// From processor face to reconstructed mesh face
|
||||
|
||||
Info<< "Writing faceProcAddressing to "
|
||||
<< databases[proci].caseName()
|
||||
/procMesh.facesInstance()
|
||||
/polyMesh::meshSubDir
|
||||
<< endl;
|
||||
|
||||
labelIOList faceProcAddr
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"faceProcAddressing",
|
||||
procMesh.facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Do not register
|
||||
),
|
||||
faceProcAddressing[proci]
|
||||
);
|
||||
|
||||
// Now add turning index to faceProcAddressing.
|
||||
// See reconstructPar for meaning of turning index.
|
||||
forAll(faceProcAddr, procFacei)
|
||||
{
|
||||
const label masterFacei = faceProcAddr[procFacei];
|
||||
|
||||
if
|
||||
(
|
||||
!procMesh.isInternalFace(procFacei)
|
||||
&& masterFacei < masterInternalFaces
|
||||
)
|
||||
{
|
||||
// proc face is now external but used to be internal face.
|
||||
// Check if we have owner or neighbour.
|
||||
|
||||
label procOwn = procMesh.faceOwner()[procFacei];
|
||||
label masterOwn = masterOwner[masterFacei];
|
||||
|
||||
if (cellProcAddressing[proci][procOwn] == masterOwn)
|
||||
{
|
||||
// No turning. Offset by 1.
|
||||
faceProcAddr[procFacei]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Turned face.
|
||||
faceProcAddr[procFacei] =
|
||||
-1 - faceProcAddr[procFacei];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No turning. Offset by 1.
|
||||
faceProcAddr[procFacei]++;
|
||||
}
|
||||
}
|
||||
|
||||
faceProcAddr.write();
|
||||
|
||||
|
||||
// From processor cell to reconstructed mesh cell
|
||||
|
||||
Info<< "Writing cellProcAddressing to "
|
||||
<< databases[proci].caseName()
|
||||
/procMesh.facesInstance()
|
||||
/polyMesh::meshSubDir
|
||||
<< endl;
|
||||
|
||||
labelIOList
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellProcAddressing",
|
||||
procMesh.facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Do not register
|
||||
),
|
||||
cellProcAddressing[proci]
|
||||
).write();
|
||||
|
||||
|
||||
|
||||
// From processor patch to reconstructed mesh patch
|
||||
|
||||
Info<< "Writing boundaryProcAddressing to "
|
||||
<< databases[proci].caseName()
|
||||
/procMesh.facesInstance()
|
||||
/polyMesh::meshSubDir
|
||||
<< endl;
|
||||
|
||||
labelIOList
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"boundaryProcAddressing",
|
||||
procMesh.facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Do not register
|
||||
),
|
||||
cellProcAddressing[proci],
|
||||
faceProcAddressing[proci],
|
||||
pointProcAddressing[proci],
|
||||
boundaryProcAddressing[proci]
|
||||
).write();
|
||||
|
||||
Info<< endl;
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -107,52 +107,6 @@ using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Tolerance (as fraction of the bounding box). Needs to be fairly lax since
|
||||
// usually meshes get written with limited precision (6 digits)
|
||||
static const scalar defaultMergeTol = 1e-6;
|
||||
|
||||
|
||||
// Get merging distance when matching face centres
|
||||
scalar getMergeDistance
|
||||
(
|
||||
const argList& args,
|
||||
const Time& runTime,
|
||||
const boundBox& bb
|
||||
)
|
||||
{
|
||||
const scalar mergeTol =
|
||||
args.getOrDefault<scalar>("mergeTol", defaultMergeTol);
|
||||
|
||||
const scalar writeTol =
|
||||
Foam::pow(scalar(10), -scalar(IOstream::defaultPrecision()));
|
||||
|
||||
Info<< "Merge tolerance : " << mergeTol << nl
|
||||
<< "Write tolerance : " << writeTol << endl;
|
||||
|
||||
if (runTime.writeFormat() == IOstream::ASCII && mergeTol < writeTol)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Your current settings specify ASCII writing with "
|
||||
<< IOstream::defaultPrecision() << " digits precision." << nl
|
||||
<< "Your merging tolerance (" << mergeTol << ") is finer than this."
|
||||
<< nl
|
||||
<< "Please change your writeFormat to binary"
|
||||
<< " or increase the writePrecision" << endl
|
||||
<< "or adjust the merge tolerance (-mergeTol)."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
const scalar mergeDist = mergeTol * bb.mag();
|
||||
|
||||
Info<< "Overall meshes bounding box : " << bb << nl
|
||||
<< "Relative tolerance : " << mergeTol << nl
|
||||
<< "Absolute matching distance : " << mergeDist << nl
|
||||
<< endl;
|
||||
|
||||
return mergeDist;
|
||||
}
|
||||
|
||||
|
||||
void setBasicGeometry(fvMesh& mesh)
|
||||
{
|
||||
// Set the fvGeometryScheme to basic since it does not require
|
||||
@ -860,7 +814,6 @@ void correctCoupledBoundaryConditions(fvMesh& mesh)
|
||||
autoPtr<mapDistributePolyMesh> redistributeAndWrite
|
||||
(
|
||||
const Time& baseRunTime,
|
||||
const scalar tolDim,
|
||||
const boolList& haveMesh,
|
||||
const fileName& meshSubDir,
|
||||
const bool doReadFields,
|
||||
@ -1150,7 +1103,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
|
||||
|
||||
|
||||
// Mesh distribution engine
|
||||
fvMeshDistribute distributor(mesh, tolDim);
|
||||
fvMeshDistribute distributor(mesh);
|
||||
|
||||
// Do all the distribution of mesh and fields
|
||||
autoPtr<mapDistributePolyMesh> rawMap = distributor.distribute(decomp);
|
||||
@ -2317,12 +2270,6 @@ int main(int argc, char *argv[])
|
||||
"Test without writing the decomposition. "
|
||||
"Changes -cellDist to only write volScalarField."
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"mergeTol",
|
||||
"scalar",
|
||||
"The merge distance relative to the bounding box size (default 1e-6)"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"cellDist",
|
||||
@ -2707,14 +2654,6 @@ int main(int argc, char *argv[])
|
||||
// problems. See comment in routine
|
||||
setBasicGeometry(mesh);
|
||||
|
||||
// Global matching tolerance
|
||||
const scalar tolDim = getMergeDistance
|
||||
(
|
||||
args,
|
||||
runTime,
|
||||
mesh.bounds()
|
||||
);
|
||||
|
||||
|
||||
// Determine decomposition
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -2728,7 +2667,6 @@ int main(int argc, char *argv[])
|
||||
redistributeAndWrite
|
||||
(
|
||||
baseRunTime,
|
||||
tolDim,
|
||||
haveMesh,
|
||||
meshSubDir,
|
||||
false, // do not read fields
|
||||
@ -3060,14 +2998,6 @@ int main(int argc, char *argv[])
|
||||
// << " nPatches:" << mesh.boundaryMesh().size() << endl;
|
||||
|
||||
|
||||
// Global matching tolerance
|
||||
const scalar tolDim = getMergeDistance
|
||||
(
|
||||
args,
|
||||
runTime,
|
||||
mesh.bounds()
|
||||
);
|
||||
|
||||
// Determine decomposition
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -3139,7 +3069,6 @@ int main(int argc, char *argv[])
|
||||
autoPtr<mapDistributePolyMesh> distMap = redistributeAndWrite
|
||||
(
|
||||
baseRunTime,
|
||||
tolDim,
|
||||
haveMesh,
|
||||
meshSubDir,
|
||||
true, // read fields
|
||||
|
||||
@ -317,9 +317,15 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshAdder::add
|
||||
if (meshes.set(meshi))
|
||||
{
|
||||
constructPatchMap[meshi] = patchMap[meshi];
|
||||
constructPatchMap[meshi].setSize
|
||||
(
|
||||
meshes[meshi].boundaryMesh().size(),
|
||||
-1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Map all fields
|
||||
fvMeshAdder::MapVolFields<scalar>
|
||||
(
|
||||
|
||||
@ -704,8 +704,15 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "mergeSharedPoints : found " << nShared
|
||||
<< " points on processor boundaries" << nl << endl;
|
||||
}
|
||||
|
||||
Map<label> globalMasterToLocalMaster(2*nShared);
|
||||
Map<label> pointToMaster(2*nShared);
|
||||
label nMatch = 0;
|
||||
|
||||
forAll(pointToGlobalMaster, pointi)
|
||||
{
|
||||
@ -716,7 +723,9 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
|
||||
|
||||
if (iter.found())
|
||||
{
|
||||
// Matched to existing master
|
||||
pointToMaster.insert(pointi, *iter);
|
||||
nMatch++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -727,7 +736,16 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
|
||||
}
|
||||
}
|
||||
|
||||
if (returnReduce(pointToMaster.size(), sumOp<label>()) == 0)
|
||||
reduce(nMatch, sumOp<label>());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "mergeSharedPoints : found "
|
||||
<< nMatch << " mergeable points" << nl << endl;
|
||||
}
|
||||
|
||||
|
||||
if (nMatch == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1120,6 +1138,141 @@ void Foam::fvMeshDistribute::findCouples
|
||||
}
|
||||
|
||||
|
||||
void Foam::fvMeshDistribute::findCouples
|
||||
(
|
||||
const UPtrList<polyMesh>& meshes,
|
||||
const PtrList<labelList>& domainSourceFaces,
|
||||
const PtrList<labelList>& domainSourceProcs,
|
||||
const PtrList<labelList>& domainSourcePatchs,
|
||||
|
||||
labelListList& localBoundaryFace,
|
||||
labelListList& remoteFaceProc,
|
||||
labelListList& remoteBoundaryFace
|
||||
)
|
||||
{
|
||||
// Collect all matching processor face pairs. These are all the
|
||||
// faces for which we have both sides
|
||||
|
||||
// Pass 0: count number of inter-processor faces
|
||||
labelList nProcFaces(meshes.size(), 0);
|
||||
forAll(meshes, meshi)
|
||||
{
|
||||
if (meshes.set(meshi))
|
||||
{
|
||||
const labelList& domainProc = domainSourceProcs[meshi];
|
||||
const labelList& domainPatch = domainSourcePatchs[meshi];
|
||||
|
||||
forAll(domainProc, bFacei)
|
||||
{
|
||||
if (domainProc[bFacei] != -1 && domainPatch[bFacei] == -1)
|
||||
{
|
||||
nProcFaces[meshi]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "fvMeshDistribute::findCouples : nProcFaces:"
|
||||
<< flatOutput(nProcFaces) << endl;
|
||||
}
|
||||
|
||||
|
||||
// Size
|
||||
List<DynamicList<label>> dynLocalFace(Pstream::nProcs());
|
||||
List<DynamicList<label>> dynRemoteProc(Pstream::nProcs());
|
||||
List<DynamicList<label>> dynRemoteFace(Pstream::nProcs());
|
||||
|
||||
forAll(meshes, meshi)
|
||||
{
|
||||
if (meshes.set(meshi))
|
||||
{
|
||||
dynLocalFace[meshi].setCapacity(nProcFaces[meshi]);
|
||||
dynRemoteProc[meshi].setCapacity(nProcFaces[meshi]);
|
||||
dynRemoteFace[meshi].setCapacity(nProcFaces[meshi]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Insert all into big map. Find matches
|
||||
HashTable<labelPair, labelPair, labelPair::Hash<>> map(2*sum(nProcFaces));
|
||||
|
||||
nProcFaces = 0;
|
||||
|
||||
forAll(meshes, meshi)
|
||||
{
|
||||
if (meshes.set(meshi))
|
||||
{
|
||||
const labelList& domainFace = domainSourceFaces[meshi];
|
||||
const labelList& domainProc = domainSourceProcs[meshi];
|
||||
const labelList& domainPatch = domainSourcePatchs[meshi];
|
||||
|
||||
forAll(domainProc, bFacei)
|
||||
{
|
||||
if (domainProc[bFacei] != -1 && domainPatch[bFacei] == -1)
|
||||
{
|
||||
const labelPair key
|
||||
(
|
||||
domainProc[bFacei],
|
||||
domainFace[bFacei]
|
||||
);
|
||||
auto fnd = map.find(key);
|
||||
|
||||
if (!fnd.found())
|
||||
{
|
||||
// Insert
|
||||
map.emplace(key, meshi, bFacei);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Second occurence. Found match.
|
||||
const label matchProci = fnd().first();
|
||||
const label matchFacei = fnd().second();
|
||||
|
||||
dynLocalFace[meshi].append(bFacei);
|
||||
dynRemoteProc[meshi].append(matchProci);
|
||||
dynRemoteFace[meshi].append(matchFacei);
|
||||
nProcFaces[meshi]++;
|
||||
|
||||
dynLocalFace[matchProci].append(matchFacei);
|
||||
dynRemoteProc[matchProci].append(meshi);
|
||||
dynRemoteFace[matchProci].append(bFacei);
|
||||
nProcFaces[matchProci]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "fvMeshDistribute::findCouples : stored procFaces:"
|
||||
<< map.size() << endl;
|
||||
}
|
||||
|
||||
localBoundaryFace.setSize(Pstream::nProcs());
|
||||
remoteFaceProc.setSize(Pstream::nProcs());
|
||||
remoteBoundaryFace.setSize(Pstream::nProcs());
|
||||
forAll(meshes, meshi)
|
||||
{
|
||||
if (meshes.set(meshi))
|
||||
{
|
||||
localBoundaryFace[meshi] = std::move(dynLocalFace[meshi]);
|
||||
remoteFaceProc[meshi] = std::move(dynRemoteProc[meshi]);
|
||||
remoteBoundaryFace[meshi] = std::move(dynRemoteFace[meshi]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "fvMeshDistribute::findCouples : found matches:"
|
||||
<< flatOutput(nProcFaces) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Map data on boundary faces to new mesh (resulting from adding two meshes)
|
||||
Foam::labelList Foam::fvMeshDistribute::mapBoundaryData
|
||||
(
|
||||
@ -1676,10 +1829,10 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fvMeshDistribute::fvMeshDistribute(fvMesh& mesh, const scalar mergeTol)
|
||||
Foam::fvMeshDistribute::fvMeshDistribute(fvMesh& mesh)//, const scalar mergeTol)
|
||||
:
|
||||
mesh_(mesh),
|
||||
mergeTol_(mergeTol)
|
||||
mesh_(mesh)
|
||||
//mergeTol_(mergeTol)
|
||||
{}
|
||||
|
||||
|
||||
@ -2165,7 +2318,21 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
|
||||
|
||||
// Start sending&receiving from buffers
|
||||
pBufs.finishedSends();
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Starting sending" << endl;
|
||||
}
|
||||
|
||||
labelList recvSizes;
|
||||
pBufs.finishedSends(recvSizes);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Finished sending and receiving : " << flatOutput(recvSizes)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Subset the part that stays
|
||||
@ -2208,14 +2375,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
subPointMap[Pstream::myProcNo()] = subMap().pointMap();
|
||||
subPatchMap[Pstream::myProcNo()] = identity(patches.size());
|
||||
|
||||
// Initialize all addressing into current mesh
|
||||
constructCellMap[Pstream::myProcNo()] = identity(mesh_.nCells());
|
||||
constructFaceMap[Pstream::myProcNo()] = identity(mesh_.nFaces(), 1);
|
||||
constructPointMap[Pstream::myProcNo()] = identity(mesh_.nPoints());
|
||||
constructPatchMap[Pstream::myProcNo()] = identity(patches.size());
|
||||
|
||||
// Subset the mesh data: neighbourCell/neighbourProc
|
||||
// fields
|
||||
// Subset the mesh data: neighbourCell/neighbourProc fields
|
||||
labelList domainSourceFace;
|
||||
labelList domainSourceProc;
|
||||
labelList domainSourcePatch;
|
||||
@ -2281,6 +2441,41 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
// Disable parallel. Original state already known.
|
||||
UPstream::parRun(false);
|
||||
|
||||
PtrList<labelList> domainSourceFaces(Pstream::nProcs());
|
||||
PtrList<labelList> domainSourceProcs(Pstream::nProcs());
|
||||
PtrList<labelList> domainSourcePatchs(Pstream::nProcs());
|
||||
PtrList<labelList> domainSourceNewNbrProcs(Pstream::nProcs());
|
||||
PtrList<labelList> domainSourcePointMasters(Pstream::nProcs());
|
||||
|
||||
PtrList<fvMesh> domainMeshPtrs(Pstream::nProcs());
|
||||
|
||||
PtrList<PtrList<volScalarField>> vsfs(Pstream::nProcs());
|
||||
PtrList<PtrList<volVectorField>> vvfs(Pstream::nProcs());
|
||||
PtrList<PtrList<volSphericalTensorField>> vsptfs(Pstream::nProcs());
|
||||
PtrList<PtrList<volSymmTensorField>> vsytfs(Pstream::nProcs());
|
||||
PtrList<PtrList<volTensorField>> vtfs(Pstream::nProcs());
|
||||
|
||||
PtrList<PtrList<surfaceScalarField>> ssfs(Pstream::nProcs());
|
||||
PtrList<PtrList<surfaceVectorField>> svfs(Pstream::nProcs());
|
||||
PtrList<PtrList<surfaceSphericalTensorField>> ssptfs
|
||||
(
|
||||
Pstream::nProcs()
|
||||
);
|
||||
PtrList<PtrList<surfaceSymmTensorField>> ssytfs(Pstream::nProcs());
|
||||
PtrList<PtrList<surfaceTensorField>> stfs(Pstream::nProcs());
|
||||
|
||||
PtrList<PtrList<volScalarField::Internal>> dsfs(Pstream::nProcs());
|
||||
PtrList<PtrList<volVectorField::Internal>> dvfs(Pstream::nProcs());
|
||||
PtrList<PtrList<volSphericalTensorField::Internal>> dstfs
|
||||
(
|
||||
Pstream::nProcs()
|
||||
);
|
||||
PtrList<PtrList<volSymmTensorField::Internal>> dsytfs
|
||||
(
|
||||
Pstream::nProcs()
|
||||
);
|
||||
PtrList<PtrList<volTensorField::Internal>> dtfs(Pstream::nProcs());
|
||||
|
||||
forAll(nRevcCells, sendProc)
|
||||
{
|
||||
// Did processor sendProc send anything to me?
|
||||
@ -2301,36 +2496,26 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
|
||||
|
||||
// Receive from sendProc
|
||||
labelList domainSourceFace;
|
||||
labelList domainSourceProc;
|
||||
labelList domainSourcePatch;
|
||||
labelList domainSourceNewNbrProc;
|
||||
labelList domainSourcePointMaster;
|
||||
domainSourceFaces.set(sendProc, new labelList(0));
|
||||
labelList& domainSourceFace = domainSourceFaces[sendProc];
|
||||
|
||||
autoPtr<fvMesh> domainMeshPtr;
|
||||
domainSourceProcs.set(sendProc, new labelList(0));
|
||||
labelList& domainSourceProc = domainSourceProcs[sendProc];
|
||||
|
||||
PtrList<volScalarField> vsf;
|
||||
PtrList<volVectorField> vvf;
|
||||
PtrList<volSphericalTensorField> vsptf;
|
||||
PtrList<volSymmTensorField> vsytf;
|
||||
PtrList<volTensorField> vtf;
|
||||
domainSourcePatchs.set(sendProc, new labelList(0));
|
||||
labelList& domainSourcePatch = domainSourcePatchs[sendProc];
|
||||
|
||||
PtrList<surfaceScalarField> ssf;
|
||||
PtrList<surfaceVectorField> svf;
|
||||
PtrList<surfaceSphericalTensorField> ssptf;
|
||||
PtrList<surfaceSymmTensorField> ssytf;
|
||||
PtrList<surfaceTensorField> stf;
|
||||
|
||||
PtrList<volScalarField::Internal> dsf;
|
||||
PtrList<volVectorField::Internal> dvf;
|
||||
PtrList<volSphericalTensorField::Internal> dstf;
|
||||
PtrList<volSymmTensorField::Internal> dsytf;
|
||||
PtrList<volTensorField::Internal> dtf;
|
||||
domainSourceNewNbrProcs.set(sendProc, new labelList(0));
|
||||
labelList& domainSourceNewNbrProc =
|
||||
domainSourceNewNbrProcs[sendProc];
|
||||
|
||||
domainSourcePointMasters.set(sendProc, new labelList(0));
|
||||
labelList& domainSourcePointMaster =
|
||||
domainSourcePointMasters[sendProc];
|
||||
|
||||
// Opposite of sendMesh
|
||||
{
|
||||
domainMeshPtr = receiveMesh
|
||||
autoPtr<fvMesh> domainMeshPtr = receiveMesh
|
||||
(
|
||||
sendProc,
|
||||
pointZoneNames,
|
||||
@ -2345,7 +2530,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
domainSourcePointMaster,
|
||||
str
|
||||
);
|
||||
fvMesh& domainMesh = domainMeshPtr();
|
||||
domainMeshPtrs.set(sendProc, domainMeshPtr.ptr());
|
||||
fvMesh& domainMesh = domainMeshPtrs[sendProc];
|
||||
// Force construction of various on mesh.
|
||||
//(void)domainMesh.globalData();
|
||||
|
||||
@ -2355,331 +2541,258 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
dictionary fieldDicts(str);
|
||||
|
||||
// Vol fields
|
||||
vsfs.set(sendProc, new PtrList<volScalarField>(0));
|
||||
receiveFields<volScalarField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
vsf,
|
||||
vsfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
vvfs.set(sendProc, new PtrList<volVectorField>(0));
|
||||
receiveFields<volVectorField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
vvf,
|
||||
vvfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
vsptfs.set
|
||||
(
|
||||
sendProc,
|
||||
new PtrList<volSphericalTensorField>(0)
|
||||
);
|
||||
receiveFields<volSphericalTensorField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
vsptf,
|
||||
vsptfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
vsytfs.set(sendProc, new PtrList<volSymmTensorField>(0));
|
||||
receiveFields<volSymmTensorField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
vsytf,
|
||||
vsytfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
vtfs.set(sendProc, new PtrList<volTensorField>(0));
|
||||
receiveFields<volTensorField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
vtf,
|
||||
vtfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
|
||||
// Surface fields
|
||||
ssfs.set(sendProc, new PtrList<surfaceScalarField>(0));
|
||||
receiveFields<surfaceScalarField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
ssf,
|
||||
ssfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
svfs.set(sendProc, new PtrList<surfaceVectorField>(0));
|
||||
receiveFields<surfaceVectorField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
svf,
|
||||
svfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
ssptfs.set
|
||||
(
|
||||
sendProc,
|
||||
new PtrList<surfaceSphericalTensorField>(0)
|
||||
);
|
||||
receiveFields<surfaceSphericalTensorField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
ssptf,
|
||||
ssptfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
ssytfs.set(sendProc, new PtrList<surfaceSymmTensorField>(0));
|
||||
receiveFields<surfaceSymmTensorField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
ssytf,
|
||||
ssytfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
stfs.set(sendProc, new PtrList<surfaceTensorField>(0));
|
||||
receiveFields<surfaceTensorField>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
stf,
|
||||
stfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
|
||||
// Dimensioned fields
|
||||
dsfs.set
|
||||
(
|
||||
sendProc,
|
||||
new PtrList<volScalarField::Internal>(0)
|
||||
);
|
||||
receiveFields<volScalarField::Internal>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
dsf,
|
||||
dsfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
dvfs.set
|
||||
(
|
||||
sendProc,
|
||||
new PtrList<volVectorField::Internal>(0)
|
||||
);
|
||||
receiveFields<volVectorField::Internal>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
dvf,
|
||||
dvfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
dstfs.set
|
||||
(
|
||||
sendProc,
|
||||
new PtrList<volSphericalTensorField::Internal>(0)
|
||||
);
|
||||
receiveFields<volSphericalTensorField::Internal>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
dstf,
|
||||
dstfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
dsytfs.set
|
||||
(
|
||||
sendProc,
|
||||
new PtrList<volSymmTensorField::Internal>(0)
|
||||
);
|
||||
receiveFields<volSymmTensorField::Internal>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
dsytf,
|
||||
dsytfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
dtfs.set
|
||||
(
|
||||
sendProc,
|
||||
new PtrList<volTensorField::Internal>(0)
|
||||
);
|
||||
receiveFields<volTensorField::Internal>
|
||||
(
|
||||
sendProc,
|
||||
allFieldNames,
|
||||
domainMesh,
|
||||
dtf,
|
||||
dtfs[sendProc],
|
||||
fieldDicts
|
||||
);
|
||||
}
|
||||
const fvMesh& domainMesh = domainMeshPtr();
|
||||
}
|
||||
}
|
||||
|
||||
// Clear out storage
|
||||
pBufs.clear();
|
||||
|
||||
|
||||
constructCellMap[sendProc] = identity(domainMesh.nCells());
|
||||
constructFaceMap[sendProc] = identity(domainMesh.nFaces(), 1);
|
||||
constructPointMap[sendProc] = identity(domainMesh.nPoints());
|
||||
constructPatchMap[sendProc] =
|
||||
identity(domainMesh.boundaryMesh().size());
|
||||
|
||||
|
||||
// Print a bit.
|
||||
if (debug)
|
||||
// Set up pointers to meshes so we can include our mesh_
|
||||
UPtrList<polyMesh> meshes(domainMeshPtrs.size());
|
||||
UPtrList<fvMesh> fvMeshes(domainMeshPtrs.size());
|
||||
forAll(domainMeshPtrs, proci)
|
||||
{
|
||||
Pout<< nl << "RECEIVED MESH FROM:" << sendProc << endl;
|
||||
printMeshInfo(domainMesh);
|
||||
printFieldInfo<volScalarField>(domainMesh);
|
||||
printFieldInfo<volVectorField>(domainMesh);
|
||||
printFieldInfo<volSphericalTensorField>(domainMesh);
|
||||
printFieldInfo<volSymmTensorField>(domainMesh);
|
||||
printFieldInfo<volTensorField>(domainMesh);
|
||||
printFieldInfo<surfaceScalarField>(domainMesh);
|
||||
printFieldInfo<surfaceVectorField>(domainMesh);
|
||||
printFieldInfo<surfaceSphericalTensorField>(domainMesh);
|
||||
printFieldInfo<surfaceSymmTensorField>(domainMesh);
|
||||
printFieldInfo<surfaceTensorField>(domainMesh);
|
||||
if (domainMeshPtrs.set(proci))
|
||||
{
|
||||
meshes.set(proci, &domainMeshPtrs[proci]);
|
||||
fvMeshes.set(proci, &domainMeshPtrs[proci]);
|
||||
}
|
||||
}
|
||||
|
||||
// 'Receive' from myself
|
||||
{
|
||||
meshes.set(Pstream::myProcNo(), &mesh_);
|
||||
fvMeshes.set(Pstream::myProcNo(), &mesh_);
|
||||
|
||||
//domainSourceFaces.set(Pstream::myProcNo(), std::move(sourceFace));
|
||||
domainSourceFaces.set(Pstream::myProcNo(), new labelList(0));
|
||||
domainSourceFaces[Pstream::myProcNo()] = sourceFace;
|
||||
|
||||
domainSourceProcs.set(Pstream::myProcNo(), new labelList(0));
|
||||
//std::move(sourceProc));
|
||||
domainSourceProcs[Pstream::myProcNo()] = sourceProc;
|
||||
|
||||
domainSourcePatchs.set(Pstream::myProcNo(), new labelList(0));
|
||||
//, std::move(sourcePatch));
|
||||
domainSourcePatchs[Pstream::myProcNo()] = sourcePatch;
|
||||
|
||||
domainSourceNewNbrProcs.set(Pstream::myProcNo(), new labelList(0));
|
||||
domainSourceNewNbrProcs[Pstream::myProcNo()] = sourceNewNbrProc;
|
||||
|
||||
domainSourcePointMasters.set(Pstream::myProcNo(), new labelList(0));
|
||||
domainSourcePointMasters[Pstream::myProcNo()] = sourcePointMaster;
|
||||
}
|
||||
|
||||
|
||||
// Now this mesh we received (from sendProc) needs to be merged
|
||||
// with the current mesh. On the current mesh we have for all
|
||||
// boundaryfaces the original face and processor. See if we can
|
||||
// match these up to the received domainSourceFace and
|
||||
// domainSourceProc.
|
||||
labelList masterCoupledFaces;
|
||||
labelList slaveCoupledFaces;
|
||||
// Find matching faces that need to be stitched
|
||||
labelListList localBoundaryFace(Pstream::nProcs());
|
||||
labelListList remoteFaceProc(Pstream::nProcs());
|
||||
labelListList remoteBoundaryFace(Pstream::nProcs());
|
||||
findCouples
|
||||
(
|
||||
mesh_,
|
||||
meshes,
|
||||
domainSourceFaces,
|
||||
domainSourceProcs,
|
||||
domainSourcePatchs,
|
||||
|
||||
sourceFace,
|
||||
sourceProc,
|
||||
sourcePatch,
|
||||
|
||||
sendProc,
|
||||
domainMesh,
|
||||
domainSourceFace,
|
||||
domainSourceProc,
|
||||
domainSourcePatch,
|
||||
|
||||
masterCoupledFaces,
|
||||
slaveCoupledFaces
|
||||
);
|
||||
|
||||
// Generate additional coupling info (points, edges) from
|
||||
// faces-that-match
|
||||
faceCoupleInfo couples
|
||||
(
|
||||
mesh_,
|
||||
masterCoupledFaces,
|
||||
domainMesh,
|
||||
slaveCoupledFaces,
|
||||
mergeTol_, // merge tolerance
|
||||
true, // faces align
|
||||
true, // couples are ordered already
|
||||
false
|
||||
localBoundaryFace,
|
||||
remoteFaceProc,
|
||||
remoteBoundaryFace
|
||||
);
|
||||
|
||||
|
||||
// Add domainMesh to mesh
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
const label nOldInternalFaces = mesh_.nInternalFaces();
|
||||
const labelList oldFaceOwner(mesh_.faceOwner());
|
||||
|
||||
autoPtr<mapAddedPolyMesh> map = fvMeshAdder::add
|
||||
fvMeshAdder::add
|
||||
(
|
||||
mesh_,
|
||||
domainMesh,
|
||||
couples,
|
||||
false, // no parallel comms
|
||||
true // fake complete mapping
|
||||
Pstream::myProcNo(), // index of mesh to modify (== mesh_)
|
||||
fvMeshes,
|
||||
oldFaceOwner,
|
||||
|
||||
// Coupling info
|
||||
localBoundaryFace,
|
||||
remoteFaceProc,
|
||||
remoteBoundaryFace,
|
||||
|
||||
constructPatchMap,
|
||||
constructCellMap,
|
||||
constructFaceMap,
|
||||
constructPointMap
|
||||
);
|
||||
|
||||
// Update mesh data: sourceFace,sourceProc for added
|
||||
// mesh.
|
||||
|
||||
sourceFace = mapBoundaryData
|
||||
(
|
||||
mesh_,
|
||||
map(),
|
||||
sourceFace,
|
||||
domainMesh.nInternalFaces(),
|
||||
domainSourceFace
|
||||
);
|
||||
sourceProc = mapBoundaryData
|
||||
(
|
||||
mesh_,
|
||||
map(),
|
||||
sourceProc,
|
||||
domainMesh.nInternalFaces(),
|
||||
domainSourceProc
|
||||
);
|
||||
sourcePatch = mapBoundaryData
|
||||
(
|
||||
mesh_,
|
||||
map(),
|
||||
sourcePatch,
|
||||
domainMesh.nInternalFaces(),
|
||||
domainSourcePatch
|
||||
);
|
||||
sourceNewNbrProc = mapBoundaryData
|
||||
(
|
||||
mesh_,
|
||||
map(),
|
||||
sourceNewNbrProc,
|
||||
domainMesh.nInternalFaces(),
|
||||
domainSourceNewNbrProc
|
||||
);
|
||||
// Update pointMaster data
|
||||
sourcePointMaster = mapPointData
|
||||
(
|
||||
mesh_,
|
||||
map(),
|
||||
sourcePointMaster,
|
||||
domainSourcePointMaster
|
||||
);
|
||||
|
||||
|
||||
// Update all addressing so xxProcAddressing points to correct
|
||||
// item in masterMesh.
|
||||
const labelList& oldCellMap = map().oldCellMap();
|
||||
const labelList& oldFaceMap = map().oldFaceMap();
|
||||
const labelList& oldPointMap = map().oldPointMap();
|
||||
const labelList& oldPatchMap = map().oldPatchMap();
|
||||
|
||||
//Note: old mesh faces never flipped!
|
||||
forAll(constructPatchMap, proci)
|
||||
{
|
||||
if (proci != sendProc && constructPatchMap[proci].size())
|
||||
{
|
||||
// Processor already in mesh (either myProcNo or received)
|
||||
inplaceRenumber(oldCellMap, constructCellMap[proci]);
|
||||
inplaceRenumberWithFlip
|
||||
(
|
||||
oldFaceMap,
|
||||
false,
|
||||
true,
|
||||
constructFaceMap[proci]
|
||||
);
|
||||
inplaceRenumber(oldPointMap, constructPointMap[proci]);
|
||||
inplaceRenumber(oldPatchMap, constructPatchMap[proci]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
labelHashSet flippedAddedFaces;
|
||||
{
|
||||
// Find out if any faces of domain mesh were flipped (boundary
|
||||
// faces becoming internal)
|
||||
const label nBnd = domainMesh.nBoundaryFaces();
|
||||
flippedAddedFaces.resize(nBnd/4);
|
||||
|
||||
for
|
||||
(
|
||||
label domainFaceI = domainMesh.nInternalFaces();
|
||||
domainFaceI < domainMesh.nFaces();
|
||||
domainFaceI++
|
||||
)
|
||||
{
|
||||
label newFaceI = map().addedFaceMap()[domainFaceI];
|
||||
label newCellI = mesh_.faceOwner()[newFaceI];
|
||||
|
||||
label domainCellI = domainMesh.faceOwner()[domainFaceI];
|
||||
|
||||
if (newCellI != map().addedCellMap()[domainCellI])
|
||||
{
|
||||
flippedAddedFaces.insert(domainFaceI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Added processor
|
||||
inplaceRenumber(map().addedCellMap(), constructCellMap[sendProc]);
|
||||
// Add flip
|
||||
for (const label domainFaceI : flippedAddedFaces)
|
||||
{
|
||||
label& val = constructFaceMap[sendProc][domainFaceI];
|
||||
val = -val;
|
||||
}
|
||||
inplaceRenumberWithFlip
|
||||
(
|
||||
map().addedFaceMap(),
|
||||
false,
|
||||
true, // constructFaceMap has flip sign
|
||||
constructFaceMap[sendProc]
|
||||
);
|
||||
inplaceRenumber(map().addedPointMap(), constructPointMap[sendProc]);
|
||||
inplaceRenumber(map().addedPatchMap(), constructPatchMap[sendProc]);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< nl << "MERGED MESH FROM:" << sendProc << endl;
|
||||
Pout<< nl << "ADDED REMOTE MESHES:" << endl;
|
||||
printMeshInfo(mesh_);
|
||||
printFieldInfo<volScalarField>(mesh_);
|
||||
printFieldInfo<volVectorField>(mesh_);
|
||||
@ -2693,9 +2806,97 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
printFieldInfo<surfaceTensorField>(mesh_);
|
||||
Pout<< nl << endl;
|
||||
}
|
||||
|
||||
{
|
||||
//- Combine sourceProc, sourcePatch, sourceFace
|
||||
sourceProc.setSize(mesh_.nBoundaryFaces());
|
||||
sourceProc = -1;
|
||||
sourcePatch.setSize(mesh_.nBoundaryFaces());
|
||||
sourcePatch = -1;
|
||||
sourceFace.setSize(mesh_.nBoundaryFaces());
|
||||
sourceFace = -1;
|
||||
sourceNewNbrProc.setSize(mesh_.nBoundaryFaces());
|
||||
sourceNewNbrProc = -1;
|
||||
sourcePointMaster.setSize(mesh_.nPoints());
|
||||
sourcePointMaster = -1;
|
||||
|
||||
if (mesh_.nPoints() > 0)
|
||||
{
|
||||
forAll(meshes, meshi)
|
||||
{
|
||||
if (domainSourceFaces.set(meshi))
|
||||
{
|
||||
const label nIntFaces =
|
||||
(
|
||||
meshi == Pstream::myProcNo()
|
||||
? nOldInternalFaces
|
||||
: meshes[meshi].nInternalFaces()
|
||||
);
|
||||
const labelList& faceOwner
|
||||
(
|
||||
meshi == Pstream::myProcNo()
|
||||
? oldFaceOwner
|
||||
: meshes[meshi].faceOwner()
|
||||
);
|
||||
|
||||
labelList& faceMap = constructFaceMap[meshi];
|
||||
const labelList& cellMap = constructCellMap[meshi];
|
||||
|
||||
const labelList& domainSourceFace =
|
||||
domainSourceFaces[meshi];
|
||||
const labelList& domainSourceProc =
|
||||
domainSourceProcs[meshi];
|
||||
const labelList& domainSourcePatch =
|
||||
domainSourcePatchs[meshi];
|
||||
const labelList& domainSourceNewNbr =
|
||||
domainSourceNewNbrProcs[meshi];
|
||||
UIndirectList<label>
|
||||
(
|
||||
sourcePointMaster,
|
||||
constructPointMap[meshi]
|
||||
) = domainSourcePointMasters[meshi];
|
||||
|
||||
|
||||
forAll(domainSourceFace, bFacei)
|
||||
{
|
||||
const label oldFacei = bFacei+nIntFaces;
|
||||
const label allFacei = faceMap[oldFacei];
|
||||
const label allbFacei = allFacei-mesh_.nInternalFaces();
|
||||
|
||||
if (allbFacei >= 0)
|
||||
{
|
||||
sourceProc[allbFacei] = domainSourceProc[bFacei];
|
||||
sourcePatch[allbFacei] = domainSourcePatch[bFacei];
|
||||
sourceFace[allbFacei] = domainSourceFace[bFacei];
|
||||
sourceNewNbrProc[allbFacei] =
|
||||
domainSourceNewNbr[bFacei];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add flip to constructFaceMap
|
||||
forAll(faceMap, oldFacei)
|
||||
{
|
||||
const label allFacei = faceMap[oldFacei];
|
||||
const label allOwn = mesh_.faceOwner()[allFacei];
|
||||
|
||||
if (cellMap[faceOwner[oldFacei]] == allOwn)
|
||||
{
|
||||
// Master face
|
||||
faceMap[oldFacei] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Slave face. Flip.
|
||||
faceMap[oldFacei] = -faceMap[oldFacei] - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UPstream::parRun(oldParRun); // Restore parallel state
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -42,9 +42,6 @@ Description
|
||||
expects procPatches on all)
|
||||
- initial mesh has to have procPatches last and all normal patches common
|
||||
to all processors and in the same order. This is checked.
|
||||
- faces are matched topologically but points on the faces are not. So
|
||||
expect problems -on separated patches (cyclics?) -on zero sized processor
|
||||
edges.
|
||||
|
||||
SourceFiles
|
||||
fvMeshDistribute.C
|
||||
@ -78,10 +75,6 @@ class fvMeshDistribute
|
||||
//- Underlying fvMesh
|
||||
fvMesh& mesh_;
|
||||
|
||||
//- Absolute merging tolerance (constructing meshes gets done using
|
||||
// geometric matching)
|
||||
const scalar mergeTol_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
@ -230,6 +223,20 @@ class fvMeshDistribute
|
||||
labelList& slaveCoupledFaces
|
||||
);
|
||||
|
||||
//- Find cells on mesh whose faceID/procID match the neighbour
|
||||
// cell/proc of domainMesh. Store the matching face pairs
|
||||
static void findCouples
|
||||
(
|
||||
const UPtrList<polyMesh>& meshes,
|
||||
const PtrList<labelList>& domainSourceFaces,
|
||||
const PtrList<labelList>& domainSourceProcs,
|
||||
const PtrList<labelList>& domainSourcePatchs,
|
||||
|
||||
labelListList& localBoundaryFace,
|
||||
labelListList& remoteFaceProc,
|
||||
labelListList& remoteBoundaryFace
|
||||
);
|
||||
|
||||
//- Map data on boundary faces to new mesh (resulting from adding
|
||||
// two meshes)
|
||||
static labelList mapBoundaryData
|
||||
@ -352,8 +359,8 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh and absolute merge tolerance
|
||||
fvMeshDistribute(fvMesh& mesh, const scalar mergeTol);
|
||||
//- Construct from mesh
|
||||
fvMeshDistribute(fvMesh& mesh);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
@ -42,6 +42,7 @@ License
|
||||
#include "processorPolyPatch.H"
|
||||
#include "CompactListList.H"
|
||||
#include "ListOps.H"
|
||||
#include "mapPolyMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -1298,17 +1299,23 @@ Foam::labelList Foam::polyTopoChange::selectFaces
|
||||
void Foam::polyTopoChange::calcPatchPointMap
|
||||
(
|
||||
const UList<Map<label>>& oldPatchMeshPointMaps,
|
||||
const labelUList& patchMap,
|
||||
const polyBoundaryMesh& boundary,
|
||||
labelListList& patchPointMap
|
||||
) const
|
||||
{
|
||||
patchPointMap.setSize(boundary.size());
|
||||
patchPointMap.setSize(patchMap.size());
|
||||
|
||||
forAll(boundary, patchi)
|
||||
forAll(patchMap, patchi)
|
||||
{
|
||||
const label oldPatchi = patchMap[patchi];
|
||||
|
||||
if (oldPatchi != -1)
|
||||
{
|
||||
const labelList& meshPoints = boundary[patchi].meshPoints();
|
||||
|
||||
const Map<label>& oldMeshPointMap = oldPatchMeshPointMaps[patchi];
|
||||
const Map<label>& oldMeshPointMap =
|
||||
oldPatchMeshPointMaps[oldPatchi];
|
||||
|
||||
labelList& curPatchPointRnb = patchPointMap[patchi];
|
||||
|
||||
@ -1332,6 +1339,7 @@ void Foam::polyTopoChange::calcPatchPointMap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::polyTopoChange::calcFaceInflationMaps
|
||||
@ -1865,7 +1873,8 @@ void Foam::polyTopoChange::calcFaceZonePointMap
|
||||
void Foam::polyTopoChange::reorderCoupledFaces
|
||||
(
|
||||
const bool syncParallel,
|
||||
const polyBoundaryMesh& boundary,
|
||||
const polyBoundaryMesh& oldBoundary,
|
||||
const labelUList& patchMap, // new to old patches
|
||||
const labelUList& patchStarts,
|
||||
const labelUList& patchSizes,
|
||||
const pointField& points
|
||||
@ -1881,11 +1890,17 @@ void Foam::polyTopoChange::reorderCoupledFaces
|
||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||
|
||||
// Send ordering
|
||||
forAll(boundary, patchi)
|
||||
forAll(patchMap, patchi)
|
||||
{
|
||||
if (syncParallel || !isA<processorPolyPatch>(boundary[patchi]))
|
||||
const label oldPatchi = patchMap[patchi];
|
||||
|
||||
if
|
||||
(
|
||||
oldPatchi != -1
|
||||
&& (syncParallel || !isA<processorPolyPatch>(oldBoundary[oldPatchi]))
|
||||
)
|
||||
{
|
||||
boundary[patchi].initOrder
|
||||
oldBoundary[oldPatchi].initOrder
|
||||
(
|
||||
pBufs,
|
||||
primitivePatch
|
||||
@ -1911,14 +1926,20 @@ void Foam::polyTopoChange::reorderCoupledFaces
|
||||
|
||||
bool anyChanged = false;
|
||||
|
||||
forAll(boundary, patchi)
|
||||
forAll(patchMap, patchi)
|
||||
{
|
||||
if (syncParallel || !isA<processorPolyPatch>(boundary[patchi]))
|
||||
const label oldPatchi = patchMap[patchi];
|
||||
|
||||
if
|
||||
(
|
||||
oldPatchi != -1
|
||||
&& (syncParallel || !isA<processorPolyPatch>(oldBoundary[oldPatchi]))
|
||||
)
|
||||
{
|
||||
labelList patchFaceMap(patchSizes[patchi], -1);
|
||||
labelList patchFaceRotation(patchSizes[patchi], Zero);
|
||||
|
||||
const bool changed = boundary[patchi].order
|
||||
const bool changed = oldBoundary[oldPatchi].order
|
||||
(
|
||||
pBufs,
|
||||
primitivePatch
|
||||
@ -1982,6 +2003,7 @@ void Foam::polyTopoChange::reorderCoupledFaces
|
||||
void Foam::polyTopoChange::compactAndReorder
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelUList& patchMap, // from new to old patch
|
||||
const bool syncParallel,
|
||||
const bool orderCells,
|
||||
const bool orderPoints,
|
||||
@ -2004,13 +2026,13 @@ void Foam::polyTopoChange::compactAndReorder
|
||||
List<Map<label>>& oldFaceZoneMeshPointMaps
|
||||
)
|
||||
{
|
||||
if (mesh.boundaryMesh().size() != nPatches_)
|
||||
if (patchMap.size() != nPatches_)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "polyTopoChange was constructed with a mesh with "
|
||||
<< nPatches_ << " patches." << endl
|
||||
<< "The mesh now provided has a different number of patches "
|
||||
<< mesh.boundaryMesh().size()
|
||||
<< patchMap.size()
|
||||
<< " which is illegal" << endl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
@ -2028,6 +2050,7 @@ void Foam::polyTopoChange::compactAndReorder
|
||||
(
|
||||
syncParallel,
|
||||
mesh.boundaryMesh(),
|
||||
patchMap,
|
||||
patchStarts,
|
||||
patchSizes,
|
||||
newPoints
|
||||
@ -2245,7 +2268,7 @@ void Foam::polyTopoChange::addMesh
|
||||
points_.setCapacity(points_.size() + points.size());
|
||||
pointMap_.setCapacity(pointMap_.size() + points.size());
|
||||
reversePointMap_.setCapacity(reversePointMap_.size() + points.size());
|
||||
pointZone_.resize(pointZone_.size() + points.size()/100);
|
||||
pointZone_.resize(pointZone_.size() + points.size()/128);
|
||||
|
||||
// Precalc offset zones
|
||||
labelList newZoneID(points.size(), -1);
|
||||
@ -2285,9 +2308,9 @@ void Foam::polyTopoChange::addMesh
|
||||
|
||||
cellMap_.setCapacity(cellMap_.size() + nAllCells);
|
||||
reverseCellMap_.setCapacity(reverseCellMap_.size() + nAllCells);
|
||||
cellFromPoint_.resize(cellFromPoint_.size() + nAllCells/100);
|
||||
cellFromEdge_.resize(cellFromEdge_.size() + nAllCells/100);
|
||||
cellFromFace_.resize(cellFromFace_.size() + nAllCells/100);
|
||||
cellFromPoint_.resize(cellFromPoint_.size() + nAllCells/128);
|
||||
cellFromEdge_.resize(cellFromEdge_.size() + nAllCells/128);
|
||||
cellFromFace_.resize(cellFromFace_.size() + nAllCells/128);
|
||||
cellZone_.setCapacity(cellZone_.size() + nAllCells);
|
||||
|
||||
|
||||
@ -2343,10 +2366,10 @@ void Foam::polyTopoChange::addMesh
|
||||
faceNeighbour_.setCapacity(faceNeighbour_.size() + nAllFaces);
|
||||
faceMap_.setCapacity(faceMap_.size() + nAllFaces);
|
||||
reverseFaceMap_.setCapacity(reverseFaceMap_.size() + nAllFaces);
|
||||
faceFromPoint_.resize(faceFromPoint_.size() + nAllFaces/100);
|
||||
faceFromEdge_.resize(faceFromEdge_.size() + nAllFaces/100);
|
||||
faceFromPoint_.resize(faceFromPoint_.size() + nAllFaces/128);
|
||||
faceFromEdge_.resize(faceFromEdge_.size() + nAllFaces/128);
|
||||
flipFaceFlux_.setCapacity(faces_.size() + nAllFaces);
|
||||
faceZone_.resize(faceZone_.size() + nAllFaces/100);
|
||||
faceZone_.resize(faceZone_.size() + nAllFaces/128);
|
||||
faceZoneFlip_.setCapacity(faces_.size() + nAllFaces);
|
||||
|
||||
|
||||
@ -2434,7 +2457,7 @@ void Foam::polyTopoChange::setCapacity
|
||||
points_.setCapacity(nPoints);
|
||||
pointMap_.setCapacity(nPoints);
|
||||
reversePointMap_.setCapacity(nPoints);
|
||||
pointZone_.resize(pointZone_.size() + nPoints/100);
|
||||
pointZone_.resize(pointZone_.size() + nPoints/128);
|
||||
|
||||
faces_.setCapacity(nFaces);
|
||||
region_.setCapacity(nFaces);
|
||||
@ -2442,17 +2465,17 @@ void Foam::polyTopoChange::setCapacity
|
||||
faceNeighbour_.setCapacity(nFaces);
|
||||
faceMap_.setCapacity(nFaces);
|
||||
reverseFaceMap_.setCapacity(nFaces);
|
||||
faceFromPoint_.resize(faceFromPoint_.size() + nFaces/100);
|
||||
faceFromEdge_.resize(faceFromEdge_.size() + nFaces/100);
|
||||
faceFromPoint_.resize(faceFromPoint_.size() + nFaces/128);
|
||||
faceFromEdge_.resize(faceFromEdge_.size() + nFaces/128);
|
||||
flipFaceFlux_.setCapacity(nFaces);
|
||||
faceZone_.resize(faceZone_.size() + nFaces/100);
|
||||
faceZone_.resize(faceZone_.size() + nFaces/128);
|
||||
faceZoneFlip_.setCapacity(nFaces);
|
||||
|
||||
cellMap_.setCapacity(nCells);
|
||||
reverseCellMap_.setCapacity(nCells);
|
||||
cellFromPoint_.resize(cellFromPoint_.size() + nCells/100);
|
||||
cellFromEdge_.resize(cellFromEdge_.size() + nCells/100);
|
||||
cellFromFace_.resize(cellFromFace_.size() + nCells/100);
|
||||
cellFromPoint_.resize(cellFromPoint_.size() + nCells/128);
|
||||
cellFromEdge_.resize(cellFromEdge_.size() + nCells/128);
|
||||
cellFromFace_.resize(cellFromFace_.size() + nCells/128);
|
||||
cellZone_.setCapacity(nCells);
|
||||
}
|
||||
|
||||
@ -2958,6 +2981,7 @@ void Foam::polyTopoChange::removeCell
|
||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::changeMesh
|
||||
(
|
||||
polyMesh& mesh,
|
||||
const labelUList& patchMap,
|
||||
const bool inflate,
|
||||
const bool syncParallel,
|
||||
const bool orderCells,
|
||||
@ -3003,6 +3027,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::changeMesh
|
||||
compactAndReorder
|
||||
(
|
||||
mesh,
|
||||
patchMap,
|
||||
syncParallel,
|
||||
orderCells,
|
||||
orderPoints,
|
||||
@ -3159,6 +3184,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::changeMesh
|
||||
calcPatchPointMap
|
||||
(
|
||||
oldPatchMeshPointMaps,
|
||||
patchMap,
|
||||
mesh.boundaryMesh(),
|
||||
patchPointMap
|
||||
);
|
||||
@ -3218,4 +3244,25 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::changeMesh
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::changeMesh
|
||||
(
|
||||
polyMesh& mesh,
|
||||
const bool inflate,
|
||||
const bool syncParallel,
|
||||
const bool orderCells,
|
||||
const bool orderPoints
|
||||
)
|
||||
{
|
||||
return changeMesh
|
||||
(
|
||||
mesh,
|
||||
identity(mesh.boundaryMesh().size()),
|
||||
inflate,
|
||||
syncParallel,
|
||||
orderCells,
|
||||
orderPoints
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -71,7 +71,6 @@ SourceFiles
|
||||
#include "pointField.H"
|
||||
#include "Map.H"
|
||||
#include "HashSet.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "bitSet.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -91,6 +90,7 @@ class dictionary;
|
||||
class topoAction;
|
||||
class objectMap;
|
||||
class IOobject;
|
||||
class mapPolyMesh;
|
||||
template<class T, class Container> class CompactListList;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
@ -349,6 +349,7 @@ class polyTopoChange
|
||||
void calcPatchPointMap
|
||||
(
|
||||
const UList<Map<label>>& oldPatchMeshPointMaps,
|
||||
const labelUList& patchMap,
|
||||
const polyBoundaryMesh& boundary,
|
||||
labelListList& patchPointMap
|
||||
) const;
|
||||
@ -394,6 +395,7 @@ class polyTopoChange
|
||||
(
|
||||
const bool syncParallel,
|
||||
const polyBoundaryMesh& boundary,
|
||||
const labelUList& patchMap, // new back to old patch labels
|
||||
const labelUList& patchStarts,
|
||||
const labelUList& patchSizes,
|
||||
const pointField& points
|
||||
@ -402,6 +404,7 @@ class polyTopoChange
|
||||
void compactAndReorder
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelUList& patchMap, // from new to old patch
|
||||
const bool syncParallel,
|
||||
const bool orderCells,
|
||||
const bool orderPoints,
|
||||
@ -611,12 +614,37 @@ public:
|
||||
autoPtr<mapPolyMesh> changeMesh
|
||||
(
|
||||
polyMesh& mesh,
|
||||
const labelUList& patchMap,
|
||||
const bool inflate,
|
||||
const bool syncParallel = true,
|
||||
const bool orderCells = false,
|
||||
const bool orderPoints = false
|
||||
);
|
||||
|
||||
//- Without patch mapping
|
||||
autoPtr<mapPolyMesh> changeMesh
|
||||
(
|
||||
polyMesh& mesh,
|
||||
const bool inflate,
|
||||
const bool syncParallel = true,
|
||||
const bool orderCells = false,
|
||||
const bool orderPoints = false
|
||||
);
|
||||
|
||||
//- Create new mesh with old mesh patches. Additional dictionaries
|
||||
// (fv* etc) read according to IO flags
|
||||
template<class Type>
|
||||
autoPtr<mapPolyMesh> makeMesh
|
||||
(
|
||||
autoPtr<Type>& newMesh,
|
||||
const IOobject& io,
|
||||
const polyMesh& mesh,
|
||||
const labelUList& patchMap,
|
||||
const bool syncParallel = true,
|
||||
const bool orderCells = false,
|
||||
const bool orderPoints = false
|
||||
);
|
||||
|
||||
//- Create new mesh with old mesh patches. Additional dictionaries
|
||||
// (fv* etc) read according to IO flags
|
||||
template<class Type>
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,9 +26,10 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "polyTopoChange.H"
|
||||
#include "polyMesh.H"
|
||||
#include "HashOps.H"
|
||||
#include "emptyPolyPatch.H"
|
||||
#include "mapPolyMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
@ -105,6 +106,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
|
||||
autoPtr<Type>& newMeshPtr,
|
||||
const IOobject& io,
|
||||
const polyMesh& mesh,
|
||||
const labelUList& patchMap,
|
||||
const bool syncParallel,
|
||||
const bool orderCells,
|
||||
const bool orderPoints
|
||||
@ -151,6 +153,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
|
||||
compactAndReorder
|
||||
(
|
||||
mesh,
|
||||
patchMap, // from new to old patch
|
||||
syncParallel,
|
||||
orderCells,
|
||||
orderPoints,
|
||||
@ -239,11 +242,15 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
|
||||
{
|
||||
const polyBoundaryMesh& oldPatches = mesh.boundaryMesh();
|
||||
|
||||
List<polyPatch*> newBoundary(oldPatches.size());
|
||||
List<polyPatch*> newBoundary(patchMap.size());
|
||||
|
||||
forAll(oldPatches, patchi)
|
||||
forAll(patchMap, patchi)
|
||||
{
|
||||
newBoundary[patchi] = oldPatches[patchi].clone
|
||||
const label oldPatchi = patchMap[patchi];
|
||||
|
||||
if (oldPatchi != -1)
|
||||
{
|
||||
newBoundary[patchi] = oldPatches[oldPatchi].clone
|
||||
(
|
||||
newMesh.boundaryMesh(),
|
||||
patchi,
|
||||
@ -251,6 +258,20 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
|
||||
patchStarts[patchi]
|
||||
).ptr();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Added patch
|
||||
newBoundary[patchi] = new emptyPolyPatch
|
||||
(
|
||||
"patch" + Foam::name(patchi),
|
||||
patchSizes[patchi],
|
||||
patchStarts[patchi],
|
||||
patchi,
|
||||
newMesh.boundaryMesh(),
|
||||
word::null
|
||||
);
|
||||
}
|
||||
}
|
||||
newMesh.addFvPatches(newBoundary);
|
||||
}
|
||||
|
||||
@ -327,6 +348,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
|
||||
calcPatchPointMap
|
||||
(
|
||||
oldPatchMeshPointMaps,
|
||||
patchMap,
|
||||
newMesh.boundaryMesh(),
|
||||
patchPointMap
|
||||
);
|
||||
@ -338,7 +360,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "New mesh:" << nl;
|
||||
writeMeshStats(mesh, Pout);
|
||||
writeMeshStats(newMesh, Pout);
|
||||
}
|
||||
|
||||
labelHashSet flipFaceFluxSet(HashSetOps::used(flipFaceFlux_));
|
||||
@ -390,4 +412,28 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
|
||||
(
|
||||
autoPtr<Type>& newMeshPtr,
|
||||
const IOobject& io,
|
||||
const polyMesh& mesh,
|
||||
const bool syncParallel,
|
||||
const bool orderCells,
|
||||
const bool orderPoints
|
||||
)
|
||||
{
|
||||
return makeMesh
|
||||
(
|
||||
newMeshPtr,
|
||||
io,
|
||||
mesh,
|
||||
identity(mesh.boundaryMesh().size()),
|
||||
syncParallel,
|
||||
orderCells,
|
||||
orderPoints
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
Reference in New Issue
Block a user