ENH: improve syncTools handling of bitSet/PackedList types

- additional support for face sync/swap of boundary values.
  This allows use of bitSet instead of boolList in more places
This commit is contained in:
Mark Olesen
2019-08-09 10:07:28 +02:00
parent 751e1c278d
commit 3fd5e53007
2 changed files with 161 additions and 60 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011, 2015-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation | Copyright (C) 2011-2016 OpenFOAM Foundation
@ -67,7 +67,7 @@ class syncTools
{ {
// Private Member Functions // Private Member Functions
//- Combine value with existing value in map. //- Combine val with existing value in pointValues map at given index
template<class T, class CombineOp> template<class T, class CombineOp>
static void combine static void combine
( (
@ -77,7 +77,7 @@ class syncTools
const T& val const T& val
); );
//- Combine val with existing value at (implicit index) e. //- Combine val with existing value in edgeValues at edge index
template<class T, class CombineOp> template<class T, class CombineOp>
static void combine static void combine
( (
@ -90,9 +90,8 @@ class syncTools
public: public:
// Basic routines with user-supplied transformation.
// Basic routines with user-supplied transformation. Preferably // Preferably use specialisations below.
// use specialisations below.
//- Synchronize values on selected points. //- Synchronize values on selected points.
template<class T, class CombineOp, class TransformOp> template<class T, class CombineOp, class TransformOp>
@ -434,7 +433,7 @@ public:
); );
} }
//- Swap coupled boundary face values. //- Swap coupled boundary face values. Uses eqOp
template<class T> template<class T>
static void swapBoundaryFaceList static void swapBoundaryFaceList
( (
@ -451,7 +450,7 @@ public:
); );
} }
//- Swap coupled positions. //- Swap coupled positions. Uses eqOp
static void swapBoundaryFacePositions static void swapBoundaryFacePositions
( (
const polyMesh& mesh, const polyMesh& mesh,
@ -467,7 +466,7 @@ public:
); );
} }
//- Swap coupled face values. //- Swap coupled face values. Uses eqOp
template<class T> template<class T>
static void swapFaceList static void swapFaceList
( (
@ -507,6 +506,7 @@ public:
List<point>& neighbourCellData List<point>& neighbourCellData
); );
// Sparse versions // Sparse versions
//- Synchronize values on selected points. //- Synchronize values on selected points.
@ -583,8 +583,29 @@ public:
); );
} }
// PackedList versions // PackedList versions
//- Synchronize face values from PackedList/bitSet
//
// \param mesh The mesh
// \param isBoundaryOnly True if faceValues are for the boundary
// only and not the entire mesh. This determines the face
// offset when accessing values.
// \param faceValues The face values to synchronize
// \param cop The combine operation
// \param parRun True if this is a parallel simulation
template<unsigned Width, class CombineOp>
static void syncFaceList
(
const polyMesh& mesh,
const bool isBoundaryOnly,
PackedList<Width>& faceValues,
const CombineOp& cop,
const bool parRun = Pstream::parRun()
);
//- Synchronize mesh face values from PackedList/bitSet
template<unsigned Width, class CombineOp> template<unsigned Width, class CombineOp>
static void syncFaceList static void syncFaceList
( (
@ -594,6 +615,17 @@ public:
const bool parRun = Pstream::parRun() const bool parRun = Pstream::parRun()
); );
//- Synchronize boundary face values from PackedList/bitSet
template<unsigned Width, class CombineOp>
static void syncBoundaryFaceList
(
const polyMesh& mesh,
PackedList<Width>& faceValues,
const CombineOp& cop,
const bool parRun = Pstream::parRun()
);
//- Swap coupled face values. Uses eqOp
template<unsigned Width> template<unsigned Width>
static void swapFaceList static void swapFaceList
( (
@ -601,6 +633,14 @@ public:
PackedList<Width>& faceValues PackedList<Width>& faceValues
); );
//- Swap coupled boundary face values. Uses eqOp
template<unsigned Width>
static void swapBoundaryFaceList
(
const polyMesh& mesh,
PackedList<Width>& faceValues
);
template<unsigned Width, class CombineOp> template<unsigned Width, class CombineOp>
static void syncPointList static void syncPointList
( (
@ -623,24 +663,23 @@ public:
// Other // Other
//- Get per point whether it is uncoupled or a master of a //- Get per point whether it is uncoupled or a master of a
// coupled set of points //- coupled set of points
static bitSet getMasterPoints(const polyMesh& mesh); static bitSet getMasterPoints(const polyMesh& mesh);
//- Get per edge whether it is uncoupled or a master of a //- Get per edge whether it is uncoupled or a master of a
// coupled set of edges //- coupled set of edges
static bitSet getMasterEdges(const polyMesh& mesh); static bitSet getMasterEdges(const polyMesh& mesh);
//- Get per face whether it is uncoupled or a master of a //- Get per face whether it is uncoupled or a master of a
// coupled set of faces //- coupled set of faces
static bitSet getMasterFaces(const polyMesh& mesh); static bitSet getMasterFaces(const polyMesh& mesh);
//- Get per face whether it is internal or a master of a //- Get per face whether it is internal or a master of a
// coupled set of faces //- coupled set of faces
static bitSet getInternalOrMasterFaces(const polyMesh& mesh); static bitSet getInternalOrMasterFaces(const polyMesh& mesh);
//- Get per face whether it is internal or coupled //- Get per face whether it is internal or coupled
static bitSet getInternalOrCoupledFaces(const polyMesh& mesh); static bitSet getInternalOrCoupledFaces(const polyMesh& mesh);
}; };

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2011, 2015-2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011, 2015-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation | Copyright (C) 2011-2017 OpenFOAM Foundation
@ -31,7 +31,6 @@ License
#include "cyclicPolyPatch.H" #include "cyclicPolyPatch.H"
#include "globalMeshData.H" #include "globalMeshData.H"
#include "contiguous.H" #include "contiguous.H"
#include "transform.H"
#include "transformList.H" #include "transformList.H"
#include "SubField.H" #include "SubField.H"
@ -175,8 +174,8 @@ void Foam::syncTools::syncPointMap
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp); refCast<const processorPolyPatch>(pp);
UIPstream fromNb(procPatch.neighbProcNo(), pBufs); UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
Map<T> nbrPatchInfo(fromNb); Map<T> nbrPatchInfo(fromNbr);
// Transform // Transform
top(procPatch, nbrPatchInfo); top(procPatch, nbrPatchInfo);
@ -921,6 +920,7 @@ void Foam::syncTools::syncEdgeList
} }
} }
template<class T, class CombineOp, class TransformOp> template<class T, class CombineOp, class TransformOp>
void Foam::syncTools::syncBoundaryFaceList void Foam::syncTools::syncBoundaryFaceList
( (
@ -931,14 +931,16 @@ void Foam::syncTools::syncBoundaryFaceList
const bool parRun const bool parRun
) )
{ {
const label nBFaces = mesh.nBoundaryFaces(); // Offset (global to local) for start of boundaries
const label boundaryOffset = mesh.nInternalFaces();
if (faceValues.size() != nBFaces) if (faceValues.size() != mesh.nBoundaryFaces())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Number of values " << faceValues.size() << "Number of values " << faceValues.size()
<< " is not equal to the number of boundary faces in the mesh " << " is not equal to the number of boundary faces in the mesh "
<< nBFaces << abort(FatalError); << mesh.nBoundaryFaces() << nl
<< abort(FatalError);
} }
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
@ -956,10 +958,11 @@ void Foam::syncTools::syncBoundaryFaceList
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp); refCast<const processorPolyPatch>(pp);
label patchStart = procPatch.start()-mesh.nInternalFaces(); const label patchStart = procPatch.start()-boundaryOffset;
// Send slice of values on the patch
UOPstream toNbr(procPatch.neighbProcNo(), pBufs); UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
toNbr << SubField<T>(faceValues, procPatch.size(), patchStart); toNbr<< SubList<T>(faceValues, procPatch.size(), patchStart);
} }
} }
@ -976,18 +979,18 @@ void Foam::syncTools::syncBoundaryFaceList
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp); refCast<const processorPolyPatch>(pp);
Field<T> nbrPatchInfo(procPatch.size()); Field<T> nbrVals(procPatch.size());
UIPstream fromNeighb(procPatch.neighbProcNo(), pBufs); UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
fromNeighb >> nbrPatchInfo; fromNbr >> nbrVals;
top(procPatch, nbrPatchInfo); top(procPatch, nbrVals);
label bFacei = procPatch.start()-mesh.nInternalFaces(); label bFacei = procPatch.start()-boundaryOffset;
forAll(nbrPatchInfo, i) for (T& nbrVal : nbrVals)
{ {
cop(faceValues[bFacei++], nbrPatchInfo[i]); cop(faceValues[bFacei++], nbrVal);
} }
} }
} }
@ -1005,28 +1008,28 @@ void Foam::syncTools::syncBoundaryFaceList
{ {
// Owner does all. // Owner does all.
const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch(); const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
const label ownStart = cycPatch.start()-mesh.nInternalFaces();
const label nbrStart = nbrPatch.start()-mesh.nInternalFaces();
const label sz = cycPatch.size(); const label patchSize = cycPatch.size();
const label ownStart = cycPatch.start()-boundaryOffset;
const label nbrStart = nbrPatch.start()-boundaryOffset;
// Transform (copy of) data on both sides // Transform (copy of) data on both sides
Field<T> ownVals(SubField<T>(faceValues, sz, ownStart)); Field<T> ownVals(SubList<T>(faceValues, patchSize, ownStart));
top(nbrPatch, ownVals); top(nbrPatch, ownVals);
Field<T> nbrVals(SubField<T>(faceValues, sz, nbrStart)); Field<T> nbrVals(SubList<T>(faceValues, patchSize, nbrStart));
top(cycPatch, nbrVals); top(cycPatch, nbrVals);
label i0 = ownStart; label bFacei = ownStart;
forAll(nbrVals, i) for (T& nbrVal : nbrVals)
{ {
cop(faceValues[i0++], nbrVals[i]); cop(faceValues[bFacei++], nbrVal);
} }
label i1 = nbrStart; bFacei = nbrStart;
forAll(ownVals, i) for (T& ownVal : ownVals)
{ {
cop(faceValues[i1++], ownVals[i]); cop(faceValues[bFacei++], ownVal);
} }
} }
} }
@ -1040,17 +1043,27 @@ template<unsigned Width, class CombineOp>
void Foam::syncTools::syncFaceList void Foam::syncTools::syncFaceList
( (
const polyMesh& mesh, const polyMesh& mesh,
const bool isBoundaryOnly,
PackedList<Width>& faceValues, PackedList<Width>& faceValues,
const CombineOp& cop, const CombineOp& cop,
const bool parRun const bool parRun
) )
{ {
if (faceValues.size() != mesh.nFaces()) // Offset (global to local) for start of boundaries
const label boundaryOffset = (isBoundaryOnly ? mesh.nInternalFaces() : 0);
if
(
faceValues.size()
!= (isBoundaryOnly ? mesh.nBoundaryFaces() : mesh.nFaces())
)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Number of values " << faceValues.size() << "Number of values " << faceValues.size()
<< " is not equal to the number of faces in the mesh " << " is not equal to the number of "
<< mesh.nFaces() << abort(FatalError); << (isBoundaryOnly ? "boundary" : "mesh") << " faces "
<< (isBoundaryOnly ? mesh.nBoundaryFaces() : mesh.nFaces()) << nl
<< abort(FatalError);
} }
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
@ -1068,10 +1081,15 @@ void Foam::syncTools::syncFaceList
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp); refCast<const processorPolyPatch>(pp);
const labelRange range
(
procPatch.start()-boundaryOffset,
procPatch.size()
);
// Send slice of values on the patch // Send slice of values on the patch
UOPstream toNbr(procPatch.neighbProcNo(), pBufs); UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
toNbr toNbr<< PackedList<Width>(faceValues, range);
<< PackedList<Width>(faceValues, procPatch.range());
} }
} }
@ -1087,23 +1105,26 @@ void Foam::syncTools::syncFaceList
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp); refCast<const processorPolyPatch>(pp);
const label patchSize = procPatch.size();
// Recv slice of values on the patch // Recv slice of values on the patch
PackedList<Width> recvInfo(procPatch.size()); PackedList<Width> recvInfo(patchSize);
{ {
UIPstream fromNbr(procPatch.neighbProcNo(), pBufs); UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
fromNbr >> recvInfo; fromNbr >> recvInfo;
} }
// Combine (bitwise) // Combine (bitwise)
forAll(procPatch, i) label bFacei = procPatch.start()-boundaryOffset;
for (label i = 0; i < patchSize; ++i)
{ {
const label meshFacei = procPatch.start()+i;
unsigned int recvVal = recvInfo[i]; unsigned int recvVal = recvInfo[i];
unsigned int faceVal = faceValues[meshFacei]; unsigned int faceVal = faceValues[bFacei];
cop(faceVal, recvVal); cop(faceVal, recvVal);
faceValues.set(meshFacei, faceVal); faceValues.set(bFacei, faceVal);
++bFacei;
} }
} }
} }
@ -1123,20 +1144,24 @@ void Foam::syncTools::syncFaceList
// Owner does all. // Owner does all.
const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch(); const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
for (label i = 0; i < cycPatch.size(); ++i) const label patchSize = cycPatch.size();
{
const label meshFace0 = cycPatch.start()+i;
const label meshFace1 = nbrPatch.start()+i;
unsigned int val0 = faceValues[meshFace0]; label face0 = cycPatch.start()-boundaryOffset;
unsigned int val1 = faceValues[meshFace1]; label face1 = nbrPatch.start()-boundaryOffset;
for (label i = 0; i < patchSize; ++i)
{
unsigned int val0 = faceValues[face0];
unsigned int val1 = faceValues[face1];
unsigned int t = val0; unsigned int t = val0;
cop(t, val1); cop(t, val1);
faceValues[meshFace0] = t; faceValues[face0] = t;
cop(val1, val0); cop(val1, val0);
faceValues[meshFace1] = val1; faceValues[face1] = val1;
++face0;
++face1;
} }
} }
} }
@ -1180,6 +1205,32 @@ void Foam::syncTools::swapBoundaryCellList
} }
template<unsigned Width, class CombineOp>
void Foam::syncTools::syncFaceList
(
const polyMesh& mesh,
PackedList<Width>& faceValues,
const CombineOp& cop,
const bool parRun
)
{
syncFaceList(mesh, false, faceValues, cop, parRun);
}
template<unsigned Width, class CombineOp>
void Foam::syncTools::syncBoundaryFaceList
(
const polyMesh& mesh,
PackedList<Width>& faceValues,
const CombineOp& cop,
const bool parRun
)
{
syncFaceList(mesh, true, faceValues, cop, parRun);
}
template<unsigned Width> template<unsigned Width>
void Foam::syncTools::swapFaceList void Foam::syncTools::swapFaceList
( (
@ -1191,6 +1242,17 @@ void Foam::syncTools::swapFaceList
} }
template<unsigned Width>
void Foam::syncTools::swapBoundaryFaceList
(
const polyMesh& mesh,
PackedList<Width>& faceValues
)
{
syncBoundaryFaceList(mesh, faceValues, eqOp<unsigned int>());
}
template<unsigned Width, class CombineOp> template<unsigned Width, class CombineOp>
void Foam::syncTools::syncPointList void Foam::syncTools::syncPointList
( (