mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'master' of ssh://noisy/home/noisy3/OpenFOAM/OpenFOAM-dev
This commit is contained in:
3
applications/test/globalMeshData/Make/files
Normal file
3
applications/test/globalMeshData/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
globalMeshDataTest.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/globalMeshDataTest
|
||||||
3
applications/test/globalMeshData/Make/options
Normal file
3
applications/test/globalMeshData/Make/options
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
EXE_INC =
|
||||||
|
|
||||||
|
EXE_LIBS =
|
||||||
221
applications/test/globalMeshData/globalMeshDataTest.C
Normal file
221
applications/test/globalMeshData/globalMeshDataTest.C
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Application
|
||||||
|
globalMeshDataTest
|
||||||
|
|
||||||
|
Description
|
||||||
|
Test global point communication
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "globalMeshData.H"
|
||||||
|
#include "argList.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "mapDistribute.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Main program:
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
# include "setRootCase.H"
|
||||||
|
# include "createTime.H"
|
||||||
|
# include "createPolyMesh.H"
|
||||||
|
|
||||||
|
const globalMeshData& globalData = mesh.globalData();
|
||||||
|
const indirectPrimitivePatch& coupledPatch = globalData.coupledPatch();
|
||||||
|
|
||||||
|
|
||||||
|
// Test:print shared points
|
||||||
|
{
|
||||||
|
const labelListList& globalPointSlaves =
|
||||||
|
globalData.globalPointSlaves();
|
||||||
|
const mapDistribute& globalPointSlavesMap =
|
||||||
|
globalData.globalPointSlavesMap();
|
||||||
|
|
||||||
|
pointField coords(globalPointSlavesMap.constructSize());
|
||||||
|
SubList<point>(coords, coupledPatch.nPoints()).assign
|
||||||
|
(
|
||||||
|
coupledPatch.localPoints()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Exchange data
|
||||||
|
globalPointSlavesMap.distribute(coords);
|
||||||
|
|
||||||
|
// Print
|
||||||
|
forAll(globalPointSlaves, pointI)
|
||||||
|
{
|
||||||
|
const labelList& slavePoints = globalPointSlaves[pointI];
|
||||||
|
|
||||||
|
if (slavePoints.size() > 0)
|
||||||
|
{
|
||||||
|
Pout<< "Master point:" << pointI
|
||||||
|
<< " coord:" << coords[pointI]
|
||||||
|
<< " connected to slave points:" << endl;
|
||||||
|
|
||||||
|
forAll(slavePoints, i)
|
||||||
|
{
|
||||||
|
Pout<< " " << coords[slavePoints[i]] << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Test: point to faces addressing
|
||||||
|
{
|
||||||
|
const labelListList& globalPointBoundaryFaces =
|
||||||
|
globalData.globalPointBoundaryFaces();
|
||||||
|
const mapDistribute& globalPointBoundaryFacesMap =
|
||||||
|
globalData.globalPointBoundaryFacesMap();
|
||||||
|
|
||||||
|
label nBnd = mesh.nFaces()-mesh.nInternalFaces();
|
||||||
|
|
||||||
|
pointField fc(globalPointBoundaryFacesMap.constructSize());
|
||||||
|
SubList<point>(fc, nBnd).assign
|
||||||
|
(
|
||||||
|
primitivePatch
|
||||||
|
(
|
||||||
|
SubList<face>
|
||||||
|
(
|
||||||
|
mesh.faces(),
|
||||||
|
nBnd,
|
||||||
|
mesh.nInternalFaces()
|
||||||
|
),
|
||||||
|
mesh.points()
|
||||||
|
).faceCentres()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Exchange data
|
||||||
|
globalPointBoundaryFacesMap.distribute(fc);
|
||||||
|
|
||||||
|
// Print
|
||||||
|
forAll(globalPointBoundaryFaces, pointI)
|
||||||
|
{
|
||||||
|
const labelList& bFaces = globalPointBoundaryFaces[pointI];
|
||||||
|
|
||||||
|
Pout<< "Point:" << pointI
|
||||||
|
<< " at:" << coupledPatch.localPoints()[pointI]
|
||||||
|
<< " connected to faces:" << endl;
|
||||||
|
|
||||||
|
forAll(bFaces, i)
|
||||||
|
{
|
||||||
|
Pout<< " " << fc[bFaces[i]] << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Test:point to cells addressing
|
||||||
|
{
|
||||||
|
const labelList& boundaryCells = globalData.boundaryCells();
|
||||||
|
const labelListList& globalPointBoundaryCells =
|
||||||
|
globalData.globalPointBoundaryCells();
|
||||||
|
const mapDistribute& globalPointBoundaryCellsMap =
|
||||||
|
globalData.globalPointBoundaryCellsMap();
|
||||||
|
|
||||||
|
pointField cc(globalPointBoundaryCellsMap.constructSize());
|
||||||
|
forAll(boundaryCells, i)
|
||||||
|
{
|
||||||
|
cc[i] = mesh.cellCentres()[boundaryCells[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exchange data
|
||||||
|
globalPointBoundaryCellsMap.distribute(cc);
|
||||||
|
|
||||||
|
// Print
|
||||||
|
forAll(globalPointBoundaryCells, pointI)
|
||||||
|
{
|
||||||
|
const labelList& bCells = globalPointBoundaryCells[pointI];
|
||||||
|
|
||||||
|
Pout<< "Point:" << pointI
|
||||||
|
<< " at:" << coupledPatch.localPoints()[pointI]
|
||||||
|
<< " connected to cells:" << endl;
|
||||||
|
|
||||||
|
forAll(bCells, i)
|
||||||
|
{
|
||||||
|
Pout<< " " << cc[bCells[i]] << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Test:print shared edges
|
||||||
|
{
|
||||||
|
const labelListList& globalEdgeSlaves =
|
||||||
|
globalData.globalEdgeSlaves();
|
||||||
|
const mapDistribute& globalEdgeSlavesMap =
|
||||||
|
globalData.globalEdgeSlavesMap();
|
||||||
|
|
||||||
|
// Test: distribute edge centres
|
||||||
|
pointField ec(globalEdgeSlavesMap.constructSize());
|
||||||
|
forAll(coupledPatch.edges(), edgeI)
|
||||||
|
{
|
||||||
|
ec[edgeI] = coupledPatch.edges()[edgeI].centre
|
||||||
|
(
|
||||||
|
coupledPatch.localPoints()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exchange data
|
||||||
|
globalEdgeSlavesMap.distribute(ec);
|
||||||
|
|
||||||
|
// Print
|
||||||
|
forAll(globalEdgeSlaves, edgeI)
|
||||||
|
{
|
||||||
|
const labelList& slaveEdges = globalEdgeSlaves[edgeI];
|
||||||
|
|
||||||
|
if (slaveEdges.size() > 0)
|
||||||
|
{
|
||||||
|
Pout<< "Master edge:" << edgeI
|
||||||
|
<< " centre:" << ec[edgeI]
|
||||||
|
<< " connected to slave edges:" << endl;
|
||||||
|
|
||||||
|
forAll(slaveEdges, i)
|
||||||
|
{
|
||||||
|
Pout<< " " << ec[slaveEdges[i]] << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
3
applications/test/syncTools/Make/files
Normal file
3
applications/test/syncTools/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
syncToolsTest.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/syncToolsTest
|
||||||
1
applications/test/syncTools/Make/options
Normal file
1
applications/test/syncTools/Make/options
Normal file
@ -0,0 +1 @@
|
|||||||
|
EXE_INC =
|
||||||
629
applications/test/syncTools/syncToolsTest.C
Normal file
629
applications/test/syncTools/syncToolsTest.C
Normal file
@ -0,0 +1,629 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Application
|
||||||
|
syncToolsTest
|
||||||
|
|
||||||
|
Description
|
||||||
|
Test some functionality in syncTools.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "argList.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "Random.H"
|
||||||
|
#include "PackedList.H"
|
||||||
|
#include "syncTools.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void testPackedList(const polyMesh& mesh, Random& rndGen)
|
||||||
|
{
|
||||||
|
Info<< nl << "Testing PackedList synchronisation." << endl;
|
||||||
|
|
||||||
|
{
|
||||||
|
PackedList<3> bits(mesh.nEdges());
|
||||||
|
forAll(bits, i)
|
||||||
|
{
|
||||||
|
bits.set(i, rndGen.integer(0,3));
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList edgeValues(mesh.nEdges());
|
||||||
|
forAll(bits, i)
|
||||||
|
{
|
||||||
|
edgeValues[i] = bits.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedList<3> maxBits(bits);
|
||||||
|
labelList maxEdgeValues(edgeValues);
|
||||||
|
|
||||||
|
syncTools::syncEdgeList(mesh, bits, minEqOp<unsigned int>(), 0);
|
||||||
|
syncTools::syncEdgeList(mesh, edgeValues, minEqOp<label>(), 0, false);
|
||||||
|
|
||||||
|
syncTools::syncEdgeList(mesh, maxBits, maxEqOp<unsigned int>(), 0);
|
||||||
|
syncTools::syncEdgeList(mesh, maxEdgeValues, maxEqOp<label>(), 0, false);
|
||||||
|
|
||||||
|
forAll(bits, i)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
edgeValues[i] != label(bits.get(i))
|
||||||
|
|| maxEdgeValues[i] != label(maxBits.get(i))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testPackedList()")
|
||||||
|
<< "edge:" << i
|
||||||
|
<< " minlabel:" << edgeValues[i]
|
||||||
|
<< " minbits:" << bits.get(i)
|
||||||
|
<< " maxLabel:" << maxEdgeValues[i]
|
||||||
|
<< " maxBits:" << maxBits.get(i)
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
PackedList<3> bits(mesh.nPoints());
|
||||||
|
forAll(bits, i)
|
||||||
|
{
|
||||||
|
bits.set(i, rndGen.integer(0,3));
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList pointValues(mesh.nPoints());
|
||||||
|
forAll(bits, i)
|
||||||
|
{
|
||||||
|
pointValues[i] = bits.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedList<3> maxBits(bits);
|
||||||
|
labelList maxPointValues(pointValues);
|
||||||
|
|
||||||
|
syncTools::syncPointList(mesh, bits, minEqOp<unsigned int>(), 0);
|
||||||
|
syncTools::syncPointList(mesh, pointValues, minEqOp<label>(), 0, false);
|
||||||
|
|
||||||
|
syncTools::syncPointList(mesh, maxBits, maxEqOp<unsigned int>(), 0);
|
||||||
|
syncTools::syncPointList(mesh, maxPointValues, maxEqOp<label>(), 0, false);
|
||||||
|
|
||||||
|
forAll(bits, i)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
pointValues[i] != label(bits.get(i))
|
||||||
|
|| maxPointValues[i] != label(maxBits.get(i))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testPackedList()")
|
||||||
|
<< "point:" << i
|
||||||
|
<< " minlabel:" << pointValues[i]
|
||||||
|
<< " minbits:" << bits.get(i)
|
||||||
|
<< " maxLabel:" << maxPointValues[i]
|
||||||
|
<< " maxBits:" << maxBits.get(i)
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
PackedList<3> bits(mesh.nFaces());
|
||||||
|
forAll(bits, faceI)
|
||||||
|
{
|
||||||
|
bits.set(faceI, rndGen.integer(0,3));
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList faceValues(mesh.nFaces());
|
||||||
|
forAll(bits, faceI)
|
||||||
|
{
|
||||||
|
faceValues[faceI] = bits.get(faceI);
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedList<3> maxBits(bits);
|
||||||
|
labelList maxFaceValues(faceValues);
|
||||||
|
|
||||||
|
syncTools::syncFaceList(mesh, bits, minEqOp<unsigned int>());
|
||||||
|
syncTools::syncFaceList(mesh, faceValues, minEqOp<label>(), false);
|
||||||
|
|
||||||
|
syncTools::syncFaceList(mesh, maxBits, maxEqOp<unsigned int>());
|
||||||
|
syncTools::syncFaceList(mesh, maxFaceValues, maxEqOp<label>(), false);
|
||||||
|
|
||||||
|
forAll(bits, faceI)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
faceValues[faceI] != label(bits.get(faceI))
|
||||||
|
|| maxFaceValues[faceI] != label(maxBits.get(faceI))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testPackedList()")
|
||||||
|
<< "face:" << faceI
|
||||||
|
<< " minlabel:" << faceValues[faceI]
|
||||||
|
<< " minbits:" << bits.get(faceI)
|
||||||
|
<< " maxLabel:" << maxFaceValues[faceI]
|
||||||
|
<< " maxBits:" << maxBits.get(faceI)
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void testSparseData(const polyMesh& mesh, Random& rndGen)
|
||||||
|
{
|
||||||
|
Info<< nl << "Testing Map synchronisation." << endl;
|
||||||
|
|
||||||
|
primitivePatch allBoundary
|
||||||
|
(
|
||||||
|
SubList<face>
|
||||||
|
(
|
||||||
|
mesh.faces(),
|
||||||
|
mesh.nFaces()-mesh.nInternalFaces(),
|
||||||
|
mesh.nInternalFaces()
|
||||||
|
),
|
||||||
|
mesh.points()
|
||||||
|
);
|
||||||
|
const pointField& localPoints = allBoundary.localPoints();
|
||||||
|
|
||||||
|
const point greatPoint(GREAT, GREAT, GREAT);
|
||||||
|
|
||||||
|
|
||||||
|
// Point data
|
||||||
|
// ~~~~~~~~~~
|
||||||
|
|
||||||
|
{
|
||||||
|
// Create some data. Use slightly perturbed positions.
|
||||||
|
Map<vector> sparseData;
|
||||||
|
pointField fullData(mesh.nPoints(), greatPoint);
|
||||||
|
|
||||||
|
forAll(localPoints, i)
|
||||||
|
{
|
||||||
|
const point pt = localPoints[i] + 1E-4*rndGen.vector01();
|
||||||
|
|
||||||
|
label meshPointI = allBoundary.meshPoints()[i];
|
||||||
|
|
||||||
|
sparseData.insert(meshPointI, pt);
|
||||||
|
fullData[meshPointI] = pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pout<< "sparseData:" << sparseData << endl;
|
||||||
|
|
||||||
|
syncTools::syncPointMap
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
sparseData,
|
||||||
|
minEqOp<vector>(),
|
||||||
|
true // apply separation
|
||||||
|
);
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
fullData,
|
||||||
|
minEqOp<vector>(),
|
||||||
|
greatPoint,
|
||||||
|
true // apply separation
|
||||||
|
);
|
||||||
|
|
||||||
|
// Compare.
|
||||||
|
// 1. Is all fullData also present in sparseData and same value
|
||||||
|
forAll(fullData, meshPointI)
|
||||||
|
{
|
||||||
|
const point& fullPt = fullData[meshPointI];
|
||||||
|
|
||||||
|
if (fullPt != greatPoint)
|
||||||
|
{
|
||||||
|
const point& sparsePt = sparseData[meshPointI];
|
||||||
|
|
||||||
|
if (fullPt != sparsePt)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testSparseData()")
|
||||||
|
<< "point:" << meshPointI
|
||||||
|
<< " full:" << fullPt
|
||||||
|
<< " sparse:" << sparsePt
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Does sparseData contain more?
|
||||||
|
forAllConstIter(Map<vector>, sparseData, iter)
|
||||||
|
{
|
||||||
|
const point& sparsePt = iter();
|
||||||
|
label meshPointI = iter.key();
|
||||||
|
const point& fullPt = fullData[meshPointI];
|
||||||
|
|
||||||
|
if (fullPt != sparsePt)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testSparseData()")
|
||||||
|
<< "point:" << meshPointI
|
||||||
|
<< " full:" << fullPt
|
||||||
|
<< " sparse:" << sparsePt
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Edge data
|
||||||
|
// ~~~~~~~~~
|
||||||
|
|
||||||
|
{
|
||||||
|
// Create some data. Use slightly perturbed positions.
|
||||||
|
EdgeMap<vector> sparseData;
|
||||||
|
pointField fullData(mesh.nEdges(), greatPoint);
|
||||||
|
|
||||||
|
const edgeList& edges = allBoundary.edges();
|
||||||
|
const labelList meshEdges = allBoundary.meshEdges
|
||||||
|
(
|
||||||
|
mesh.edges(),
|
||||||
|
mesh.pointEdges()
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(edges, i)
|
||||||
|
{
|
||||||
|
const edge& e = edges[i];
|
||||||
|
|
||||||
|
const point pt = e.centre(localPoints) + 1E-4*rndGen.vector01();
|
||||||
|
|
||||||
|
label meshEdgeI = meshEdges[i];
|
||||||
|
|
||||||
|
sparseData.insert(mesh.edges()[meshEdgeI], pt);
|
||||||
|
fullData[meshEdgeI] = pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pout<< "sparseData:" << sparseData << endl;
|
||||||
|
|
||||||
|
syncTools::syncEdgeMap
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
sparseData,
|
||||||
|
minEqOp<vector>(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
syncTools::syncEdgeList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
fullData,
|
||||||
|
minEqOp<vector>(),
|
||||||
|
greatPoint,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
// Compare.
|
||||||
|
// 1. Is all fullData also present in sparseData and same value
|
||||||
|
forAll(fullData, meshEdgeI)
|
||||||
|
{
|
||||||
|
const point& fullPt = fullData[meshEdgeI];
|
||||||
|
|
||||||
|
if (fullPt != greatPoint)
|
||||||
|
{
|
||||||
|
const point& sparsePt = sparseData[mesh.edges()[meshEdgeI]];
|
||||||
|
|
||||||
|
if (fullPt != sparsePt)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testSparseData()")
|
||||||
|
<< "edge:" << meshEdgeI
|
||||||
|
<< " points:" << mesh.edges()[meshEdgeI]
|
||||||
|
<< " full:" << fullPt
|
||||||
|
<< " sparse:" << sparsePt
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Does sparseData contain more?
|
||||||
|
forAll(fullData, meshEdgeI)
|
||||||
|
{
|
||||||
|
const edge& e = mesh.edges()[meshEdgeI];
|
||||||
|
|
||||||
|
EdgeMap<vector>::const_iterator iter = sparseData.find(e);
|
||||||
|
|
||||||
|
if (iter != sparseData.end())
|
||||||
|
{
|
||||||
|
const point& sparsePt = iter();
|
||||||
|
const point& fullPt = fullData[meshEdgeI];
|
||||||
|
|
||||||
|
if (fullPt != sparsePt)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testSparseData()")
|
||||||
|
<< "Extra edge:" << meshEdgeI
|
||||||
|
<< " points:" << mesh.edges()[meshEdgeI]
|
||||||
|
<< " full:" << fullPt
|
||||||
|
<< " sparse:" << sparsePt
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void testPointSync(const polyMesh& mesh, Random& rndGen)
|
||||||
|
{
|
||||||
|
Info<< nl << "Testing point-wise data synchronisation." << endl;
|
||||||
|
|
||||||
|
const point greatPoint(GREAT, GREAT, GREAT);
|
||||||
|
|
||||||
|
// Test position.
|
||||||
|
|
||||||
|
{
|
||||||
|
WarningIn("testPointSync()")
|
||||||
|
<< "Position test only correct for cases without cyclics"
|
||||||
|
<< " with shared points." << endl;
|
||||||
|
|
||||||
|
pointField syncedPoints(mesh.points());
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
syncedPoints,
|
||||||
|
minEqOp<point>(),
|
||||||
|
greatPoint,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(syncedPoints, pointI)
|
||||||
|
{
|
||||||
|
if (mag(syncedPoints[pointI] - mesh.points()[pointI]) > SMALL)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testPointSync()")
|
||||||
|
<< "Point " << pointI
|
||||||
|
<< " original location " << mesh.points()[pointI]
|
||||||
|
<< " synced location " << syncedPoints[pointI]
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test masterPoints
|
||||||
|
|
||||||
|
{
|
||||||
|
labelList nMasters(mesh.nPoints(), 0);
|
||||||
|
|
||||||
|
PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh));
|
||||||
|
|
||||||
|
forAll(isMasterPoint, pointI)
|
||||||
|
{
|
||||||
|
if (isMasterPoint[pointI])
|
||||||
|
{
|
||||||
|
nMasters[pointI] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
nMasters,
|
||||||
|
plusEqOp<label>(),
|
||||||
|
0,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(nMasters, pointI)
|
||||||
|
{
|
||||||
|
if (nMasters[pointI] != 1)
|
||||||
|
{
|
||||||
|
//FatalErrorIn("testPointSync()")
|
||||||
|
WarningIn("testPointSync()")
|
||||||
|
<< "Point " << pointI
|
||||||
|
<< " original location " << mesh.points()[pointI]
|
||||||
|
<< " has " << nMasters[pointI]
|
||||||
|
<< " masters."
|
||||||
|
//<< exit(FatalError);
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void testEdgeSync(const polyMesh& mesh, Random& rndGen)
|
||||||
|
{
|
||||||
|
Info<< nl << "Testing edge-wise data synchronisation." << endl;
|
||||||
|
|
||||||
|
const edgeList& edges = mesh.edges();
|
||||||
|
|
||||||
|
const point greatPoint(GREAT, GREAT, GREAT);
|
||||||
|
|
||||||
|
// Test position.
|
||||||
|
|
||||||
|
{
|
||||||
|
WarningIn("testEdgeSync()")
|
||||||
|
<< "Position test only correct for cases without cyclics"
|
||||||
|
<< " with shared edges." << endl;
|
||||||
|
|
||||||
|
pointField syncedMids(edges.size());
|
||||||
|
forAll(syncedMids, edgeI)
|
||||||
|
{
|
||||||
|
syncedMids[edgeI] = edges[edgeI].centre(mesh.points());
|
||||||
|
}
|
||||||
|
syncTools::syncEdgeList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
syncedMids,
|
||||||
|
minEqOp<point>(),
|
||||||
|
greatPoint,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(syncedMids, edgeI)
|
||||||
|
{
|
||||||
|
point eMid = edges[edgeI].centre(mesh.points());
|
||||||
|
|
||||||
|
if (mag(syncedMids[edgeI] - eMid) > SMALL)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testEdgeSync()")
|
||||||
|
<< "Edge " << edgeI
|
||||||
|
<< " original midpoint " << eMid
|
||||||
|
<< " synced location " << syncedMids[edgeI]
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test masterEdges
|
||||||
|
|
||||||
|
{
|
||||||
|
labelList nMasters(edges.size(), 0);
|
||||||
|
|
||||||
|
PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh));
|
||||||
|
|
||||||
|
forAll(isMasterEdge, edgeI)
|
||||||
|
{
|
||||||
|
if (isMasterEdge[edgeI])
|
||||||
|
{
|
||||||
|
nMasters[edgeI] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncTools::syncEdgeList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
nMasters,
|
||||||
|
plusEqOp<label>(),
|
||||||
|
0,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(nMasters, edgeI)
|
||||||
|
{
|
||||||
|
if (nMasters[edgeI] != 1)
|
||||||
|
{
|
||||||
|
//FatalErrorIn("testEdgeSync()")
|
||||||
|
WarningIn("testEdgeSync()")
|
||||||
|
<< "Edge " << edgeI
|
||||||
|
<< " midpoint " << edges[edgeI].centre(mesh.points())
|
||||||
|
<< " has " << nMasters[edgeI]
|
||||||
|
<< " masters."
|
||||||
|
//<< exit(FatalError);
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void testFaceSync(const polyMesh& mesh, Random& rndGen)
|
||||||
|
{
|
||||||
|
Info<< nl << "Testing face-wise data synchronisation." << endl;
|
||||||
|
|
||||||
|
// Test position.
|
||||||
|
|
||||||
|
{
|
||||||
|
pointField syncedFc(mesh.faceCentres());
|
||||||
|
|
||||||
|
syncTools::syncFaceList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
syncedFc,
|
||||||
|
maxEqOp<point>(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(syncedFc, faceI)
|
||||||
|
{
|
||||||
|
if (mag(syncedFc[faceI] - mesh.faceCentres()[faceI]) > SMALL)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testFaceSync()")
|
||||||
|
<< "Face " << faceI
|
||||||
|
<< " original centre " << mesh.faceCentres()[faceI]
|
||||||
|
<< " synced centre " << syncedFc[faceI]
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test masterFaces
|
||||||
|
|
||||||
|
{
|
||||||
|
labelList nMasters(mesh.nFaces(), 0);
|
||||||
|
|
||||||
|
PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
|
||||||
|
|
||||||
|
forAll(isMasterFace, faceI)
|
||||||
|
{
|
||||||
|
if (isMasterFace[faceI])
|
||||||
|
{
|
||||||
|
nMasters[faceI] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncTools::syncFaceList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
nMasters,
|
||||||
|
plusEqOp<label>(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(nMasters, faceI)
|
||||||
|
{
|
||||||
|
if (nMasters[faceI] != 1)
|
||||||
|
{
|
||||||
|
FatalErrorIn("testFaceSync()")
|
||||||
|
<< "Face " << faceI
|
||||||
|
<< " centre " << mesh.faceCentres()[faceI]
|
||||||
|
<< " has " << nMasters[faceI]
|
||||||
|
<< " masters."
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Main program:
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
# include "setRootCase.H"
|
||||||
|
# include "createTime.H"
|
||||||
|
# include "createPolyMesh.H"
|
||||||
|
|
||||||
|
|
||||||
|
Random rndGen(5341*(Pstream::myProcNo()+1));
|
||||||
|
|
||||||
|
|
||||||
|
// Face sync
|
||||||
|
testFaceSync(mesh, rndGen);
|
||||||
|
|
||||||
|
// Edge sync
|
||||||
|
testEdgeSync(mesh, rndGen);
|
||||||
|
|
||||||
|
// Point sync
|
||||||
|
testPointSync(mesh, rndGen);
|
||||||
|
|
||||||
|
// PackedList synchronisation
|
||||||
|
testPackedList(mesh, rndGen);
|
||||||
|
|
||||||
|
// Sparse synchronisation
|
||||||
|
testSparseData(mesh, rndGen);
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -180,6 +180,12 @@ castellatedMeshControls
|
|||||||
// NOTE: This point should never be on a face, always inside a cell, even
|
// NOTE: This point should never be on a face, always inside a cell, even
|
||||||
// after refinement.
|
// after refinement.
|
||||||
locationInMesh (5 0.28 0.43);
|
locationInMesh (5 0.28 0.43);
|
||||||
|
|
||||||
|
|
||||||
|
// Whether any faceZones (as specified in the refinementSurfaces)
|
||||||
|
// are only on the boundary of corresponding cellZones or also allow
|
||||||
|
// free-standing zone faces. Not used if there are no faceZones.
|
||||||
|
allowFreeStandingZoneFaces true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -274,6 +280,7 @@ addLayersControls
|
|||||||
maxThicknessToMedialRatio 0.3;
|
maxThicknessToMedialRatio 0.3;
|
||||||
|
|
||||||
// Angle used to pick up medial axis points
|
// Angle used to pick up medial axis points
|
||||||
|
// Note: changed(corrected) w.r.t 16x! 90 degrees corresponds to 130 in 16x.
|
||||||
minMedianAxisAngle 90;
|
minMedianAxisAngle 90;
|
||||||
|
|
||||||
// Create buffer region for new layer terminations
|
// Create buffer region for new layer terminations
|
||||||
|
|||||||
@ -28,6 +28,7 @@ wmake libso triSurface
|
|||||||
|
|
||||||
# Decomposition methods needed by meshTools
|
# Decomposition methods needed by meshTools
|
||||||
wmake libso parallel/decompositionMethods
|
wmake libso parallel/decompositionMethods
|
||||||
|
wmake libso parallel/metisDecomp
|
||||||
|
|
||||||
wmake libso meshTools
|
wmake libso meshTools
|
||||||
wmake libso finiteVolume
|
wmake libso finiteVolume
|
||||||
|
|||||||
@ -32,6 +32,8 @@ License
|
|||||||
#include "demandDrivenData.H"
|
#include "demandDrivenData.H"
|
||||||
#include "globalPoints.H"
|
#include "globalPoints.H"
|
||||||
//#include "geomGlobalPoints.H"
|
//#include "geomGlobalPoints.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
#include "mapDistribute.H"
|
||||||
#include "labelIOList.H"
|
#include "labelIOList.H"
|
||||||
#include "PackedList.H"
|
#include "PackedList.H"
|
||||||
#include "mergePoints.H"
|
#include "mergePoints.H"
|
||||||
@ -115,24 +117,17 @@ void Foam::globalMeshData::initProcAddr()
|
|||||||
// Given information about locally used edges allocate global shared edges.
|
// Given information about locally used edges allocate global shared edges.
|
||||||
void Foam::globalMeshData::countSharedEdges
|
void Foam::globalMeshData::countSharedEdges
|
||||||
(
|
(
|
||||||
const HashTable<labelList, edge, Hash<edge> >& procSharedEdges,
|
const EdgeMap<labelList>& procSharedEdges,
|
||||||
HashTable<label, edge, Hash<edge> >& globalShared,
|
EdgeMap<label>& globalShared,
|
||||||
label& sharedEdgeI
|
label& sharedEdgeI
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Count occurrences of procSharedEdges in global shared edges table.
|
// Count occurrences of procSharedEdges in global shared edges table.
|
||||||
for
|
forAllConstIter(EdgeMap<labelList>, procSharedEdges, iter)
|
||||||
(
|
|
||||||
HashTable<labelList, edge, Hash<edge> >::const_iterator iter =
|
|
||||||
procSharedEdges.begin();
|
|
||||||
iter != procSharedEdges.end();
|
|
||||||
++iter
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
const edge& e = iter.key();
|
const edge& e = iter.key();
|
||||||
|
|
||||||
HashTable<label, edge, Hash<edge> >::iterator globalFnd =
|
EdgeMap<label>::iterator globalFnd = globalShared.find(e);
|
||||||
globalShared.find(e);
|
|
||||||
|
|
||||||
if (globalFnd == globalShared.end())
|
if (globalFnd == globalShared.end())
|
||||||
{
|
{
|
||||||
@ -189,10 +184,7 @@ void Foam::globalMeshData::calcSharedEdges() const
|
|||||||
// Find edges using shared points. Store correspondence to local edge
|
// Find edges using shared points. Store correspondence to local edge
|
||||||
// numbering. Note that multiple local edges can have the same shared
|
// numbering. Note that multiple local edges can have the same shared
|
||||||
// points! (for cyclics or separated processor patches)
|
// points! (for cyclics or separated processor patches)
|
||||||
HashTable<labelList, edge, Hash<edge> > localShared
|
EdgeMap<labelList> localShared(2*sharedPtAddr.size());
|
||||||
(
|
|
||||||
2*sharedPtAddr.size()
|
|
||||||
);
|
|
||||||
|
|
||||||
const edgeList& edges = mesh_.edges();
|
const edgeList& edges = mesh_.edges();
|
||||||
|
|
||||||
@ -218,7 +210,7 @@ void Foam::globalMeshData::calcSharedEdges() const
|
|||||||
sharedPtAddr[e1Fnd()]
|
sharedPtAddr[e1Fnd()]
|
||||||
);
|
);
|
||||||
|
|
||||||
HashTable<labelList, edge, Hash<edge> >::iterator iter =
|
EdgeMap<labelList>::iterator iter =
|
||||||
localShared.find(sharedEdge);
|
localShared.find(sharedEdge);
|
||||||
|
|
||||||
if (iter == localShared.end())
|
if (iter == localShared.end())
|
||||||
@ -249,7 +241,7 @@ void Foam::globalMeshData::calcSharedEdges() const
|
|||||||
// used). But then this only gets done once so not too bothered about the
|
// used). But then this only gets done once so not too bothered about the
|
||||||
// extra global communication.
|
// extra global communication.
|
||||||
|
|
||||||
HashTable<label, edge, Hash<edge> > globalShared(nGlobalPoints());
|
EdgeMap<label> globalShared(nGlobalPoints());
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
@ -275,10 +267,7 @@ void Foam::globalMeshData::calcSharedEdges() const
|
|||||||
{
|
{
|
||||||
// Receive the edges using shared points from the slave.
|
// Receive the edges using shared points from the slave.
|
||||||
IPstream fromSlave(Pstream::blocking, slave);
|
IPstream fromSlave(Pstream::blocking, slave);
|
||||||
HashTable<labelList, edge, Hash<edge> > procSharedEdges
|
EdgeMap<labelList> procSharedEdges(fromSlave);
|
||||||
(
|
|
||||||
fromSlave
|
|
||||||
);
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
@ -295,17 +284,11 @@ void Foam::globalMeshData::calcSharedEdges() const
|
|||||||
// These were only used once so are not proper shared edges.
|
// These were only used once so are not proper shared edges.
|
||||||
// Remove them.
|
// Remove them.
|
||||||
{
|
{
|
||||||
HashTable<label, edge, Hash<edge> > oldSharedEdges(globalShared);
|
EdgeMap<label> oldSharedEdges(globalShared);
|
||||||
|
|
||||||
globalShared.clear();
|
globalShared.clear();
|
||||||
|
|
||||||
for
|
forAllConstIter(EdgeMap<label>, oldSharedEdges, iter)
|
||||||
(
|
|
||||||
HashTable<label, edge, Hash<edge> >::const_iterator iter =
|
|
||||||
oldSharedEdges.begin();
|
|
||||||
iter != oldSharedEdges.end();
|
|
||||||
++iter
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (iter() != -1)
|
if (iter() != -1)
|
||||||
{
|
{
|
||||||
@ -361,18 +344,11 @@ void Foam::globalMeshData::calcSharedEdges() const
|
|||||||
DynamicList<label> dynSharedEdgeLabels(globalShared.size());
|
DynamicList<label> dynSharedEdgeLabels(globalShared.size());
|
||||||
DynamicList<label> dynSharedEdgeAddr(globalShared.size());
|
DynamicList<label> dynSharedEdgeAddr(globalShared.size());
|
||||||
|
|
||||||
for
|
forAllConstIter(EdgeMap<labelList>, localShared, iter)
|
||||||
(
|
|
||||||
HashTable<labelList, edge, Hash<edge> >::const_iterator iter =
|
|
||||||
localShared.begin();
|
|
||||||
iter != localShared.end();
|
|
||||||
++iter
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
const edge& e = iter.key();
|
const edge& e = iter.key();
|
||||||
|
|
||||||
HashTable<label, edge, Hash<edge> >::const_iterator edgeFnd =
|
EdgeMap<label>::const_iterator edgeFnd = globalShared.find(e);
|
||||||
globalShared.find(e);
|
|
||||||
|
|
||||||
if (edgeFnd != globalShared.end())
|
if (edgeFnd != globalShared.end())
|
||||||
{
|
{
|
||||||
@ -434,6 +410,557 @@ Foam::label Foam::globalMeshData::countCoincidentFaces
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::globalMeshData::calcGlobalPointSlaves() const
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "globalMeshData::calcGlobalPointSlaves() :"
|
||||||
|
<< " calculating coupled master to slave point addressing."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate connected points for master points
|
||||||
|
globalPoints globalData(mesh_, coupledPatch(), true);
|
||||||
|
|
||||||
|
const Map<label>& meshToProcPoint = globalData.meshToProcPoint();
|
||||||
|
|
||||||
|
// Create global numbering for coupled points
|
||||||
|
globalPointNumberingPtr_.reset
|
||||||
|
(
|
||||||
|
new globalIndex(globalData.globalIndices())
|
||||||
|
);
|
||||||
|
const globalIndex& globalIndices = globalPointNumberingPtr_();
|
||||||
|
|
||||||
|
// Create master to slave addressing. Empty for slave points.
|
||||||
|
globalPointSlavesPtr_.reset
|
||||||
|
(
|
||||||
|
new labelListList(coupledPatch().nPoints())
|
||||||
|
);
|
||||||
|
labelListList& globalPointSlaves = globalPointSlavesPtr_();
|
||||||
|
|
||||||
|
forAllConstIter(Map<label>, meshToProcPoint, iter)
|
||||||
|
{
|
||||||
|
label localPointI = iter.key();
|
||||||
|
const labelList& pPoints = globalData.procPoints()[iter()];
|
||||||
|
|
||||||
|
// Am I master?
|
||||||
|
if
|
||||||
|
(
|
||||||
|
globalIndices.isLocal(pPoints[0])
|
||||||
|
&& globalIndices.toLocal(pPoints[0]) == localPointI
|
||||||
|
)
|
||||||
|
{
|
||||||
|
labelList& slaves = globalPointSlaves[localPointI];
|
||||||
|
slaves.setSize(pPoints.size()-1);
|
||||||
|
for (label i = 1; i < pPoints.size(); i++)
|
||||||
|
{
|
||||||
|
slaves[i-1] = pPoints[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create schedule to get information from slaves onto master
|
||||||
|
|
||||||
|
// Construct compact numbering and distribution map.
|
||||||
|
// Changes globalPointSlaves to be indices into compact data
|
||||||
|
|
||||||
|
List<Map<label> > compactMap(Pstream::nProcs());
|
||||||
|
globalPointSlavesMapPtr_.reset
|
||||||
|
(
|
||||||
|
new mapDistribute
|
||||||
|
(
|
||||||
|
globalIndices,
|
||||||
|
globalPointSlaves,
|
||||||
|
compactMap
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "globalMeshData::calcGlobalPointSlaves() :"
|
||||||
|
<< " coupled points:" << coupledPatch().nPoints()
|
||||||
|
<< " additional remote points:"
|
||||||
|
<< globalPointSlavesMapPtr_().constructSize()
|
||||||
|
- coupledPatch().nPoints()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::globalMeshData::calcGlobalEdgeSlaves() const
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "globalMeshData::calcGlobalEdgeSlaves() :"
|
||||||
|
<< " calculating coupled master to slave edge addressing."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelListList& globalPointSlaves = this->globalPointSlaves();
|
||||||
|
const mapDistribute& globalPointSlavesMap = this->globalPointSlavesMap();
|
||||||
|
|
||||||
|
// - Send across connected edges (in global edge addressing)
|
||||||
|
// - Check on receiving side whether edge has same slave edge
|
||||||
|
// on both endpoints.
|
||||||
|
|
||||||
|
// Create global numbering for coupled edges
|
||||||
|
globalEdgeNumberingPtr_.reset
|
||||||
|
(
|
||||||
|
new globalIndex(coupledPatch().nEdges())
|
||||||
|
);
|
||||||
|
const globalIndex& globalIndices = globalEdgeNumberingPtr_();
|
||||||
|
|
||||||
|
// Coupled point to global coupled edges.
|
||||||
|
labelListList globalPointEdges(globalPointSlavesMap.constructSize());
|
||||||
|
|
||||||
|
// Create local version
|
||||||
|
const labelListList& pointEdges = coupledPatch().pointEdges();
|
||||||
|
forAll(pointEdges, pointI)
|
||||||
|
{
|
||||||
|
const labelList& pEdges = pointEdges[pointI];
|
||||||
|
labelList& globalPEdges = globalPointEdges[pointI];
|
||||||
|
globalPEdges.setSize(pEdges.size());
|
||||||
|
forAll(pEdges, i)
|
||||||
|
{
|
||||||
|
globalPEdges[i] = globalIndices.toGlobal(pEdges[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull slave data to master
|
||||||
|
globalPointSlavesMap.distribute(globalPointEdges);
|
||||||
|
|
||||||
|
// Now check on master if any of my edges are also on slave.
|
||||||
|
// This assumes that if slaves have a coupled edge it is also on
|
||||||
|
// the master (otherwise the mesh would be illegal anyway)
|
||||||
|
|
||||||
|
labelHashSet pointEdgeSet;
|
||||||
|
|
||||||
|
const edgeList& edges = coupledPatch().edges();
|
||||||
|
|
||||||
|
// Create master to slave addressing. Empty for slave edges.
|
||||||
|
globalEdgeSlavesPtr_.reset(new labelListList(edges.size()));
|
||||||
|
labelListList& globalEdgeSlaves = globalEdgeSlavesPtr_();
|
||||||
|
|
||||||
|
forAll(edges, edgeI)
|
||||||
|
{
|
||||||
|
const edge& e = edges[edgeI];
|
||||||
|
const labelList& slaves0 = globalPointSlaves[e[0]];
|
||||||
|
const labelList& slaves1 = globalPointSlaves[e[1]];
|
||||||
|
|
||||||
|
// Check for edges that are in both slaves0 and slaves1.
|
||||||
|
pointEdgeSet.clear();
|
||||||
|
forAll(slaves0, i)
|
||||||
|
{
|
||||||
|
const labelList& connectedEdges = globalPointEdges[slaves0[i]];
|
||||||
|
pointEdgeSet.insert(connectedEdges);
|
||||||
|
}
|
||||||
|
forAll(slaves1, i)
|
||||||
|
{
|
||||||
|
const labelList& connectedEdges = globalPointEdges[slaves1[i]];
|
||||||
|
|
||||||
|
forAll(connectedEdges, j)
|
||||||
|
{
|
||||||
|
label globalEdgeI = connectedEdges[j];
|
||||||
|
|
||||||
|
if (pointEdgeSet.found(globalEdgeI))
|
||||||
|
{
|
||||||
|
// Found slave edge.
|
||||||
|
label sz = globalEdgeSlaves[edgeI].size();
|
||||||
|
globalEdgeSlaves[edgeI].setSize(sz+1);
|
||||||
|
globalEdgeSlaves[edgeI][sz] = globalEdgeI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Construct map
|
||||||
|
List<Map<label> > compactMap(Pstream::nProcs());
|
||||||
|
globalEdgeSlavesMapPtr_.reset
|
||||||
|
(
|
||||||
|
new mapDistribute
|
||||||
|
(
|
||||||
|
globalIndices,
|
||||||
|
globalEdgeSlaves,
|
||||||
|
compactMap
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "globalMeshData::calcGlobalEdgeSlaves() :"
|
||||||
|
<< " coupled edge:" << edges.size()
|
||||||
|
<< " additional remote edges:"
|
||||||
|
<< globalEdgeSlavesMapPtr_().constructSize() - edges.size()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate uncoupled boundary faces (without calculating
|
||||||
|
// primitiveMesh::pointFaces())
|
||||||
|
void Foam::globalMeshData::calcPointBoundaryFaces
|
||||||
|
(
|
||||||
|
labelListList& pointBoundaryFaces
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const polyBoundaryMesh& bMesh = mesh_.boundaryMesh();
|
||||||
|
const Map<label>& meshPointMap = coupledPatch().meshPointMap();
|
||||||
|
|
||||||
|
// 1. Count
|
||||||
|
|
||||||
|
labelList nPointFaces(coupledPatch().nPoints(), 0);
|
||||||
|
|
||||||
|
forAll(bMesh, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = bMesh[patchI];
|
||||||
|
|
||||||
|
if (!pp.coupled())
|
||||||
|
{
|
||||||
|
forAll(pp, i)
|
||||||
|
{
|
||||||
|
const face& f = pp[i];
|
||||||
|
|
||||||
|
forAll(f, fp)
|
||||||
|
{
|
||||||
|
Map<label>::const_iterator iter = meshPointMap.find(f[fp]);
|
||||||
|
if (iter != meshPointMap.end())
|
||||||
|
{
|
||||||
|
nPointFaces[iter()]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 2. Size
|
||||||
|
|
||||||
|
pointBoundaryFaces.setSize(coupledPatch().nPoints());
|
||||||
|
forAll(nPointFaces, pointI)
|
||||||
|
{
|
||||||
|
pointBoundaryFaces[pointI].setSize(nPointFaces[pointI]);
|
||||||
|
}
|
||||||
|
nPointFaces = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// 3. Fill
|
||||||
|
|
||||||
|
forAll(bMesh, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = bMesh[patchI];
|
||||||
|
|
||||||
|
if (!pp.coupled())
|
||||||
|
{
|
||||||
|
forAll(pp, i)
|
||||||
|
{
|
||||||
|
const face& f = pp[i];
|
||||||
|
forAll(f, fp)
|
||||||
|
{
|
||||||
|
Map<label>::const_iterator iter = meshPointMap.find(f[fp]);
|
||||||
|
if (iter != meshPointMap.end())
|
||||||
|
{
|
||||||
|
label bFaceI = pp.start() + i - mesh_.nInternalFaces();
|
||||||
|
pointBoundaryFaces[iter()][nPointFaces[iter()]++] =
|
||||||
|
bFaceI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Foam::globalMeshData::calcGlobalPointBoundaryFaces() const
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "globalMeshData::calcGlobalPointBoundaryFaces() :"
|
||||||
|
<< " calculating coupled point to boundary face addressing."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct local point to (uncoupled)boundaryfaces.
|
||||||
|
labelListList pointBoundaryFaces;
|
||||||
|
calcPointBoundaryFaces(pointBoundaryFaces);
|
||||||
|
|
||||||
|
|
||||||
|
// Global indices for boundary faces
|
||||||
|
globalBoundaryFaceNumberingPtr_.reset
|
||||||
|
(
|
||||||
|
new globalIndex(mesh_.nFaces()-mesh_.nInternalFaces())
|
||||||
|
);
|
||||||
|
globalIndex& globalIndices = globalBoundaryFaceNumberingPtr_();
|
||||||
|
|
||||||
|
|
||||||
|
// Convert local boundary faces to global numbering
|
||||||
|
globalPointBoundaryFacesPtr_.reset
|
||||||
|
(
|
||||||
|
new labelListList(globalPointSlavesMap().constructSize())
|
||||||
|
);
|
||||||
|
labelListList& globalPointBoundaryFaces = globalPointBoundaryFacesPtr_();
|
||||||
|
|
||||||
|
forAll(pointBoundaryFaces, pointI)
|
||||||
|
{
|
||||||
|
const labelList& bFaces = pointBoundaryFaces[pointI];
|
||||||
|
labelList& globalFaces = globalPointBoundaryFaces[pointI];
|
||||||
|
globalFaces.setSize(bFaces.size());
|
||||||
|
forAll(bFaces, i)
|
||||||
|
{
|
||||||
|
globalFaces[i] = globalIndices.toGlobal(bFaces[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Pull slave pointBoundaryFaces to master
|
||||||
|
globalPointSlavesMap().distribute(globalPointBoundaryFaces);
|
||||||
|
|
||||||
|
|
||||||
|
// Merge slave labels into master globalPointBoundaryFaces
|
||||||
|
const labelListList& pointSlaves = globalPointSlaves();
|
||||||
|
|
||||||
|
forAll(pointSlaves, pointI)
|
||||||
|
{
|
||||||
|
const labelList& slaves = pointSlaves[pointI];
|
||||||
|
|
||||||
|
if (slaves.size() > 0)
|
||||||
|
{
|
||||||
|
labelList& myBFaces = globalPointBoundaryFaces[pointI];
|
||||||
|
|
||||||
|
forAll(slaves, i)
|
||||||
|
{
|
||||||
|
const labelList& slaveBFaces =
|
||||||
|
globalPointBoundaryFaces[slaves[i]];
|
||||||
|
|
||||||
|
// Add all slaveBFaces. Note that need to check for
|
||||||
|
// uniqueness only in case of cyclics.
|
||||||
|
|
||||||
|
label sz = myBFaces.size();
|
||||||
|
myBFaces.setSize(sz+slaveBFaces.size());
|
||||||
|
forAll(slaveBFaces, j)
|
||||||
|
{
|
||||||
|
label slave = slaveBFaces[j];
|
||||||
|
if (findIndex(SubList<label>(myBFaces, sz), slave) == -1)
|
||||||
|
{
|
||||||
|
myBFaces[sz++] = slave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myBFaces.setSize(sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Copy merged boundaryFaces back from master into slave slot
|
||||||
|
forAll(pointSlaves, pointI)
|
||||||
|
{
|
||||||
|
const labelList& bFaces = globalPointBoundaryFaces[pointI];
|
||||||
|
const labelList& slaves = pointSlaves[pointI];
|
||||||
|
|
||||||
|
forAll(slaves, i)
|
||||||
|
{
|
||||||
|
globalPointBoundaryFaces[slaves[i]] = bFaces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Sync back to slaves.
|
||||||
|
globalPointSlavesMap().reverseDistribute
|
||||||
|
(
|
||||||
|
coupledPatch().nPoints(),
|
||||||
|
globalPointBoundaryFaces
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Construct a map to get the face data directly
|
||||||
|
List<Map<label> > compactMap(Pstream::nProcs());
|
||||||
|
globalPointBoundaryFacesMapPtr_.reset
|
||||||
|
(
|
||||||
|
new mapDistribute
|
||||||
|
(
|
||||||
|
globalIndices,
|
||||||
|
globalPointBoundaryFaces,
|
||||||
|
compactMap
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "globalMeshData::calcGlobalPointBoundaryFaces() :"
|
||||||
|
<< " coupled points:" << coupledPatch().nPoints()
|
||||||
|
<< " local boundary faces:" << globalIndices.localSize()
|
||||||
|
<< " additional remote faces:"
|
||||||
|
<< globalPointBoundaryFacesMapPtr_().constructSize()
|
||||||
|
- globalIndices.localSize()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::globalMeshData::calcGlobalPointBoundaryCells() const
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "globalMeshData::calcGlobalPointBoundaryCells() :"
|
||||||
|
<< " calculating coupled point to boundary cell addressing."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create map of boundary cells and point-cell addressing
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
label bCellI = 0;
|
||||||
|
Map<label> meshCellMap(4*coupledPatch().nPoints());
|
||||||
|
DynamicList<label> cellMap(meshCellMap.size());
|
||||||
|
|
||||||
|
// Create addressing for point to boundary cells (local)
|
||||||
|
labelListList pointBoundaryCells(coupledPatch().nPoints());
|
||||||
|
|
||||||
|
forAll(coupledPatch().meshPoints(), pointI)
|
||||||
|
{
|
||||||
|
label meshPointI = coupledPatch().meshPoints()[pointI];
|
||||||
|
const labelList& pCells = mesh_.pointCells(meshPointI);
|
||||||
|
|
||||||
|
labelList& bCells = pointBoundaryCells[pointI];
|
||||||
|
bCells.setSize(pCells.size());
|
||||||
|
|
||||||
|
forAll(pCells, i)
|
||||||
|
{
|
||||||
|
label cellI = pCells[i];
|
||||||
|
Map<label>::iterator fnd = meshCellMap.find(cellI);
|
||||||
|
|
||||||
|
if (fnd != meshCellMap.end())
|
||||||
|
{
|
||||||
|
bCells[i] = fnd();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meshCellMap.insert(cellI, bCellI);
|
||||||
|
cellMap.append(cellI);
|
||||||
|
bCells[i] = bCellI;
|
||||||
|
bCellI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boundaryCellsPtr_.reset(new labelList());
|
||||||
|
labelList& boundaryCells = boundaryCellsPtr_();
|
||||||
|
boundaryCells.transfer(cellMap.shrink());
|
||||||
|
|
||||||
|
|
||||||
|
// Convert point-cells to global point numbers
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
globalBoundaryCellNumberingPtr_.reset
|
||||||
|
(
|
||||||
|
new globalIndex(boundaryCells.size())
|
||||||
|
);
|
||||||
|
globalIndex& globalIndices = globalBoundaryCellNumberingPtr_();
|
||||||
|
|
||||||
|
|
||||||
|
globalPointBoundaryCellsPtr_.reset
|
||||||
|
(
|
||||||
|
new labelListList(globalPointSlavesMap().constructSize())
|
||||||
|
);
|
||||||
|
labelListList& globalPointBoundaryCells = globalPointBoundaryCellsPtr_();
|
||||||
|
|
||||||
|
forAll(pointBoundaryCells, pointI)
|
||||||
|
{
|
||||||
|
const labelList& pCells = pointBoundaryCells[pointI];
|
||||||
|
labelList& globalCells = globalPointBoundaryCells[pointI];
|
||||||
|
globalCells.setSize(pCells.size());
|
||||||
|
forAll(pCells, i)
|
||||||
|
{
|
||||||
|
globalCells[i] = globalIndices.toGlobal(pCells[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Pull slave pointBoundaryCells to master
|
||||||
|
globalPointSlavesMap().distribute(globalPointBoundaryCells);
|
||||||
|
|
||||||
|
|
||||||
|
// Merge slave labels into master globalPointBoundaryCells
|
||||||
|
const labelListList& pointSlaves = globalPointSlaves();
|
||||||
|
|
||||||
|
forAll(pointSlaves, pointI)
|
||||||
|
{
|
||||||
|
const labelList& slaves = pointSlaves[pointI];
|
||||||
|
|
||||||
|
if (slaves.size() > 0)
|
||||||
|
{
|
||||||
|
labelList& myBCells = globalPointBoundaryCells[pointI];
|
||||||
|
|
||||||
|
forAll(slaves, i)
|
||||||
|
{
|
||||||
|
const labelList& slaveBCells =
|
||||||
|
globalPointBoundaryCells[slaves[i]];
|
||||||
|
|
||||||
|
// Add all slaveBCells. Note that need to check for
|
||||||
|
// uniqueness only in case of cyclics.
|
||||||
|
|
||||||
|
label sz = myBCells.size();
|
||||||
|
myBCells.setSize(sz+slaveBCells.size());
|
||||||
|
forAll(slaveBCells, j)
|
||||||
|
{
|
||||||
|
label slave = slaveBCells[j];
|
||||||
|
if (findIndex(SubList<label>(myBCells, sz), slave) == -1)
|
||||||
|
{
|
||||||
|
myBCells[sz++] = slave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myBCells.setSize(sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Copy merged boundaryCells back from master into slave slot
|
||||||
|
forAll(pointSlaves, pointI)
|
||||||
|
{
|
||||||
|
const labelList& bCells = globalPointBoundaryCells[pointI];
|
||||||
|
const labelList& slaves = pointSlaves[pointI];
|
||||||
|
|
||||||
|
forAll(slaves, i)
|
||||||
|
{
|
||||||
|
globalPointBoundaryCells[slaves[i]] = bCells;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Sync back to slaves.
|
||||||
|
globalPointSlavesMap().reverseDistribute
|
||||||
|
(
|
||||||
|
coupledPatch().nPoints(),
|
||||||
|
globalPointBoundaryCells
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Construct a map to get the cell data directly
|
||||||
|
List<Map<label> > compactMap(Pstream::nProcs());
|
||||||
|
globalPointBoundaryCellsMapPtr_.reset
|
||||||
|
(
|
||||||
|
new mapDistribute
|
||||||
|
(
|
||||||
|
globalIndices,
|
||||||
|
globalPointBoundaryCells,
|
||||||
|
compactMap
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "globalMeshData::calcGlobalPointBoundaryCells() :"
|
||||||
|
<< " coupled points:" << coupledPatch().nPoints()
|
||||||
|
<< " local boundary cells:" << globalIndices.localSize()
|
||||||
|
<< " additional remote cells:"
|
||||||
|
<< globalPointBoundaryCellsMapPtr_().constructSize()
|
||||||
|
- globalIndices.localSize()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// Construct from polyMesh
|
// Construct from polyMesh
|
||||||
@ -511,6 +1038,25 @@ void Foam::globalMeshData::clearOut()
|
|||||||
nGlobalPoints_ = -1;
|
nGlobalPoints_ = -1;
|
||||||
deleteDemandDrivenData(sharedEdgeLabelsPtr_);
|
deleteDemandDrivenData(sharedEdgeLabelsPtr_);
|
||||||
deleteDemandDrivenData(sharedEdgeAddrPtr_);
|
deleteDemandDrivenData(sharedEdgeAddrPtr_);
|
||||||
|
|
||||||
|
coupledPatchPtr_.clear();
|
||||||
|
// Point
|
||||||
|
globalPointNumberingPtr_.clear();
|
||||||
|
globalPointSlavesPtr_.clear();
|
||||||
|
globalPointSlavesMapPtr_.clear();
|
||||||
|
// Edge
|
||||||
|
globalEdgeNumberingPtr_.clear();
|
||||||
|
globalEdgeSlavesPtr_.clear();
|
||||||
|
globalEdgeSlavesMapPtr_.clear();
|
||||||
|
// Face
|
||||||
|
globalBoundaryFaceNumberingPtr_.clear();
|
||||||
|
globalPointBoundaryFacesPtr_.clear();
|
||||||
|
globalPointBoundaryFacesMapPtr_.clear();
|
||||||
|
// Cell
|
||||||
|
boundaryCellsPtr_.clear();
|
||||||
|
globalBoundaryCellNumberingPtr_.clear();
|
||||||
|
globalPointBoundaryCellsPtr_.clear();
|
||||||
|
globalPointBoundaryCellsMapPtr_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -709,6 +1255,203 @@ const Foam::labelList& Foam::globalMeshData::sharedEdgeAddr() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::indirectPrimitivePatch& Foam::globalMeshData::coupledPatch() const
|
||||||
|
{
|
||||||
|
if (!coupledPatchPtr_.valid())
|
||||||
|
{
|
||||||
|
const polyBoundaryMesh& bMesh = mesh_.boundaryMesh();
|
||||||
|
|
||||||
|
label nCoupled = 0;
|
||||||
|
|
||||||
|
forAll(bMesh, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = bMesh[patchI];
|
||||||
|
|
||||||
|
if (pp.coupled())
|
||||||
|
{
|
||||||
|
nCoupled += pp.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
labelList coupledFaces(nCoupled);
|
||||||
|
nCoupled = 0;
|
||||||
|
|
||||||
|
forAll(bMesh, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = bMesh[patchI];
|
||||||
|
|
||||||
|
if (pp.coupled())
|
||||||
|
{
|
||||||
|
label faceI = pp.start();
|
||||||
|
|
||||||
|
forAll(pp, i)
|
||||||
|
{
|
||||||
|
coupledFaces[nCoupled++] = faceI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
coupledPatchPtr_.reset
|
||||||
|
(
|
||||||
|
new indirectPrimitivePatch
|
||||||
|
(
|
||||||
|
IndirectList<face>
|
||||||
|
(
|
||||||
|
mesh_.faces(),
|
||||||
|
coupledFaces
|
||||||
|
),
|
||||||
|
mesh_.points()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "globalMeshData::coupledPatch() :"
|
||||||
|
<< " constructed coupled faces patch:"
|
||||||
|
<< " faces:" << coupledPatchPtr_().size()
|
||||||
|
<< " points:" << coupledPatchPtr_().nPoints()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return coupledPatchPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::globalIndex& Foam::globalMeshData::globalPointNumbering() const
|
||||||
|
{
|
||||||
|
if (!globalPointNumberingPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointSlaves();
|
||||||
|
}
|
||||||
|
return globalPointNumberingPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::labelListList& Foam::globalMeshData::globalPointSlaves() const
|
||||||
|
{
|
||||||
|
if (!globalPointSlavesPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointSlaves();
|
||||||
|
}
|
||||||
|
return globalPointSlavesPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::mapDistribute& Foam::globalMeshData::globalPointSlavesMap() const
|
||||||
|
{
|
||||||
|
if (!globalPointSlavesMapPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointSlaves();
|
||||||
|
}
|
||||||
|
return globalPointSlavesMapPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::globalIndex& Foam::globalMeshData::globalEdgeNumbering() const
|
||||||
|
{
|
||||||
|
if (!globalEdgeNumberingPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalEdgeSlaves();
|
||||||
|
}
|
||||||
|
return globalEdgeNumberingPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::labelListList& Foam::globalMeshData::globalEdgeSlaves() const
|
||||||
|
{
|
||||||
|
if (!globalEdgeSlavesPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalEdgeSlaves();
|
||||||
|
}
|
||||||
|
return globalEdgeSlavesPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::mapDistribute& Foam::globalMeshData::globalEdgeSlavesMap() const
|
||||||
|
{
|
||||||
|
if (!globalEdgeSlavesMapPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalEdgeSlaves();
|
||||||
|
}
|
||||||
|
return globalEdgeSlavesMapPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::globalIndex& Foam::globalMeshData::globalBoundaryFaceNumbering()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if (!globalBoundaryFaceNumberingPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointBoundaryFaces();
|
||||||
|
}
|
||||||
|
return globalBoundaryFaceNumberingPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::labelListList& Foam::globalMeshData::globalPointBoundaryFaces()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if (!globalPointBoundaryFacesPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointBoundaryFaces();
|
||||||
|
}
|
||||||
|
return globalPointBoundaryFacesPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::mapDistribute& Foam::globalMeshData::globalPointBoundaryFacesMap()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if (!globalPointBoundaryFacesMapPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointBoundaryFaces();
|
||||||
|
}
|
||||||
|
return globalPointBoundaryFacesMapPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::labelList& Foam::globalMeshData::boundaryCells() const
|
||||||
|
{
|
||||||
|
if (!boundaryCellsPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointBoundaryCells();
|
||||||
|
}
|
||||||
|
return boundaryCellsPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::globalIndex& Foam::globalMeshData::globalBoundaryCellNumbering()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if (!globalBoundaryCellNumberingPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointBoundaryCells();
|
||||||
|
}
|
||||||
|
return globalBoundaryCellNumberingPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::labelListList& Foam::globalMeshData::globalPointBoundaryCells()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if (!globalPointBoundaryCellsPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointBoundaryCells();
|
||||||
|
}
|
||||||
|
return globalPointBoundaryCellsPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::mapDistribute& Foam::globalMeshData::globalPointBoundaryCellsMap()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if (!globalPointBoundaryCellsMapPtr_.valid())
|
||||||
|
{
|
||||||
|
calcGlobalPointBoundaryCells();
|
||||||
|
}
|
||||||
|
return globalPointBoundaryCellsMapPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::globalMeshData::movePoints(const pointField& newPoints)
|
void Foam::globalMeshData::movePoints(const pointField& newPoints)
|
||||||
{
|
{
|
||||||
// Topology does not change and we don't store any geometry so nothing
|
// Topology does not change and we don't store any geometry so nothing
|
||||||
@ -740,7 +1483,7 @@ void Foam::globalMeshData::updateMesh()
|
|||||||
// Option 1. Topological
|
// Option 1. Topological
|
||||||
{
|
{
|
||||||
// Calculate all shared points. This does all the hard work.
|
// Calculate all shared points. This does all the hard work.
|
||||||
globalPoints parallelPoints(mesh_);
|
globalPoints parallelPoints(mesh_, false);
|
||||||
|
|
||||||
// Copy data out.
|
// Copy data out.
|
||||||
nGlobalPoints_ = parallelPoints.nGlobalPoints();
|
nGlobalPoints_ = parallelPoints.nGlobalPoints();
|
||||||
|
|||||||
@ -74,10 +74,13 @@ SourceFiles
|
|||||||
#ifndef globalMeshData_H
|
#ifndef globalMeshData_H
|
||||||
#define globalMeshData_H
|
#define globalMeshData_H
|
||||||
|
|
||||||
#include "polyMesh.H"
|
//#include "polyMesh.H"
|
||||||
#include "Switch.H"
|
#include "Switch.H"
|
||||||
#include "processorTopology.H"
|
#include "processorTopology.H"
|
||||||
#include "labelPair.H"
|
#include "labelPair.H"
|
||||||
|
#include "indirectPrimitivePatch.H"
|
||||||
|
#include "boundBox.H"
|
||||||
|
#include "IOobject.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -88,7 +91,10 @@ namespace Foam
|
|||||||
|
|
||||||
class globalMeshData;
|
class globalMeshData;
|
||||||
Ostream& operator<<(Ostream&, const globalMeshData&);
|
Ostream& operator<<(Ostream&, const globalMeshData&);
|
||||||
|
class globalIndex;
|
||||||
|
class polyMesh;
|
||||||
|
class mapDistribute;
|
||||||
|
template<class T> class EdgeMap;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class globalMeshData Declaration
|
Class globalMeshData Declaration
|
||||||
@ -194,6 +200,39 @@ class globalMeshData
|
|||||||
mutable labelList* sharedEdgeAddrPtr_;
|
mutable labelList* sharedEdgeAddrPtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Coupled point addressing
|
||||||
|
// This is addressing from coupled point to coupled points,faces,cells
|
||||||
|
// This is a full schedule so includes points only used by two
|
||||||
|
// coupled patches.
|
||||||
|
|
||||||
|
mutable autoPtr<indirectPrimitivePatch> coupledPatchPtr_;
|
||||||
|
|
||||||
|
// Coupled point to coupled points
|
||||||
|
|
||||||
|
mutable autoPtr<globalIndex> globalPointNumberingPtr_;
|
||||||
|
mutable autoPtr<labelListList> globalPointSlavesPtr_;
|
||||||
|
mutable autoPtr<mapDistribute> globalPointSlavesMapPtr_;
|
||||||
|
|
||||||
|
// Coupled edge to coupled edges
|
||||||
|
|
||||||
|
mutable autoPtr<globalIndex> globalEdgeNumberingPtr_;
|
||||||
|
mutable autoPtr<labelListList> globalEdgeSlavesPtr_;
|
||||||
|
mutable autoPtr<mapDistribute> globalEdgeSlavesMapPtr_;
|
||||||
|
|
||||||
|
// Coupled point to boundary faces
|
||||||
|
|
||||||
|
mutable autoPtr<globalIndex> globalBoundaryFaceNumberingPtr_;
|
||||||
|
mutable autoPtr<labelListList> globalPointBoundaryFacesPtr_;
|
||||||
|
mutable autoPtr<mapDistribute> globalPointBoundaryFacesMapPtr_;
|
||||||
|
|
||||||
|
// Coupled point to boundary cells
|
||||||
|
|
||||||
|
mutable autoPtr<labelList> boundaryCellsPtr_;
|
||||||
|
mutable autoPtr<globalIndex> globalBoundaryCellNumberingPtr_;
|
||||||
|
mutable autoPtr<labelListList> globalPointBoundaryCellsPtr_;
|
||||||
|
mutable autoPtr<mapDistribute> globalPointBoundaryCellsMapPtr_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Set up processor patch addressing
|
//- Set up processor patch addressing
|
||||||
@ -202,8 +241,8 @@ class globalMeshData
|
|||||||
//- Helper function for shared edge addressing
|
//- Helper function for shared edge addressing
|
||||||
static void countSharedEdges
|
static void countSharedEdges
|
||||||
(
|
(
|
||||||
const HashTable<labelList, edge, Hash<edge> >& procSharedEdges,
|
const EdgeMap<labelList>&,
|
||||||
HashTable<label, edge, Hash<edge> >&,
|
EdgeMap<label>&,
|
||||||
label&
|
label&
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -217,6 +256,22 @@ class globalMeshData
|
|||||||
const vectorField& separationDist
|
const vectorField& separationDist
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Calculate global point addressing.
|
||||||
|
void calcGlobalPointSlaves() const;
|
||||||
|
|
||||||
|
//- Calculate global edge addressing.
|
||||||
|
void calcGlobalEdgeSlaves() const;
|
||||||
|
|
||||||
|
//- Calculate coupled point to uncoupled boundary faces. Local only.
|
||||||
|
void calcPointBoundaryFaces(labelListList& pointBoundaryFaces) const;
|
||||||
|
|
||||||
|
//- Calculate global point to global boundary face addressing.
|
||||||
|
void calcGlobalPointBoundaryFaces() const;
|
||||||
|
|
||||||
|
//- Calculate global point to global boundary cell addressing.
|
||||||
|
void calcGlobalPointBoundaryCells() const;
|
||||||
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
globalMeshData(const globalMeshData&);
|
globalMeshData(const globalMeshData&);
|
||||||
|
|
||||||
@ -388,6 +443,47 @@ public:
|
|||||||
const labelList& sharedEdgeAddr() const;
|
const labelList& sharedEdgeAddr() const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Global master - slave point communication
|
||||||
|
|
||||||
|
//- Return patch of all coupled faces
|
||||||
|
const indirectPrimitivePatch& coupledPatch() const;
|
||||||
|
|
||||||
|
// Coupled point to coupled points. Coupled points are points on
|
||||||
|
// any coupled patch.
|
||||||
|
|
||||||
|
//- Numbering of coupled points is according to coupledPatch.
|
||||||
|
const globalIndex& globalPointNumbering() const;
|
||||||
|
//- For every coupled point the indices into the field
|
||||||
|
// distributed by below map.
|
||||||
|
const labelListList& globalPointSlaves() const;
|
||||||
|
const mapDistribute& globalPointSlavesMap() const;
|
||||||
|
|
||||||
|
// Coupled edge to coupled edges.
|
||||||
|
|
||||||
|
const globalIndex& globalEdgeNumbering() const;
|
||||||
|
const labelListList& globalEdgeSlaves() const;
|
||||||
|
const mapDistribute& globalEdgeSlavesMap() const;
|
||||||
|
|
||||||
|
// Coupled point to boundary faces. These are uncoupled boundary
|
||||||
|
// faces only but include empty patches.
|
||||||
|
|
||||||
|
//- Numbering of boundary faces is face-mesh.nInternalFaces()
|
||||||
|
const globalIndex& globalBoundaryFaceNumbering() const;
|
||||||
|
const labelListList& globalPointBoundaryFaces() const;
|
||||||
|
const mapDistribute& globalPointBoundaryFacesMap() const;
|
||||||
|
|
||||||
|
// Coupled point to boundary cell
|
||||||
|
|
||||||
|
//- From boundary cell to mesh cell
|
||||||
|
const labelList& boundaryCells() const;
|
||||||
|
|
||||||
|
//- Numbering of boundary cells is according to boundaryCells()
|
||||||
|
const globalIndex& globalBoundaryCellNumbering() const;
|
||||||
|
const labelListList& globalPointBoundaryCells() const;
|
||||||
|
const mapDistribute& globalPointBoundaryCellsMap() const;
|
||||||
|
|
||||||
|
|
||||||
// Edit
|
// Edit
|
||||||
|
|
||||||
//- Update for moving points.
|
//- Update for moving points.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -29,9 +29,8 @@ Description
|
|||||||
Calculates points shared by more than two processor patches or cyclic
|
Calculates points shared by more than two processor patches or cyclic
|
||||||
patches.
|
patches.
|
||||||
|
|
||||||
Is used in globalMeshData. (this info is needed for point-edge
|
Is used in globalMeshData. (this info is needed for point/edge
|
||||||
communication where you do all but these shared points with patch to
|
communication where processor swaps are not enough to exchange data)
|
||||||
patch communication but need to do a reduce on these shared points)
|
|
||||||
|
|
||||||
Works purely topological and using local communication only.
|
Works purely topological and using local communication only.
|
||||||
Needs:
|
Needs:
|
||||||
@ -41,8 +40,8 @@ Description
|
|||||||
- f[0] ordering on patch faces to be ok.
|
- f[0] ordering on patch faces to be ok.
|
||||||
|
|
||||||
Works by constructing equivalence lists for all the points on processor
|
Works by constructing equivalence lists for all the points on processor
|
||||||
patches. These list are procPointList and give processor and meshPoint
|
patches. These list are in globalIndex numbering (so consecutively numbered
|
||||||
label on that processor.
|
per processor)
|
||||||
E.g.
|
E.g.
|
||||||
@verbatim
|
@verbatim
|
||||||
((7 93)(4 731)(3 114))
|
((7 93)(4 731)(3 114))
|
||||||
@ -85,6 +84,9 @@ Description
|
|||||||
endloop until nothing changes.
|
endloop until nothing changes.
|
||||||
|
|
||||||
|
|
||||||
|
Note: the data held is either mesh point labels (construct from mesh only)
|
||||||
|
or patch point labels (construct from mesh and patch).
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
globalPoints.C
|
globalPoints.C
|
||||||
|
|
||||||
@ -95,11 +97,11 @@ SourceFiles
|
|||||||
|
|
||||||
#include "DynamicList.H"
|
#include "DynamicList.H"
|
||||||
#include "Map.H"
|
#include "Map.H"
|
||||||
#include "labelList.H"
|
|
||||||
#include "FixedList.H"
|
|
||||||
#include "primitivePatch.H"
|
#include "primitivePatch.H"
|
||||||
#include "className.H"
|
#include "className.H"
|
||||||
#include "edgeList.H"
|
#include "edgeList.H"
|
||||||
|
#include "globalIndex.H"
|
||||||
|
#include "indirectPrimitivePatch.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -119,30 +121,29 @@ class globalPoints
|
|||||||
{
|
{
|
||||||
// Private classes
|
// Private classes
|
||||||
|
|
||||||
//- Define procPointList as holding a list of meshPoint/processor labels
|
|
||||||
typedef FixedList<label, 2> procPoint;
|
|
||||||
typedef List<procPoint> procPointList;
|
|
||||||
|
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
//- Mesh reference
|
//- Mesh reference
|
||||||
const polyMesh& mesh_;
|
const polyMesh& mesh_;
|
||||||
|
|
||||||
|
//- Global numbering of points
|
||||||
|
globalIndex globalIndices_;
|
||||||
|
|
||||||
//- Sum of points on processor patches (unfiltered, point on 2 patches
|
//- Sum of points on processor patches (unfiltered, point on 2 patches
|
||||||
// counts as 2)
|
// counts as 2)
|
||||||
const label nPatchPoints_;
|
const label nPatchPoints_;
|
||||||
|
|
||||||
//- All points on boundaries and their corresponding connected points
|
//- All points on boundaries and their corresponding connected points
|
||||||
// on other processors.
|
// on other processors.
|
||||||
DynamicList<procPointList> procPoints_;
|
DynamicList<labelList> procPoints_;
|
||||||
|
|
||||||
//- Map from mesh point to index in procPoints
|
//- Map from mesh (or patch) point to index in procPoints
|
||||||
Map<label> meshToProcPoint_;
|
Map<label> meshToProcPoint_;
|
||||||
|
|
||||||
//- Shared points used by this processor (= global point number)
|
//- Shared points used by this processor (= global point number)
|
||||||
labelList sharedPointAddr_;
|
labelList sharedPointAddr_;
|
||||||
|
|
||||||
//- My meshpoints corresponding to the shared points
|
//- My mesh(or patch) points corresponding to the shared points
|
||||||
labelList sharedPointLabels_;
|
labelList sharedPointLabels_;
|
||||||
|
|
||||||
//- Total number of shared points.
|
//- Total number of shared points.
|
||||||
@ -155,56 +156,108 @@ class globalPoints
|
|||||||
// information is collected.
|
// information is collected.
|
||||||
static label countPatchPoints(const polyBoundaryMesh&);
|
static label countPatchPoints(const polyBoundaryMesh&);
|
||||||
|
|
||||||
|
////- Get all faces on coupled patches
|
||||||
|
//static labelListl coupledFaces(const polyBoundaryMesh&);
|
||||||
|
|
||||||
//- Add information about patchPointI in relative indices to send
|
//- Add information about patchPointI in relative indices to send
|
||||||
// buffers (patchFaces, indexInFace etc.)
|
// buffers (patchFaces, indexInFace etc.)
|
||||||
static void addToSend
|
static void addToSend
|
||||||
(
|
(
|
||||||
const primitivePatch&,
|
const primitivePatch&,
|
||||||
const label patchPointI,
|
const label patchPointI,
|
||||||
const procPointList&,
|
const labelList&,
|
||||||
DynamicList<label>& patchFaces,
|
DynamicList<label>& patchFaces,
|
||||||
DynamicList<label>& indexInFace,
|
DynamicList<label>& indexInFace,
|
||||||
DynamicList<procPointList>& allInfo
|
DynamicList<labelList>& allInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Merge info from neighbour into my data
|
//- Merge info from neighbour into my data
|
||||||
static bool mergeInfo
|
static bool mergeInfo
|
||||||
(
|
(
|
||||||
const procPointList& nbrInfo,
|
const labelList& nbrInfo,
|
||||||
procPointList& myInfo
|
labelList& myInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
//- From mesh point to 'local point'. Is the mesh point itself
|
||||||
|
// if meshToPatchPoint is empty.
|
||||||
|
static label meshToLocalPoint
|
||||||
|
(
|
||||||
|
const Map<label>& meshToPatchPoint,
|
||||||
|
const label meshPointI
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Opposite of meshToLocalPoint.
|
||||||
|
static label localToMeshPoint
|
||||||
|
(
|
||||||
|
const labelList& patchToMeshPoint,
|
||||||
|
const label localPointI
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Store (and merge) info for meshPointI
|
//- Store (and merge) info for meshPointI
|
||||||
bool storeInfo(const procPointList& nbrInfo, const label meshPointI);
|
bool storeInfo
|
||||||
|
(
|
||||||
|
const labelList& nbrInfo,
|
||||||
|
const label localPointI
|
||||||
|
);
|
||||||
|
|
||||||
//- Initialize procPoints_ to my patch points. allPoints = true:
|
//- Initialize procPoints_ to my patch points. allPoints = true:
|
||||||
// seed with all patch points, = false: only boundaryPoints().
|
// seed with all patch points, = false: only boundaryPoints().
|
||||||
void initOwnPoints(const bool allPoints, labelHashSet& changedPoints);
|
void initOwnPoints
|
||||||
|
(
|
||||||
|
const Map<label>& meshToPatchPoint,
|
||||||
|
const bool allPoints,
|
||||||
|
labelHashSet& changedPoints
|
||||||
|
);
|
||||||
|
|
||||||
//- Send subset of procPoints to neighbours
|
//- Send subset of procPoints to neighbours
|
||||||
void sendPatchPoints(const labelHashSet& changedPoints) const;
|
void sendPatchPoints
|
||||||
|
(
|
||||||
|
const Map<label>&,
|
||||||
|
PstreamBuffers&,
|
||||||
|
const labelHashSet&
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Receive neighbour points and merge into my procPoints.
|
//- Receive neighbour points and merge into my procPoints.
|
||||||
void receivePatchPoints(labelHashSet& changedPoints);
|
void receivePatchPoints
|
||||||
|
(
|
||||||
|
const Map<label>&,
|
||||||
|
PstreamBuffers&,
|
||||||
|
labelHashSet&
|
||||||
|
);
|
||||||
|
|
||||||
//- Remove entries of size 2 where meshPoint is in provided Map.
|
//- Remove entries of size 2 where meshPoint is in provided Map.
|
||||||
// Used to remove normal face-face connected points.
|
// Used to remove normal face-face connected points.
|
||||||
void remove(const Map<label>&);
|
void remove(const labelList& patchToMeshPoint, const Map<label>&);
|
||||||
|
|
||||||
|
//- Compact out unused elements of procPoints.
|
||||||
|
void compact();
|
||||||
|
|
||||||
//- Get indices of point for which I am master (lowest numbered proc)
|
//- Get indices of point for which I am master (lowest numbered proc)
|
||||||
labelList getMasterPoints() const;
|
labelList getMasterPoints(const labelList& patchToMeshPoint) const;
|
||||||
|
|
||||||
//- Send subset of shared points to neighbours
|
//- Send subset of shared points to neighbours
|
||||||
void sendSharedPoints(const labelList& changedIndices) const;
|
void sendSharedPoints(PstreamBuffers&, const labelList&) const;
|
||||||
|
|
||||||
//- Receive shared points and update subset.
|
//- Receive shared points and update subset.
|
||||||
void receiveSharedPoints(labelList& changedIndices);
|
void receiveSharedPoints
|
||||||
|
(
|
||||||
|
const Map<label>&,
|
||||||
|
PstreamBuffers&,
|
||||||
|
labelList&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Should move into cyclicPolyPatch ordering problem
|
||||||
//- Should move into cyclicPolyPatch but some ordering problem
|
|
||||||
// keeps on giving problems.
|
// keeps on giving problems.
|
||||||
static edgeList coupledPoints(const cyclicPolyPatch&);
|
static edgeList coupledPoints(const cyclicPolyPatch&);
|
||||||
|
|
||||||
|
//- Do all calculations.
|
||||||
|
void calculateSharedPoints
|
||||||
|
(
|
||||||
|
const Map<label>&,
|
||||||
|
const labelList&,
|
||||||
|
const bool keepAllPoints
|
||||||
|
);
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
globalPoints(const globalPoints&);
|
globalPoints(const globalPoints&);
|
||||||
|
|
||||||
@ -220,36 +273,59 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from mesh
|
//- Construct from mesh.
|
||||||
globalPoints(const polyMesh& mesh);
|
// keepAllPoints = false : filter out points that are on two
|
||||||
|
// neighbouring coupled patches (so can be swapped)
|
||||||
|
globalPoints(const polyMesh& mesh, const bool keepAllPoints);
|
||||||
|
|
||||||
|
//- Construct from mesh and patch of coupled faces. Difference with
|
||||||
|
// construct from mesh only is that this stores the meshToProcPoint,
|
||||||
|
// procPoints and sharedPointLabels as patch local point labels
|
||||||
|
// instead of mesh point labels.
|
||||||
|
globalPoints
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const indirectPrimitivePatch& coupledPatch,
|
||||||
|
const bool keepAllPoints
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
// Access
|
// Access
|
||||||
|
|
||||||
label nPatchPoints() const
|
//- From (mesh or patch) point to index in procPoints
|
||||||
{
|
|
||||||
return nPatchPoints_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Map<label>& meshToProcPoint() const
|
const Map<label>& meshToProcPoint() const
|
||||||
{
|
{
|
||||||
return meshToProcPoint_;
|
return meshToProcPoint_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- procPoints is per point the connected points (in global
|
||||||
|
// point numbers)
|
||||||
|
const DynamicList<labelList>& procPoints() const
|
||||||
|
{
|
||||||
|
return procPoints_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Global numbering of (mesh or patch) points
|
||||||
|
const globalIndex& globalIndices() const
|
||||||
|
{
|
||||||
|
return globalIndices_;
|
||||||
|
}
|
||||||
|
|
||||||
//- shared points used by this processor (= global point number)
|
//- shared points used by this processor (= global point number)
|
||||||
const labelList& sharedPointAddr() const
|
const labelList& sharedPointAddr() const
|
||||||
{
|
{
|
||||||
return sharedPointAddr_;
|
return sharedPointAddr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- my meshpoints corresponding to the shared points
|
//- my (mesh or patch)points corresponding to the shared points
|
||||||
const labelList& sharedPointLabels() const
|
const labelList& sharedPointLabels() const
|
||||||
{
|
{
|
||||||
return sharedPointLabels_;
|
return sharedPointLabels_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- total number of shared points
|
||||||
label nGlobalPoints() const
|
label nGlobalPoints() const
|
||||||
{
|
{
|
||||||
return nGlobalPoints_;
|
return nGlobalPoints_;
|
||||||
|
|||||||
@ -288,6 +288,7 @@ Foam::mapDistribute::mapDistribute
|
|||||||
|
|
||||||
forAll(compactMap, procI)
|
forAll(compactMap, procI)
|
||||||
{
|
{
|
||||||
|
compactMap[procI].clear();
|
||||||
if (procI != Pstream::myProcNo())
|
if (procI != Pstream::myProcNo())
|
||||||
{
|
{
|
||||||
compactMap[procI].resize(2*nNonLocal[procI]);
|
compactMap[procI].resize(2*nNonLocal[procI]);
|
||||||
@ -433,6 +434,7 @@ Foam::mapDistribute::mapDistribute
|
|||||||
|
|
||||||
forAll(compactMap, procI)
|
forAll(compactMap, procI)
|
||||||
{
|
{
|
||||||
|
compactMap[procI].clear();
|
||||||
if (procI != Pstream::myProcNo())
|
if (procI != Pstream::myProcNo())
|
||||||
{
|
{
|
||||||
compactMap[procI].resize(2*nNonLocal[procI]);
|
compactMap[procI].resize(2*nNonLocal[procI]);
|
||||||
|
|||||||
@ -276,6 +276,49 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Reverse distribute data using default commsType.
|
||||||
|
template<class T>
|
||||||
|
void reverseDistribute(const label constructSize, List<T>& fld)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if (Pstream::defaultCommsType == Pstream::nonBlocking)
|
||||||
|
{
|
||||||
|
distribute
|
||||||
|
(
|
||||||
|
Pstream::nonBlocking,
|
||||||
|
List<labelPair>(),
|
||||||
|
constructSize,
|
||||||
|
constructMap_,
|
||||||
|
subMap_,
|
||||||
|
fld
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (Pstream::defaultCommsType == Pstream::scheduled)
|
||||||
|
{
|
||||||
|
distribute
|
||||||
|
(
|
||||||
|
Pstream::scheduled,
|
||||||
|
schedule(),
|
||||||
|
constructSize,
|
||||||
|
constructMap_,
|
||||||
|
subMap_,
|
||||||
|
fld
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
distribute
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
List<labelPair>(),
|
||||||
|
constructSize,
|
||||||
|
constructMap_,
|
||||||
|
subMap_,
|
||||||
|
fld
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//- Correct for topo change.
|
//- Correct for topo change.
|
||||||
void updateMesh(const mapPolyMesh&)
|
void updateMesh(const mapPolyMesh&)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -552,7 +552,6 @@ void Foam::mapDistribute::distribute
|
|||||||
{
|
{
|
||||||
if (!contiguous<T>())
|
if (!contiguous<T>())
|
||||||
{
|
{
|
||||||
//XXXXXX
|
|
||||||
PstreamBuffers pBuffs(Pstream::nonBlocking);
|
PstreamBuffers pBuffs(Pstream::nonBlocking);
|
||||||
|
|
||||||
// Stream data into buffer
|
// Stream data into buffer
|
||||||
|
|||||||
@ -26,7 +26,7 @@ Class
|
|||||||
Foam::syncTools
|
Foam::syncTools
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Various tools to aid synchronizing lists across coupled patches.
|
Various tools to aid synchronizing lists across coupled patches. WIP.
|
||||||
|
|
||||||
Require
|
Require
|
||||||
- combineOperator (e.g. sumEqOp - not sumOp!) that is defined for the
|
- combineOperator (e.g. sumEqOp - not sumOp!) that is defined for the
|
||||||
@ -34,8 +34,11 @@ Description
|
|||||||
- null value which gets overridden by any valid value.
|
- null value which gets overridden by any valid value.
|
||||||
- transform function
|
- transform function
|
||||||
|
|
||||||
Can apply coordinate rotation/separation on cyclics but only for faces
|
note:Can apply coordinate rotation/separation on cyclics but only for faces
|
||||||
or if there is a single rotation/separation tensor.
|
or if there is a single rotation/separation tensor.
|
||||||
|
note:syncPointList or syncEdgeList will visit shared points/edges
|
||||||
|
multiple times (once through patch exchange, once through shared
|
||||||
|
points reduce). Should be replaced by pointMesh functionality.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
syncTools.C
|
syncTools.C
|
||||||
|
|||||||
@ -55,7 +55,7 @@ slicedFvPatchField<Type>::slicedFvPatchField
|
|||||||
const DimensionedField<Type, volMesh>& iF
|
const DimensionedField<Type, volMesh>& iF
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
fvPatchField<Type>(p, iF)
|
fvPatchField<Type>(p, iF, Field<Type>())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@ EXE_INC = \
|
|||||||
-I$(LIB_SRC)/triSurface/lnInclude
|
-I$(LIB_SRC)/triSurface/lnInclude
|
||||||
|
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-ldecompositionMethods \
|
|
||||||
-ldynamicMesh \
|
-ldynamicMesh \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
-llagrangian \
|
-llagrangian \
|
||||||
|
|||||||
@ -1506,8 +1506,12 @@ void Foam::autoSnapDriver::doSnap
|
|||||||
// meshMover.
|
// meshMover.
|
||||||
calcNearestSurface(snapDist, meshMover);
|
calcNearestSurface(snapDist, meshMover);
|
||||||
|
|
||||||
// Get smoothly varying internal displacement field.
|
//// Get smoothly varying internal displacement field.
|
||||||
smoothDisplacement(snapParams, meshMover);
|
//- 2009-12-16 : was not found to be beneficial. Keeping internal
|
||||||
|
// fields fixed slightly increases skewness (on boundary)
|
||||||
|
// but lowers non-orthogonality quite a bit (e.g. 65->59 degrees).
|
||||||
|
// Maybe if better smoother?
|
||||||
|
//smoothDisplacement(snapParams, meshMover);
|
||||||
|
|
||||||
// Apply internal displacement to mesh.
|
// Apply internal displacement to mesh.
|
||||||
scaleMesh(snapParams, nInitErrors, baffles, meshMover);
|
scaleMesh(snapParams, nInitErrors, baffles, meshMover);
|
||||||
|
|||||||
@ -6,4 +6,5 @@ EXE_INC = \
|
|||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-ltriSurface \
|
-ltriSurface \
|
||||||
-ldecompositionMethods \
|
-ldecompositionMethods \
|
||||||
|
-lmetisDecompositionMethod \
|
||||||
-llagrangian
|
-llagrangian
|
||||||
|
|||||||
@ -3,6 +3,7 @@ cd ${0%/*} || exit 1 # run from this directory
|
|||||||
set -x
|
set -x
|
||||||
|
|
||||||
wmake libso decompositionMethods
|
wmake libso decompositionMethods
|
||||||
|
wmake libso metisDecomp
|
||||||
wmake libso reconstruct
|
wmake libso reconstruct
|
||||||
|
|
||||||
if [ -d "$FOAM_MPI_LIBBIN" ]
|
if [ -d "$FOAM_MPI_LIBBIN" ]
|
||||||
|
|||||||
@ -6,6 +6,4 @@ manualDecomp/manualDecomp.C
|
|||||||
|
|
||||||
scotchDecomp/scotchDecomp.C
|
scotchDecomp/scotchDecomp.C
|
||||||
|
|
||||||
metisDecomp/metisDecomp.C
|
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libdecompositionMethods
|
LIB = $(FOAM_LIBBIN)/libdecompositionMethods
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(WM_THIRD_PARTY_DIR)/scotch_5.1/src/libscotch/lnInclude \
|
-I$(WM_THIRD_PARTY_DIR)/scotch_5.1/include \
|
||||||
-I$(WM_THIRD_PARTY_DIR)/metis-5.0pre2/include
|
-I../metisDecomp/lnInclude
|
||||||
|
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-lscotch \
|
-lscotch -lscotcherrexit
|
||||||
-lmetis \
|
|
||||||
-lGKlib
|
|
||||||
|
|||||||
@ -61,17 +61,12 @@ License
|
|||||||
#include "scotchDecomp.H"
|
#include "scotchDecomp.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "floatScalar.H"
|
#include "floatScalar.H"
|
||||||
#include "IFstream.H"
|
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "cyclicPolyPatch.H"
|
#include "cyclicPolyPatch.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
#include "metisDecomp.H"
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#define OMPI_SKIP_MPICXX
|
|
||||||
#include "module.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "scotch.h"
|
#include "scotch.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,13 +110,13 @@ void Foam::scotchDecomp::check(const int retVal, const char* str)
|
|||||||
if (retVal)
|
if (retVal)
|
||||||
{
|
{
|
||||||
FatalErrorIn("scotchDecomp::decompose(..)")
|
FatalErrorIn("scotchDecomp::decompose(..)")
|
||||||
<< "Called to scotch routine " << str << " failed."
|
<< "Call to scotch routine " << str << " failed."
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Call Metis with options from dictionary.
|
// Call scotch with options from dictionary.
|
||||||
Foam::label Foam::scotchDecomp::decompose
|
Foam::label Foam::scotchDecomp::decompose
|
||||||
(
|
(
|
||||||
const List<int>& adjncy,
|
const List<int>& adjncy,
|
||||||
@ -173,7 +168,7 @@ Foam::label Foam::scotchDecomp::decompose
|
|||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"parMetisDecomp::decompose"
|
"scotchDecomp::decompose"
|
||||||
"(const pointField&, const scalarField&)"
|
"(const pointField&, const scalarField&)"
|
||||||
) << "Number of cell weights " << cWeights.size()
|
) << "Number of cell weights " << cWeights.size()
|
||||||
<< " does not equal number of cells " << xadj.size()-1
|
<< " does not equal number of cells " << xadj.size()-1
|
||||||
@ -377,7 +372,10 @@ Foam::labelList Foam::scotchDecomp::decompose
|
|||||||
{
|
{
|
||||||
if (points.size() != mesh_.nCells())
|
if (points.size() != mesh_.nCells())
|
||||||
{
|
{
|
||||||
FatalErrorIn("scotchDecomp::decompose(const pointField&)")
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"scotchDecomp::decompose(const pointField&, const scalarField&)"
|
||||||
|
)
|
||||||
<< "Can use this decomposition method only for the whole mesh"
|
<< "Can use this decomposition method only for the whole mesh"
|
||||||
<< endl
|
<< endl
|
||||||
<< "and supply one coordinate (cellCentre) for every cell." << endl
|
<< "and supply one coordinate (cellCentre) for every cell." << endl
|
||||||
@ -391,12 +389,7 @@ Foam::labelList Foam::scotchDecomp::decompose
|
|||||||
// xadj(celli) : start of information in adjncy for celli
|
// xadj(celli) : start of information in adjncy for celli
|
||||||
List<int> adjncy;
|
List<int> adjncy;
|
||||||
List<int> xadj;
|
List<int> xadj;
|
||||||
metisDecomp::calcMetisCSR
|
calcCSR(mesh_, adjncy, xadj);
|
||||||
(
|
|
||||||
mesh_,
|
|
||||||
adjncy,
|
|
||||||
xadj
|
|
||||||
);
|
|
||||||
|
|
||||||
// Decompose using default weights
|
// Decompose using default weights
|
||||||
List<int> finalDecomp;
|
List<int> finalDecomp;
|
||||||
@ -445,7 +438,7 @@ Foam::labelList Foam::scotchDecomp::decompose
|
|||||||
cellCells
|
cellCells
|
||||||
);
|
);
|
||||||
|
|
||||||
metisDecomp::calcMetisCSR(cellCells, adjncy, xadj);
|
calcCSR(cellCells, adjncy, xadj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decompose using weights
|
// Decompose using weights
|
||||||
@ -475,7 +468,8 @@ Foam::labelList Foam::scotchDecomp::decompose
|
|||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"scotchDecomp::decompose(const pointField&, const labelListList&)"
|
"scotchDecomp::decompose"
|
||||||
|
"(const labelListList&, const pointField&, const scalarField&)"
|
||||||
) << "Inconsistent number of cells (" << globalCellCells.size()
|
) << "Inconsistent number of cells (" << globalCellCells.size()
|
||||||
<< ") and number of cell centres (" << cellCentres.size()
|
<< ") and number of cell centres (" << cellCentres.size()
|
||||||
<< ")." << exit(FatalError);
|
<< ")." << exit(FatalError);
|
||||||
@ -488,7 +482,7 @@ Foam::labelList Foam::scotchDecomp::decompose
|
|||||||
|
|
||||||
List<int> adjncy;
|
List<int> adjncy;
|
||||||
List<int> xadj;
|
List<int> xadj;
|
||||||
metisDecomp::calcMetisCSR(globalCellCells, adjncy, xadj);
|
calcCSR(globalCellCells, adjncy, xadj);
|
||||||
|
|
||||||
// Decompose using weights
|
// Decompose using weights
|
||||||
List<int> finalDecomp;
|
List<int> finalDecomp;
|
||||||
@ -504,4 +498,144 @@ Foam::labelList Foam::scotchDecomp::decompose
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::scotchDecomp::calcCSR
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Make Metis CSR (Compressed Storage Format) storage
|
||||||
|
// adjncy : contains neighbours (= edges in graph)
|
||||||
|
// xadj(celli) : start of information in adjncy for celli
|
||||||
|
|
||||||
|
xadj.setSize(mesh.nCells()+1);
|
||||||
|
|
||||||
|
// Initialise the number of internal faces of the cells to twice the
|
||||||
|
// number of internal faces
|
||||||
|
label nInternalFaces = 2*mesh.nInternalFaces();
|
||||||
|
|
||||||
|
// Check the boundary for coupled patches and add to the number of
|
||||||
|
// internal faces
|
||||||
|
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||||
|
|
||||||
|
forAll(pbm, patchi)
|
||||||
|
{
|
||||||
|
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
||||||
|
{
|
||||||
|
nInternalFaces += pbm[patchi].size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the adjncy array the size of the total number of internal and
|
||||||
|
// coupled faces
|
||||||
|
adjncy.setSize(nInternalFaces);
|
||||||
|
|
||||||
|
// Fill in xadj
|
||||||
|
// ~~~~~~~~~~~~
|
||||||
|
label freeAdj = 0;
|
||||||
|
|
||||||
|
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
||||||
|
{
|
||||||
|
xadj[cellI] = freeAdj;
|
||||||
|
|
||||||
|
const labelList& cFaces = mesh.cells()[cellI];
|
||||||
|
|
||||||
|
forAll(cFaces, i)
|
||||||
|
{
|
||||||
|
label faceI = cFaces[i];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
mesh.isInternalFace(faceI)
|
||||||
|
|| isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
freeAdj++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xadj[mesh.nCells()] = freeAdj;
|
||||||
|
|
||||||
|
|
||||||
|
// Fill in adjncy
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
labelList nFacesPerCell(mesh.nCells(), 0);
|
||||||
|
|
||||||
|
// Internal faces
|
||||||
|
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||||
|
{
|
||||||
|
label own = mesh.faceOwner()[faceI];
|
||||||
|
label nei = mesh.faceNeighbour()[faceI];
|
||||||
|
|
||||||
|
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||||
|
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coupled faces. Only cyclics done.
|
||||||
|
forAll(pbm, patchi)
|
||||||
|
{
|
||||||
|
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
||||||
|
{
|
||||||
|
const unallocLabelList& faceCells = pbm[patchi].faceCells();
|
||||||
|
|
||||||
|
label sizeby2 = faceCells.size()/2;
|
||||||
|
|
||||||
|
for (label facei=0; facei<sizeby2; facei++)
|
||||||
|
{
|
||||||
|
label own = faceCells[facei];
|
||||||
|
label nei = faceCells[facei + sizeby2];
|
||||||
|
|
||||||
|
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||||
|
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// From cell-cell connections to Metis format (like CompactListList)
|
||||||
|
void Foam::scotchDecomp::calcCSR
|
||||||
|
(
|
||||||
|
const labelListList& cellCells,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Count number of internal faces
|
||||||
|
label nConnections = 0;
|
||||||
|
|
||||||
|
forAll(cellCells, coarseI)
|
||||||
|
{
|
||||||
|
nConnections += cellCells[coarseI].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the adjncy array as twice the size of the total number of
|
||||||
|
// internal faces
|
||||||
|
adjncy.setSize(nConnections);
|
||||||
|
|
||||||
|
xadj.setSize(cellCells.size()+1);
|
||||||
|
|
||||||
|
|
||||||
|
// Fill in xadj
|
||||||
|
// ~~~~~~~~~~~~
|
||||||
|
label freeAdj = 0;
|
||||||
|
|
||||||
|
forAll(cellCells, coarseI)
|
||||||
|
{
|
||||||
|
xadj[coarseI] = freeAdj;
|
||||||
|
|
||||||
|
const labelList& cCells = cellCells[coarseI];
|
||||||
|
|
||||||
|
forAll(cCells, i)
|
||||||
|
{
|
||||||
|
adjncy[freeAdj++] = cCells[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xadj[cellCells.size()] = freeAdj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -135,6 +135,25 @@ public:
|
|||||||
const scalarField& cWeights
|
const scalarField& cWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Helper to convert local connectivity (supplied as owner,neighbour)
|
||||||
|
// into CSR (Metis,scotch) storage. Does cyclics but not processor
|
||||||
|
// patches
|
||||||
|
static void calcCSR
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Helper to convert connectivity (supplied as cellcells) into
|
||||||
|
// CSR (Metis,scotch) storage
|
||||||
|
static void calcCSR
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
3
src/parallel/metisDecomp/Make/files
Normal file
3
src/parallel/metisDecomp/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
metisDecomp.C
|
||||||
|
|
||||||
|
LIB = $(FOAM_LIBBIN)/libmetisDecompositionMethod
|
||||||
7
src/parallel/metisDecomp/Make/options
Normal file
7
src/parallel/metisDecomp/Make/options
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
EXE_INC = \
|
||||||
|
-I$(WM_THIRD_PARTY_DIR)/metis-5.0pre2/include \
|
||||||
|
-I../decompositionMethods/lnInclude
|
||||||
|
|
||||||
|
LIB_LIBS = \
|
||||||
|
-lmetis \
|
||||||
|
-lGKlib
|
||||||
@ -27,9 +27,8 @@ License
|
|||||||
#include "metisDecomp.H"
|
#include "metisDecomp.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "floatScalar.H"
|
#include "floatScalar.H"
|
||||||
#include "IFstream.H"
|
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "cyclicPolyPatch.H"
|
#include "scotchDecomp.H"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -331,12 +330,7 @@ Foam::labelList Foam::metisDecomp::decompose
|
|||||||
|
|
||||||
List<int> adjncy;
|
List<int> adjncy;
|
||||||
List<int> xadj;
|
List<int> xadj;
|
||||||
calcMetisCSR
|
scotchDecomp::calcCSR(mesh_, adjncy, xadj);
|
||||||
(
|
|
||||||
mesh_,
|
|
||||||
adjncy,
|
|
||||||
xadj
|
|
||||||
);
|
|
||||||
|
|
||||||
// Decompose using default weights
|
// Decompose using default weights
|
||||||
List<int> finalDecomp;
|
List<int> finalDecomp;
|
||||||
@ -352,145 +346,6 @@ Foam::labelList Foam::metisDecomp::decompose
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::metisDecomp::calcMetisCSR
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Make Metis CSR (Compressed Storage Format) storage
|
|
||||||
// adjncy : contains neighbours (= edges in graph)
|
|
||||||
// xadj(celli) : start of information in adjncy for celli
|
|
||||||
|
|
||||||
xadj.setSize(mesh.nCells()+1);
|
|
||||||
|
|
||||||
// Initialise the number of internal faces of the cells to twice the
|
|
||||||
// number of internal faces
|
|
||||||
label nInternalFaces = 2*mesh.nInternalFaces();
|
|
||||||
|
|
||||||
// Check the boundary for coupled patches and add to the number of
|
|
||||||
// internal faces
|
|
||||||
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
|
||||||
|
|
||||||
forAll(pbm, patchi)
|
|
||||||
{
|
|
||||||
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
|
||||||
{
|
|
||||||
nInternalFaces += pbm[patchi].size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the adjncy array the size of the total number of internal and
|
|
||||||
// coupled faces
|
|
||||||
adjncy.setSize(nInternalFaces);
|
|
||||||
|
|
||||||
// Fill in xadj
|
|
||||||
// ~~~~~~~~~~~~
|
|
||||||
label freeAdj = 0;
|
|
||||||
|
|
||||||
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
|
||||||
{
|
|
||||||
xadj[cellI] = freeAdj;
|
|
||||||
|
|
||||||
const labelList& cFaces = mesh.cells()[cellI];
|
|
||||||
|
|
||||||
forAll(cFaces, i)
|
|
||||||
{
|
|
||||||
label faceI = cFaces[i];
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
mesh.isInternalFace(faceI)
|
|
||||||
|| isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)])
|
|
||||||
)
|
|
||||||
{
|
|
||||||
freeAdj++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xadj[mesh.nCells()] = freeAdj;
|
|
||||||
|
|
||||||
|
|
||||||
// Fill in adjncy
|
|
||||||
// ~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
labelList nFacesPerCell(mesh.nCells(), 0);
|
|
||||||
|
|
||||||
// Internal faces
|
|
||||||
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
|
||||||
{
|
|
||||||
label own = mesh.faceOwner()[faceI];
|
|
||||||
label nei = mesh.faceNeighbour()[faceI];
|
|
||||||
|
|
||||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
|
||||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Coupled faces. Only cyclics done.
|
|
||||||
forAll(pbm, patchi)
|
|
||||||
{
|
|
||||||
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
|
||||||
{
|
|
||||||
const unallocLabelList& faceCells = pbm[patchi].faceCells();
|
|
||||||
|
|
||||||
label sizeby2 = faceCells.size()/2;
|
|
||||||
|
|
||||||
for (label facei=0; facei<sizeby2; facei++)
|
|
||||||
{
|
|
||||||
label own = faceCells[facei];
|
|
||||||
label nei = faceCells[facei + sizeby2];
|
|
||||||
|
|
||||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
|
||||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// From cell-cell connections to Metis format (like CompactListList)
|
|
||||||
void Foam::metisDecomp::calcMetisCSR
|
|
||||||
(
|
|
||||||
const labelListList& cellCells,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Count number of internal faces
|
|
||||||
label nConnections = 0;
|
|
||||||
|
|
||||||
forAll(cellCells, coarseI)
|
|
||||||
{
|
|
||||||
nConnections += cellCells[coarseI].size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the adjncy array as twice the size of the total number of
|
|
||||||
// internal faces
|
|
||||||
adjncy.setSize(nConnections);
|
|
||||||
|
|
||||||
xadj.setSize(cellCells.size()+1);
|
|
||||||
|
|
||||||
|
|
||||||
// Fill in xadj
|
|
||||||
// ~~~~~~~~~~~~
|
|
||||||
label freeAdj = 0;
|
|
||||||
|
|
||||||
forAll(cellCells, coarseI)
|
|
||||||
{
|
|
||||||
xadj[coarseI] = freeAdj;
|
|
||||||
|
|
||||||
const labelList& cCells = cellCells[coarseI];
|
|
||||||
|
|
||||||
forAll(cCells, i)
|
|
||||||
{
|
|
||||||
adjncy[freeAdj++] = cCells[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xadj[cellCells.size()] = freeAdj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::labelList Foam::metisDecomp::decompose
|
Foam::labelList Foam::metisDecomp::decompose
|
||||||
(
|
(
|
||||||
const labelList& agglom,
|
const labelList& agglom,
|
||||||
@ -525,7 +380,7 @@ Foam::labelList Foam::metisDecomp::decompose
|
|||||||
cellCells
|
cellCells
|
||||||
);
|
);
|
||||||
|
|
||||||
calcMetisCSR(cellCells, adjncy, xadj);
|
scotchDecomp::calcCSR(cellCells, adjncy, xadj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decompose using default weights
|
// Decompose using default weights
|
||||||
@ -570,7 +425,7 @@ Foam::labelList Foam::metisDecomp::decompose
|
|||||||
|
|
||||||
List<int> adjncy;
|
List<int> adjncy;
|
||||||
List<int> xadj;
|
List<int> xadj;
|
||||||
calcMetisCSR(globalCellCells, adjncy, xadj);
|
scotchDecomp::calcCSR(globalCellCells, adjncy, xadj);
|
||||||
|
|
||||||
|
|
||||||
// Decompose using default weights
|
// Decompose using default weights
|
||||||
@ -132,24 +132,6 @@ public:
|
|||||||
const scalarField& cWeights
|
const scalarField& cWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Helper to convert connectivity (supplied as owner,neighbour) into
|
|
||||||
// Metis storage
|
|
||||||
static void calcMetisCSR
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Helper to convert connectivity (supplied as cellcells) into
|
|
||||||
// Metis storage
|
|
||||||
static void calcMetisCSR
|
|
||||||
(
|
|
||||||
const labelListList& globalCellCells,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -4,7 +4,8 @@ EXE_INC = \
|
|||||||
$(PFLAGS) $(PINC) \
|
$(PFLAGS) $(PINC) \
|
||||||
-I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1/ParMETISLib \
|
-I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1/ParMETISLib \
|
||||||
-I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1 \
|
-I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1 \
|
||||||
-I../decompositionMethods/lnInclude
|
-I../decompositionMethods/lnInclude \
|
||||||
|
-I../metisDecomp/lnInclude
|
||||||
|
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-L$(FOAM_MPI_LIBBIN) \
|
-L$(FOAM_MPI_LIBBIN) \
|
||||||
|
|||||||
@ -26,6 +26,7 @@ License
|
|||||||
|
|
||||||
#include "parMetisDecomp.H"
|
#include "parMetisDecomp.H"
|
||||||
#include "metisDecomp.H"
|
#include "metisDecomp.H"
|
||||||
|
#include "scotchDecomp.H"
|
||||||
#include "syncTools.H"
|
#include "syncTools.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "floatScalar.H"
|
#include "floatScalar.H"
|
||||||
@ -434,7 +435,7 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
|||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"metisDecomp::decompose"
|
"parMetisDecomp::decompose"
|
||||||
"(const pointField&, const scalarField&)"
|
"(const pointField&, const scalarField&)"
|
||||||
) << "Number of cell weights " << cWeights.size()
|
) << "Number of cell weights " << cWeights.size()
|
||||||
<< " does not equal number of cells " << mesh_.nCells()
|
<< " does not equal number of cells " << mesh_.nCells()
|
||||||
@ -762,7 +763,7 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
|||||||
Field<int> adjncy;
|
Field<int> adjncy;
|
||||||
// Offsets into adjncy
|
// Offsets into adjncy
|
||||||
Field<int> xadj;
|
Field<int> xadj;
|
||||||
metisDecomp::calcMetisCSR(globalCellCells, adjncy, xadj);
|
scotchDecomp::calcCSR(globalCellCells, adjncy, xadj);
|
||||||
|
|
||||||
// decomposition options. 0 = use defaults
|
// decomposition options. 0 = use defaults
|
||||||
List<int> options(3, 0);
|
List<int> options(3, 0);
|
||||||
|
|||||||
@ -36,7 +36,7 @@ Description
|
|||||||
Example usage:
|
Example usage:
|
||||||
myInterfacePatchName
|
myInterfacePatchName
|
||||||
{
|
{
|
||||||
type turbulentTemperatureCoupledBaffle;
|
type compressible::turbulentTemperatureCoupledBaffle;
|
||||||
neighbourFieldName T;
|
neighbourFieldName T;
|
||||||
K K; // or none
|
K K; // or none
|
||||||
value uniform 300;
|
value uniform 300;
|
||||||
|
|||||||
@ -37,7 +37,7 @@ Description
|
|||||||
Example usage:
|
Example usage:
|
||||||
myInterfacePatchName
|
myInterfacePatchName
|
||||||
{
|
{
|
||||||
type turbulentTemperatureCoupledBaffleMixed;
|
type compressible::turbulentTemperatureCoupledBaffleMixed;
|
||||||
neighbourFieldName T;
|
neighbourFieldName T;
|
||||||
K K; // or none
|
K K; // or none
|
||||||
value uniform 300;
|
value uniform 300;
|
||||||
|
|||||||
@ -220,6 +220,12 @@ castellatedMeshControls
|
|||||||
// NOTE: This point should never be on a face, always inside a cell, even
|
// NOTE: This point should never be on a face, always inside a cell, even
|
||||||
// after refinement.
|
// after refinement.
|
||||||
locationInMesh (3 0.28 0.43);
|
locationInMesh (3 0.28 0.43);
|
||||||
|
|
||||||
|
|
||||||
|
// Whether any faceZones (as specified in the refinementSurfaces)
|
||||||
|
// are only on the boundary of corresponding cellZones or also allow
|
||||||
|
// free-standing zone faces. Not used if there are no faceZones.
|
||||||
|
allowFreeStandingZoneFaces true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -311,7 +317,8 @@ addLayersControls
|
|||||||
maxThicknessToMedialRatio 0.3;
|
maxThicknessToMedialRatio 0.3;
|
||||||
|
|
||||||
// Angle used to pick up medial axis points
|
// Angle used to pick up medial axis points
|
||||||
minMedianAxisAngle 130;
|
// Note: changed(corrected) w.r.t 16x! 90 degrees corresponds to 130 in 16x.
|
||||||
|
minMedianAxisAngle 90;
|
||||||
|
|
||||||
// Create buffer region for new layer terminations
|
// Create buffer region for new layer terminations
|
||||||
nBufferCellsNoExtrude 0;
|
nBufferCellsNoExtrude 0;
|
||||||
|
|||||||
@ -145,6 +145,12 @@ castellatedMeshControls
|
|||||||
// NOTE: This point should never be on a face, always inside a cell, even
|
// NOTE: This point should never be on a face, always inside a cell, even
|
||||||
// after refinement.
|
// after refinement.
|
||||||
locationInMesh (3 3 0.43);
|
locationInMesh (3 3 0.43);
|
||||||
|
|
||||||
|
|
||||||
|
// Whether any faceZones (as specified in the refinementSurfaces)
|
||||||
|
// are only on the boundary of corresponding cellZones or also allow
|
||||||
|
// free-standing zone faces. Not used if there are no faceZones.
|
||||||
|
allowFreeStandingZoneFaces true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -500,7 +506,9 @@ addLayersControls
|
|||||||
maxThicknessToMedialRatio 0.3;
|
maxThicknessToMedialRatio 0.3;
|
||||||
|
|
||||||
// Angle used to pick up medial axis points
|
// Angle used to pick up medial axis points
|
||||||
minMedianAxisAngle 130;
|
// Note: changed(corrected) w.r.t 16x! 90 degrees corresponds to 130 in 16x.
|
||||||
|
minMedianAxisAngle 90;
|
||||||
|
|
||||||
|
|
||||||
// Create buffer region for new layer terminations
|
// Create buffer region for new layer terminations
|
||||||
nBufferCellsNoExtrude 0;
|
nBufferCellsNoExtrude 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user