ENH: globalMeshData, mapDistribute : multi-point connectivity with transforms

This commit is contained in:
mattijs
2011-01-20 13:52:39 +00:00
parent 983048958a
commit 4c8ec205e5
15 changed files with 2652 additions and 2941 deletions

File diff suppressed because it is too large Load Diff

View File

@ -32,52 +32,56 @@ Description
- all processor patches to have correct ordering. - all processor patches to have correct ordering.
- all processorPatches to have their transforms set. - all processorPatches to have their transforms set.
The shared point addressing is quite interesting. It gives on each processor The shared point and edge addressing is quite interesting.
the vertices that cannot be set using a normal swap on processor patches. It calculates addressing for points and edges on coupled patches. In
These are the vertices that are shared between more than 2 processors. the 'old' way a distincation was made between points/edges that are
only on two processors and those that are on multiple processors. The
problem is that those on multiple processors do not allow any
transformations and require a global reduction on the master processor.
There is an issue with these shared vertices if they originate from The alternative is to have an exchange schedule (through a 'mapDistribute')
cyclics (i.e. are now separated processor patches). They will all be which sends all point/edge data (no distinction is made between
mapped to the same global point (so even though the processor points are those on two and those on more than two coupled patches) to the local
not on the same location) since topologically they are one and the same. 'master'. This master then does any calculation and sends
the result back to the 'slave' points/edges. This only needs to be done
on points on coupled faces. Any transformation is done using a predetermined
set of transformations - since transformations have to be space filling
only a certain number of transformation is supported.
So if you ask for sharedPoints() you get only one of the coordinates of The exchange needs
the topologically shared points. - a field of data
- a mapDistribute which does all parallel exchange and transformations
This appens remote data to the end of the field.
- a set of indices which indicate where to get untransformed data in the
field
- a set of indices which indicate where to get transformed data in the
field
All the hard work of these shared points is done by the globalPoints class. See also mapDistribute, globalIndexAndTransform
Shared edges: similar to shared points gives on all processors the edges Notes:
that are shared between more than two patches (i.e. the edges on which - compared to 17x nTotalFaces, nTotalPoints do not compensate for
data cannot be synchronized by a straightforward edge data swap). Note shared points since this would trigger full connectivity analysis
that shared edges will use shared points but not all edges between shared - most calculation is demand driven and uses parallel communication
points need to be shared edges (e.g. there might be an edge connecting so make sure to invoke on all processors at the same time.
two disconnected regions of shared points). - old sharedEdge calculation: currently an edge is considered shared
Currently an edge is considered shared
if it uses two shared points and is used more than once. This is not if it uses two shared points and is used more than once. This is not
correct on processor patches but it only slightly overestimates the number correct on processor patches but it only slightly overestimates the number
of shared edges. Doing full analysis of how many patches use the edge of shared edges. Doing full analysis of how many patches use the edge
would be too complicated. would be too complicated.
Shared edge calculation is demand driven so always make sure to have
your first call to one of the access functions synchronous amongst all
processors!
SourceFiles SourceFiles
globalMeshData.C globalMeshData.C
globalMeshDataTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef globalMeshData_H #ifndef globalMeshData_H
#define globalMeshData_H #define globalMeshData_H
#include "Switch.H"
#include "processorTopology.H" #include "processorTopology.H"
#include "labelPair.H" #include "labelPair.H"
#include "indirectPrimitivePatch.H" #include "indirectPrimitivePatch.H"
#include "boundBox.H"
#include "IOobject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -86,13 +90,11 @@ namespace Foam
// Forward declaration of friend functions and operators // Forward declaration of friend functions and operators
class globalMeshData;
Ostream& operator<<(Ostream&, const globalMeshData&);
class globalIndex;
class polyMesh; class polyMesh;
class mapDistribute; class mapDistribute;
template<class T> class EdgeMap; template<class T> class EdgeMap;
class globalPoints; class globalIndex;
class globalIndexAndTransform;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class globalMeshData Declaration Class globalMeshData Declaration
@ -134,9 +136,6 @@ class globalMeshData
// Data related to the complete mesh // Data related to the complete mesh
//- Bounding box of complete mesh
boundBox bb_;
//- Total number of points in the complete mesh //- Total number of points in the complete mesh
label nTotalPoints_; label nTotalPoints_;
@ -162,23 +161,70 @@ class globalMeshData
labelList processorPatchNeighbours_; labelList processorPatchNeighbours_;
// Coupled point addressing
// This is addressing from coupled point to coupled points/faces/cells.
// This is a full schedule so includes points used by only two
// coupled patches.
//- Patch of coupled faces. Additional patch edge to mesh edges
// correspondence:
// points: meshPoints(), meshPointMap()
// edges : meshEdges(), meshEdgeMap()
mutable autoPtr<indirectPrimitivePatch> coupledPatchPtr_;
mutable autoPtr<labelList> coupledPatchMeshEdgesPtr_;
mutable autoPtr<Map<label> > coupledPatchMeshEdgeMapPtr_;
//- Global numbering for coupledPatch points
mutable autoPtr<globalIndex> globalPointNumberingPtr_;
//- Global numbering for transforms
mutable autoPtr<globalIndexAndTransform> globalTransformsPtr_;
// Coupled point to coupled points
mutable autoPtr<labelListList> globalPointSlavesPtr_;
mutable autoPtr<labelListList> globalPointTransformedSlavesPtr_;
mutable autoPtr<mapDistribute> globalPointSlavesMapPtr_;
// Coupled edge to coupled edges
mutable autoPtr<globalIndex> globalEdgeNumberingPtr_;
mutable autoPtr<labelListList> globalEdgeSlavesPtr_;
mutable autoPtr<labelListList> globalEdgeTransformedSlavesPtr_;
mutable autoPtr<mapDistribute> globalEdgeSlavesMapPtr_;
//// Coupled point to boundary faces
//
//mutable autoPtr<globalIndex> globalBoundaryFaceNumberingPtr_;
//mutable autoPtr<labelListList> globalPointBoundaryFacesPtr_;
//mutable autoPtr<mapDistribute> globalPointBoundaryFacesMapPtr_;
//
//// Coupled point to collocated boundary cells
//
//mutable autoPtr<labelList> boundaryCellsPtr_;
//mutable autoPtr<globalIndex> globalBoundaryCellNumberingPtr_;
//mutable autoPtr<labelListList> globalPointBoundaryCellsPtr_;
//mutable autoPtr<mapDistribute> globalPointBoundaryCellsMapPtr_;
// Globally shared point addressing // Globally shared point addressing
//- Total number of global points //- Total number of global points
label nGlobalPoints_; mutable label nGlobalPoints_;
//- Indices of local points that are globally shared //- Indices of local points that are globally shared
labelList sharedPointLabels_; mutable autoPtr<labelList> sharedPointLabelsPtr_;
//- Indices of globally shared points in the master list //- Indices of globally shared points in the master list
// This list contains all the shared points in the mesh // This list contains all the shared points in the mesh
labelList sharedPointAddr_; mutable autoPtr<labelList> sharedPointAddrPtr_;
//- Shared point global labels. //- Shared point global labels.
// Global point index for every local shared point. // Global point index for every local shared point.
// Only valid if constructed with this information or if // Only valid if constructed with this information or if
// pointProcAddressing read. // pointProcAddressing read.
mutable labelList* sharedPointGlobalLabelsPtr_; mutable autoPtr<labelList> sharedPointGlobalLabelsPtr_;
// Globally shared edge addressing. Derived from shared points. // Globally shared edge addressing. Derived from shared points.
@ -188,68 +234,11 @@ class globalMeshData
mutable label nGlobalEdges_; mutable label nGlobalEdges_;
//- Indices of local edges that are globally shared //- Indices of local edges that are globally shared
mutable labelList* sharedEdgeLabelsPtr_; mutable autoPtr<labelList> sharedEdgeLabelsPtr_;
//- Indices of globally shared edge in the master list //- Indices of globally shared edge in the master list
// This list contains all the shared edges in the mesh // This list contains all the shared edges in the mesh
mutable labelList* sharedEdgeAddrPtr_; mutable autoPtr<labelList> sharedEdgeAddrPtr_;
// Coupled point addressing
// This is addressing from coupled point to coupled points/faces/cells.
// Two variants:
// - collocated (so not physically separated)
// - also separated
// This is a full schedule so includes points only used by two
// coupled patches.
mutable autoPtr<indirectPrimitivePatch> coupledPatchPtr_;
mutable autoPtr<labelList> coupledPatchMeshEdgesPtr_;
mutable autoPtr<Map<label> > coupledPatchMeshEdgeMapPtr_;
// Collocated
// Coupled point to collocated coupled points
mutable autoPtr<globalIndex> globalPointNumberingPtr_;
mutable autoPtr<labelListList> globalPointSlavesPtr_;
mutable autoPtr<mapDistribute> globalPointSlavesMapPtr_;
// Coupled edge to collocated coupled edges
mutable autoPtr<globalIndex> globalEdgeNumberingPtr_;
mutable autoPtr<labelListList> globalEdgeSlavesPtr_;
mutable autoPtr<mapDistribute> globalEdgeSlavesMapPtr_;
// Coupled point to collocated boundary faces
mutable autoPtr<globalIndex> globalBoundaryFaceNumberingPtr_;
mutable autoPtr<labelListList> globalPointBoundaryFacesPtr_;
mutable autoPtr<mapDistribute> globalPointBoundaryFacesMapPtr_;
// Coupled point to collocated boundary cells
mutable autoPtr<labelList> boundaryCellsPtr_;
mutable autoPtr<globalIndex> globalBoundaryCellNumberingPtr_;
mutable autoPtr<labelListList> globalPointBoundaryCellsPtr_;
mutable autoPtr<mapDistribute> globalPointBoundaryCellsMapPtr_;
// Non-collocated as well
// Coupled point to all coupled points
mutable autoPtr<globalIndex> globalPointAllNumberingPtr_;
mutable autoPtr<labelListList> globalPointAllSlavesPtr_;
mutable autoPtr<mapDistribute> globalPointAllSlavesMapPtr_;
// Coupled edge to all coupled edges (same numbering as
// collocated coupled edges)
mutable autoPtr<labelListList> globalEdgeAllSlavesPtr_;
mutable autoPtr<mapDistribute> globalEdgeAllSlavesMapPtr_;
// Private Member Functions // Private Member Functions
@ -265,70 +254,18 @@ class globalMeshData
label& label&
); );
//- Calculate shared point addressing
void calcSharedPoints() const;
//- Calculate shared edge addressing //- Calculate shared edge addressing
void calcSharedEdges() const; void calcSharedEdges() const;
//- Count coincident faces. //- Calculate global point addressing.
static label countCoincidentFaces
(
const scalar tolDim,
const vectorField& separationDist
);
//- Calculate global point addressing.
void calcGlobalPointSlaves
(
const globalPoints&,
autoPtr<globalIndex>&,
autoPtr<labelListList>&,
autoPtr<mapDistribute>&
) const;
//- Calculate global point addressing.
void calcGlobalPointSlaves() const; void calcGlobalPointSlaves() const;
//- Calculate global edge addressing.
void calcGlobalEdgeSlaves
(
const labelListList&,
const mapDistribute&,
const globalIndex&,
autoPtr<labelListList>&,
autoPtr<mapDistribute>&
) const;
//- Calculate global edge addressing. //- Calculate global edge addressing.
void calcGlobalEdgeSlaves() const; 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;
// Non-collocated
//- Calculate global point addressing.
void calcGlobalPointAllSlaves() const;
//- Calculate global edge addressing.
void calcGlobalEdgeAllSlaves() const;
//- Synchronise pointwise data
template<class Type, class CombineOp>
void syncPointData
(
List<Type>& pointData,
const labelListList& slaves,
const mapDistribute& slavesMap,
const CombineOp& cop
) const;
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
globalMeshData(const globalMeshData&); globalMeshData(const globalMeshData&);
@ -345,7 +282,7 @@ public:
// Static data members // Static data members
//- Geomtric tolerance (fraction of bounding box) //- Geomteric tolerance (fraction of bounding box)
static const Foam::scalar matchTol_; static const Foam::scalar matchTol_;
@ -354,10 +291,6 @@ public:
//- Construct from mesh, derive rest (does parallel communication!) //- Construct from mesh, derive rest (does parallel communication!)
globalMeshData(const polyMesh& mesh); globalMeshData(const polyMesh& mesh);
//- Old behaviour: read constructor given IOobject and a polyMesh
// reference. Only use this for testing!
globalMeshData(const IOobject& io, const polyMesh& mesh);
//- Destructor //- Destructor
~globalMeshData(); ~globalMeshData();
@ -383,24 +316,21 @@ public:
return processorPatches_.size() > 0; return processorPatches_.size() > 0;
} }
const boundBox& bb() const //- Return total number of points in decomposed mesh. Not
{ // compensated for duplicate points!
return bb_;
}
//- Return total number of points in decomposed mesh
label nTotalPoints() const label nTotalPoints() const
{ {
return nTotalPoints_; return nTotalPoints_;
} }
//- Return total number of faces in decomposed mesh //- Return total number of faces in decomposed mesh. Not
// compensated for duplicate faces!
label nTotalFaces() const label nTotalFaces() const
{ {
return nTotalFaces_; return nTotalFaces_;
} }
//- Return total number of cells in decomposed mesh //- Return total number of cells in decomposed mesh.
label nTotalCells() const label nTotalCells() const
{ {
return nTotalCells_; return nTotalCells_;
@ -435,16 +365,10 @@ public:
// Globally shared point addressing // Globally shared point addressing
//- Return number of globally shared points //- Return number of globally shared points
label nGlobalPoints() const label nGlobalPoints() const;
{
return nGlobalPoints_;
}
//- Return indices of local points that are globally shared //- Return indices of local points that are globally shared
const labelList& sharedPointLabels() const const labelList& sharedPointLabels() const;
{
return sharedPointLabels_;
}
//- Return addressing into the complete globally shared points //- Return addressing into the complete globally shared points
// list // list
@ -454,10 +378,7 @@ public:
// points. Shared point addressing gives the index in the // points. Shared point addressing gives the index in the
// list of all globally shared points for each of the locally // list of all globally shared points for each of the locally
// shared points. // shared points.
const labelList& sharedPointAddr() const const labelList& sharedPointAddr() const;
{
return sharedPointAddr_;
}
//- Return shared point global labels. Tries to read //- Return shared point global labels. Tries to read
// 'pointProcAddressing' and returns list or -1 if none // 'pointProcAddressing' and returns list or -1 if none
@ -512,70 +433,47 @@ public:
//- Return map from mesh edges to coupledPatch edges //- Return map from mesh edges to coupledPatch edges
const Map<label>& coupledPatchMeshEdgeMap() const; const Map<label>& coupledPatchMeshEdgeMap() const;
//- Global transforms numbering
const globalIndexAndTransform& globalTransforms() const;
// Coupled point to collocated coupled points. Coupled points are //- Helper: synchronise data with transforms
template<class Type, class CombineOp>
static void syncData
(
List<Type>& pointData,
const labelListList& slaves,
const labelListList& transformedSlaves,
const mapDistribute& slavesMap,
const globalIndexAndTransform&,
const CombineOp& cop,
const bool isPosition
);
// Coupled point to coupled points. Coupled points are
// points on any coupled patch. // points on any coupled patch.
//- Numbering of coupled points is according to coupledPatch. //- Numbering of coupled points is according to coupledPatch.
const globalIndex& globalPointNumbering() const; const globalIndex& globalPointNumbering() const;
//- For every coupled point the indices into the field
// distributed by below map.
const labelListList& globalPointSlaves() const; const labelListList& globalPointSlaves() const;
const labelListList& globalPointTransformedSlaves() const;
const mapDistribute& globalPointSlavesMap() const; const mapDistribute& globalPointSlavesMap() const;
//- Helper to synchronise mesh data //- Helper to synchronise mesh point data
template<class Type, class CombineOp> template<class Type, class CombineOp>
void syncPointData void syncPointData
( (
List<Type>& pointData, List<Type>& pointData,
const CombineOp& cop const CombineOp& cop,
const bool isPosition
) const; ) const;
// Coupled edge to coupled edges. // Coupled edge to coupled edges.
const globalIndex& globalEdgeNumbering() const; const globalIndex& globalEdgeNumbering() const;
const labelListList& globalEdgeSlaves() const; const labelListList& globalEdgeSlaves() const;
const labelListList& globalEdgeTransformedSlaves() const;
const mapDistribute& globalEdgeSlavesMap() 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;
// Collocated & non-collocated
// Coupled point to all coupled points (collocated and
// non-collocated).
const globalIndex& globalPointAllNumbering()const;
const labelListList& globalPointAllSlaves() const;
const mapDistribute& globalPointAllSlavesMap() const;
//- Helper to synchronise mesh data
template<class Type, class CombineOp>
void syncPointAllData
(
List<Type>& pointData,
const CombineOp& cop
) const;
// Coupled edge to all coupled edges (same numbering as
// collocated)
const labelListList& globalEdgeAllSlaves() const;
const mapDistribute& globalEdgeAllSlavesMap() const;
// Other // Other
@ -614,16 +512,6 @@ public:
// full parallel analysis to determine shared points and // full parallel analysis to determine shared points and
// boundaries. // boundaries.
void updateMesh(); void updateMesh();
// Write
bool write() const;
// Ostream Operator
friend Ostream& operator<<(Ostream&, const globalMeshData&);
}; };

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-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -29,13 +29,73 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, class CombineOp>
void Foam::globalMeshData::syncData
(
List<Type>& elems,
const labelListList& slaves,
const labelListList& transformedSlaves,
const mapDistribute& slavesMap,
const globalIndexAndTransform& transforms,
const CombineOp& cop,
const bool isPosition
)
{
// Pull slave data onto master
slavesMap.distribute(transforms, elems, isPosition);
// Combine master data with slave data
forAll(slaves, i)
{
Type& elem = elems[i];
const labelList& slavePoints = slaves[i];
const labelList& transformSlavePoints = transformedSlaves[i];
if (slavePoints.size()+transformSlavePoints.size() > 0)
{
// Combine master with untransformed slave data
forAll(slavePoints, j)
{
cop(elem, elems[slavePoints[j]]);
}
// Combine master with transformed slave data
forAll(transformSlavePoints, j)
{
cop(elem, elems[transformSlavePoints[j]]);
}
// Copy result back to slave slots
forAll(slavePoints, j)
{
elems[slavePoints[j]] = elem;
}
forAll(transformSlavePoints, j)
{
elems[transformSlavePoints[j]] = elem;
}
}
}
// Push slave-slot data back to slaves
slavesMap.reverseDistribute
(
transforms,
elems.size(),
elems,
isPosition
);
}
template<class Type, class CombineOp> template<class Type, class CombineOp>
void Foam::globalMeshData::syncPointData void Foam::globalMeshData::syncPointData
( (
List<Type>& pointData, List<Type>& pointData,
const labelListList& slaves, const CombineOp& cop,
const mapDistribute& slavesMap, const bool isPosition
const CombineOp& cop
) const ) const
{ {
if (pointData.size() != mesh_.nPoints()) if (pointData.size() != mesh_.nPoints())
@ -46,81 +106,26 @@ void Foam::globalMeshData::syncPointData
<< abort(FatalError); << abort(FatalError);
} }
// Transfer onto coupled patch
const indirectPrimitivePatch& cpp = coupledPatch(); const indirectPrimitivePatch& cpp = coupledPatch();
const labelList& meshPoints = cpp.meshPoints(); List<Type> cppFld(UIndirectList<Type>(pointData, cpp.meshPoints()));
// Copy mesh (point)data to coupled patch (point)data syncData
Field<Type> cppFld(slavesMap.constructSize());
forAll(meshPoints, patchPointI)
{
cppFld[patchPointI] = pointData[meshPoints[patchPointI]];
}
// Pull slave data onto master
slavesMap.distribute(cppFld);
// Combine master data with slave data
forAll(slaves, patchPointI)
{
const labelList& slavePoints = slaves[patchPointI];
// Combine master with slave data
forAll(slavePoints, i)
{
cop(cppFld[patchPointI], cppFld[slavePoints[i]]);
}
// Copy result back to slave slots
forAll(slavePoints, i)
{
cppFld[slavePoints[i]] = cppFld[patchPointI];
}
}
// Push master data back to slaves
slavesMap.reverseDistribute(meshPoints.size(), cppFld);
// Update mesh (point)data from coupled patch (point)data
forAll(meshPoints, patchPointI)
{
pointData[meshPoints[patchPointI]] = cppFld[patchPointI];
}
}
template<class Type, class CombineOp>
void Foam::globalMeshData::syncPointData
(
List<Type>& pointData,
const CombineOp& cop
) const
{
const labelListList& slaves = globalPointSlaves();
const mapDistribute& map = globalPointSlavesMap();
syncPointData
( (
pointData, cppFld,
slaves, globalPointSlaves(),
map, globalPointTransformedSlaves(),
cop globalPointSlavesMap(),
globalTransforms(),
cop,
isPosition
); );
}
// Extract back onto mesh
template<class Type, class CombineOp> forAll(cpp.meshPoints(), i)
void Foam::globalMeshData::syncPointAllData {
( pointData[cpp.meshPoints()[i]] = cppFld[i];
List<Type>& pointData, }
const CombineOp& cop
) const
{
syncPointData
(
pointData,
globalPointAllSlaves(),
globalPointAllSlavesMap(),
cop
);
} }

File diff suppressed because it is too large Load Diff

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-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -39,17 +39,15 @@ 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 in globalIndex numbering (so consecutively numbered patches. These list are in globalIndexAndTransform numbering
per processor)
E.g. E.g.
@verbatim @verbatim
((7 93)(4 731)(3 114)) ((7 93)(4 731)(3 114))
@endverbatim @endverbatim
means point 93 on proc7 is connected to point 731 on proc4 and 114 on proc3. means point 93 on proc7 is connected to point 731 on proc4 and 114 on proc3.
It then gets the lowest numbered processor (the 'master') to request a It then assigns the lowest numbered processor to be the local 'master' and
sharedPoint label from processor0 and it redistributes this label back to constructs a mapDistribute to send all data to this master.
the other processors in the equivalence list.
Algorithm: Algorithm:
- get meshPoints of all my points on processor patches and initialize - get meshPoints of all my points on processor patches and initialize
@ -64,24 +62,9 @@ Description
endloop until nothing changes endloop until nothing changes
At this point one will have complete point-point connectivity for all At this point one will have complete point-point connectivity for all
points on processor patches. Now points on processor patches. Now (optionally) remove point
equivalences of size 2. These are just normal points shared
- (optional)remove point equivalences of size 2. These are between two neighbouring procPatches.
just normal points shared between two neighbouring procPatches.
- collect on each processor points for which it is the master
- request number of sharedPointLabels from the Pstream::master.
This information gets redistributed to all processors in a similar way
as that in which the equivalence lists were collected:
- initialize the indices of shared points I am the master for
loop
- send my known sharedPoints + meshPoints to all neighbours
- receive from all neighbour. Find which meshPoint on my processor
the sharedpoint is connected to
- mark indices for which information has changed
endloop until nothing changes.
Note: the data held is either mesh point labels (construct from mesh only) Note: the data held is either mesh point labels (construct from mesh only)
or patch point labels (construct from mesh and patch). or patch point labels (construct from mesh and patch).
@ -95,12 +78,9 @@ SourceFiles
#define globalPoints_H #define globalPoints_H
#include "DynamicList.H" #include "DynamicList.H"
#include "Map.H"
#include "primitivePatch.H"
#include "edgeList.H"
#include "globalIndex.H"
#include "indirectPrimitivePatch.H" #include "indirectPrimitivePatch.H"
#include "PackedBoolList.H" #include "globalIndex.H"
#include "globalIndexAndTransform.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -112,7 +92,7 @@ class polyMesh;
class polyBoundaryMesh; class polyBoundaryMesh;
class cyclicPolyPatch; class cyclicPolyPatch;
class polyPatch; class polyPatch;
class coupledPolyPatch; class mapDistribute;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class globalPoints Declaration Class globalPoints Declaration
@ -120,91 +100,85 @@ class coupledPolyPatch;
class globalPoints class globalPoints
{ {
// Static data members
//- Offset to add to points (in globalIndices) originating from
// collocated coupled points.
static const label fromCollocated;
// Private data // Private data
//- Mesh reference //- Mesh reference
const polyMesh& mesh_; const polyMesh& mesh_;
//- Global numbering of points //- Global numbering of untransformed points
globalIndex globalIndices_; globalIndex globalIndices_;
//- Global numbering of transformed points
const globalIndexAndTransform globalTransforms_;
//- 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<labelList> procPoints_; DynamicList<labelPairList> procPoints_;
//- Map from mesh (or patch) 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)
labelList sharedPointAddr_;
//- My mesh(or patch) points corresponding to the shared points // Calculated mapDistribute addressing
labelList sharedPointLabels_;
//- Non-transformed connected points per point (in mapDistribute
// indices)
labelListList pointPoints_;
//- Transformed points per point (in mapDistribute indices)
labelListList transformedPointPoints_;
//- Corresponding map
autoPtr<mapDistribute> map_;
//- Total number of shared points.
label nGlobalPoints_;
// Private Member Functions // Private Member Functions
// Wrappers around global point numbering to add collocated bit //- Helper function to sort according minimum proc, minimum index,
// minimum transform
//- Convert into globalIndices and add collocated bit class globalIndexAndTransformLessThan
label toGlobal(const label, const bool isCollocated) const; {
public:
//- Is collocated bit set bool operator()
bool isCollocated(const label globalI) const; (
const labelPair& a,
//- Remove collocated bit const labelPair& b
label removeCollocated(const label globalI) const; );
};
//- (remove collocated bit and) check if originates from local proc
bool isLocal(const label globalI) const;
//- (remove collocated bit and) get originating processor
label whichProcID(const label globalI) const;
//- (remove collocated bit and) convert to local number on processor
label toLocal(const label procI, const label globalI) const;
//- (remove collocated bit and) convert to local number on
// Pstream::myProcNo
label toLocal(const label globalI) const;
//- Count all points on processorPatches. Is all points for which //- Count all points on processorPatches. Is all points for which
// information is collected. // information is collected.
static label countPatchPoints(const polyBoundaryMesh&); static label countPatchPoints(const polyBoundaryMesh&);
labelPairList addSendTransform
(
const label patchI,
const labelPairList& info
) const;
//- 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 void addToSend
( (
const primitivePatch&, const polyPatch&,
const label patchPointI, const label patchPointI,
const labelList&, const labelPairList&,
DynamicList<label>& patchFaces, DynamicList<label>& patchFaces,
DynamicList<label>& indexInFace, DynamicList<label>& indexInFace,
DynamicList<labelList>& allInfo DynamicList<labelPairList>& allInfo
); ) const;
//- Merge info from neighbour into my data //- Merge info from neighbour into my data
static bool mergeInfo static bool mergeInfo
( (
const labelList& nbrInfo, const labelPairList& nbrInfo,
labelList& myInfo const label localPointI,
labelPairList& myInfo
); );
//- From mesh point to 'local point'. Is the mesh point itself //- From mesh point to 'local point'. Is the mesh point itself
@ -223,18 +197,26 @@ class globalPoints
); );
//- Store (and merge) info for meshPointI //- Store (and merge) info for meshPointI
bool storeInfo bool storeInitialInfo
( (
const labelList& nbrInfo, const labelPairList& nbrInfo,
const label localPointI, const label localPointI
const bool isCollocated
); );
//- Store (and merge) info for meshPointI
bool mergeInfo
(
const labelPairList& nbrInfo,
const label localPointI
);
//- Get the signs for the individual transforms
FixedList<label, 3> transformBits(const label transformIndex) const;
void printProcPoints void printProcPoints
( (
const labelList& patchToMeshPoint, const labelList& patchToMeshPoint,
const labelList& pointInfo, const labelPairList& pointInfo
Ostream& os
) const; ) const;
//- Initialize procPoints_ to my patch points. allPoints = true: //- Initialize procPoints_ to my patch points. allPoints = true:
@ -260,6 +242,7 @@ class globalPoints
( (
const bool mergeSeparated, const bool mergeSeparated,
const Map<label>&, const Map<label>&,
const labelList&,
PstreamBuffers&, PstreamBuffers&,
labelHashSet& labelHashSet&
); );
@ -268,34 +251,6 @@ class globalPoints
// Used to remove normal face-face connected points. // Used to remove normal face-face connected points.
void remove(const labelList& patchToMeshPoint, const Map<label>&); void remove(const labelList& patchToMeshPoint, const Map<label>&);
//- Compact out unused elements of procPoints.
void compact(const labelList& patchToMeshPoint);
//- Get indices of point for which I am master (lowest numbered proc)
labelList getMasterPoints(const labelList& patchToMeshPoint) const;
//- Send subset of shared points to neighbours
void sendSharedPoints
(
const bool mergeSeparated,
PstreamBuffers&,
const DynamicList<label>&
) const;
//- Take over any local shared points
void extendSharedPoints(const Map<label>&, DynamicList<label>&);
//- Receive shared points and update subset.
void receiveSharedPoints
(
const bool mergeSeparated,
const Map<label>& meshToPatchPoint,
const Map<label>& meshToShared,
PstreamBuffers&,
DynamicList<label>&
);
//- Return mesh points of other side in same order as my meshPoints. //- Return mesh points of other side in same order as my meshPoints.
static labelList reverseMeshPoints(const cyclicPolyPatch&); static labelList reverseMeshPoints(const cyclicPolyPatch&);
@ -325,7 +280,7 @@ public:
//- Construct from mesh. //- Construct from mesh.
// keepAllPoints = false : filter out points that are on two // keepAllPoints = false : filter out points that are on two
// neighbouring coupled patches (so can be swapped) // neighbouring coupled patches only (so can be swapped)
// mergeSeparated: // mergeSeparated:
// true : merge coupled points across separated patches. // true : merge coupled points across separated patches.
// false : do not merge across coupled separated patches. // false : do not merge across coupled separated patches.
@ -338,8 +293,7 @@ public:
//- Construct from mesh and patch of coupled faces. Difference with //- Construct from mesh and patch of coupled faces. Difference with
// construct from mesh only is that this stores the meshToProcPoint, // construct from mesh only is that this stores the meshToProcPoint,
// procPoints and sharedPointLabels as patch local point labels // procPoints as patch local point labels instead of mesh point labels.
// instead of mesh point labels.
globalPoints globalPoints
( (
const polyMesh& mesh, const polyMesh& mesh,
@ -353,43 +307,68 @@ public:
// Access // Access
//- Global numbering of untransformed (mesh or patch) points
const globalIndex& globalIndices() const
{
return globalIndices_;
}
//- Global numbering of transformed (mesh or patch) points
const globalIndexAndTransform& globalTransforms() const
{
return globalTransforms_;
}
//- Non-transformed connected points per point (in mapDistribute
// indices)
const labelListList& pointPoints() const
{
return pointPoints_;
}
//- Non-transformed connected points per point (in mapDistribute
// indices)
labelListList& pointPoints()
{
return pointPoints_;
}
//- Transformed points per point (in mapDistribute indices)
const labelListList& transformedPointPoints() const
{
return transformedPointPoints_;
}
//- Transformed points per point (in mapDistribute indices)
labelListList& transformedPointPoints()
{
return transformedPointPoints_;
}
//- Corresponding map
const mapDistribute& map() const
{
return map_();
}
//- Corresponding map
mapDistribute& map()
{
return map_();
}
//- From (mesh or patch) point to index in procPoints //- From (mesh or patch) point to index in procPoints
const Map<label>& meshToProcPoint() const const Map<label>& meshToProcPoint() const
{ {
return meshToProcPoint_; return meshToProcPoint_;
} }
//- procPoints is per point the connected points (in global //- procPoints is per point the connected points (in
// point numbers) // globalTransformAndIndex point numbers)
const DynamicList<labelList>& procPoints() const const DynamicList<labelPairList>& procPoints() const
{ {
return procPoints_; return procPoints_;
} }
//- Global numbering of (mesh or patch) points
const globalIndex& globalIndices() const
{
return globalIndices_;
}
//- shared points used by this processor (= global point number)
const labelList& sharedPointAddr() const
{
return sharedPointAddr_;
}
//- my (mesh or patch)points corresponding to the shared points
const labelList& sharedPointLabels() const
{
return sharedPointLabels_;
}
//- total number of shared points
label nGlobalPoints() const
{
return nGlobalPoints_;
}
}; };

View File

@ -28,6 +28,7 @@ License
#include "HashSet.H" #include "HashSet.H"
#include "globalIndex.H" #include "globalIndex.H"
#include "globalIndexAndTransform.H" #include "globalIndexAndTransform.H"
#include "transformField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -199,35 +200,66 @@ void Foam::mapDistribute::checkReceivedSize
} }
void Foam::mapDistribute::printLayout void Foam::mapDistribute::printLayout(Ostream& os) const
(
const label localSize,
List<Map<label> >& compactMap,
Ostream& os
) const
{ {
// Determine offsets of remote data.
labelList minIndex(Pstream::nProcs(), labelMax);
labelList maxIndex(Pstream::nProcs(), labelMin);
forAll(constructMap_, procI)
{
const labelList& construct = constructMap_[procI];
minIndex[procI] = min(minIndex[procI], min(construct));
maxIndex[procI] = max(maxIndex[procI], max(construct));
}
label localSize;
if (maxIndex[Pstream::myProcNo()] == labelMin)
{
localSize = 0;
}
else
{
localSize = maxIndex[Pstream::myProcNo()]+1;
}
os << "Layout:" << endl os << "Layout:" << endl
<< "local (processor " << Pstream::myProcNo() << "):" << endl << "local (processor " << Pstream::myProcNo() << "):" << endl
<< " start : 0" << endl << " start : 0" << endl
<< " size : " << localSize << endl; << " size : " << localSize << endl;
label offset = localSize; label offset = localSize;
forAll(compactMap, procI) forAll(minIndex, procI)
{ {
if (procI != Pstream::myProcNo()) if (procI != Pstream::myProcNo())
{ {
os << "processor " << procI << ':' << endl if (constructMap_[procI].size() > 0)
<< " start : " << offset << endl {
<< " size : " << compactMap[procI].size() << endl; if (minIndex[procI] != offset)
{
FatalErrorIn("mapDistribute::printLayout(..)")
<< "offset:" << offset
<< " procI:" << procI
<< " minIndex:" << minIndex[procI]
<< abort(FatalError);
}
offset += compactMap[procI].size(); label size = maxIndex[procI]-minIndex[procI]+1;
os << "processor " << procI << ':' << endl
<< " start : " << offset << endl
<< " size : " << size << endl;
offset += size;
}
} }
} }
forAll(transformElements_, trafoI) forAll(transformElements_, trafoI)
{ {
os << "transform " << trafoI << ':' << endl if (transformElements_[trafoI].size() > 0)
<< " start : " << transformStart_[trafoI] << endl {
<< " size : " << transformElements_[trafoI].size() << endl; os << "transform " << trafoI << ':' << endl
<< " start : " << transformStart_[trafoI] << endl
<< " size : " << transformElements_[trafoI].size() << endl;
}
} }
} }
@ -502,8 +534,111 @@ void Foam::mapDistribute::exchangeAddressing
} }
template<>
void Foam::mapDistribute::applyTransforms
(
const globalIndexAndTransform& globalTransforms,
List<point>& field,
const bool isPosition
) const
{
const List<vectorTensorTransform>& totalTransform =
globalTransforms.transformPermutations();
forAll(totalTransform, trafoI)
{
const vectorTensorTransform& vt = totalTransform[trafoI];
const labelList& elems = transformElements_[trafoI];
label n = transformStart_[trafoI];
// Could be optimised to avoid memory allocations
if (isPosition)
{
Field<point> transformFld
(
vt.transformPosition(Field<point>(field, elems))
);
forAll(transformFld, i)
{
//cop(field[n++], transformFld[i]);
field[n++] = transformFld[i];
}
}
else
{
Field<point> transformFld
(
transform(vt.R(), Field<point>(field, elems))
);
forAll(transformFld, i)
{
//cop(field[n++], transformFld[i]);
field[n++] = transformFld[i];
}
}
}
}
template<>
void Foam::mapDistribute::applyInverseTransforms
(
const globalIndexAndTransform& globalTransforms,
List<point>& field,
const bool isPosition
) const
{
const List<vectorTensorTransform>& totalTransform =
globalTransforms.transformPermutations();
forAll(totalTransform, trafoI)
{
const vectorTensorTransform& vt = totalTransform[trafoI];
const labelList& elems = transformElements_[trafoI];
label n = transformStart_[trafoI];
// Could be optimised to avoid memory allocations
if (isPosition)
{
Field<point> transformFld
(
vt.invTransformPosition
(
SubField<point>(field, elems.size(), n)
)
);
forAll(transformFld, i)
{
field[elems[i]] = transformFld[i];
}
}
else
{
Field<point> transformFld(SubField<point>(field, elems.size(), n));
transform(transformFld, vt.R().T(), transformFld);
forAll(transformFld, i)
{
field[elems[i]] = transformFld[i];
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct null
Foam::mapDistribute::mapDistribute()
:
constructSize_(0),
schedulePtr_()
{}
//- Construct from components //- Construct from components
Foam::mapDistribute::mapDistribute Foam::mapDistribute::mapDistribute
( (
@ -663,7 +798,7 @@ Foam::mapDistribute::mapDistribute
if (debug) if (debug)
{ {
printLayout(globalNumbering.localSize(), compactMap, Pout); printLayout(Pout);
} }
} }
@ -719,7 +854,7 @@ Foam::mapDistribute::mapDistribute
if (debug) if (debug)
{ {
printLayout(globalNumbering.localSize(), compactMap, Pout); printLayout(Pout);
} }
} }
@ -821,10 +956,9 @@ Foam::mapDistribute::mapDistribute
n++; n++;
} }
if (debug) if (debug)
{ {
printLayout(globalNumbering.localSize(), compactMap, Pout); printLayout(Pout);
} }
} }
@ -939,10 +1073,9 @@ Foam::mapDistribute::mapDistribute
} }
} }
if (debug) if (debug)
{ {
printLayout(globalNumbering.localSize(), compactMap, Pout); printLayout(Pout);
} }
} }
@ -958,8 +1091,36 @@ Foam::mapDistribute::mapDistribute(const mapDistribute& map)
{} {}
Foam::mapDistribute::mapDistribute(const Xfer<mapDistribute>& map)
:
constructSize_(map().constructSize_),
subMap_(map().subMap_.xfer()),
constructMap_(map().constructMap_.xfer()),
transformElements_(map().transformElements_.xfer()),
transformStart_(map().transformStart_.xfer()),
schedulePtr_()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::mapDistribute::transfer(mapDistribute& rhs)
{
constructSize_ = rhs.constructSize_;
subMap_.transfer(rhs.subMap_);
constructMap_.transfer(rhs.constructMap_);
transformElements_.transfer(rhs.transformElements_);
transformStart_.transfer(rhs.transformStart_);
schedulePtr_.clear();
}
Foam::Xfer<Foam::mapDistribute> Foam::mapDistribute::xfer()
{
return xferMove(*this);
}
Foam::label Foam::mapDistribute::renumber Foam::label Foam::mapDistribute::renumber
( (
const globalIndex& globalNumbering, const globalIndex& globalNumbering,

View File

@ -35,19 +35,88 @@ Note:
Schedule is a list of processor pairs (one send, one receive. One of Schedule is a list of processor pairs (one send, one receive. One of
them will be myself) which forms a scheduled (i.e. non-buffered) exchange. them will be myself) which forms a scheduled (i.e. non-buffered) exchange.
See distribute on how to use it. See distribute on how to use it.
Note2: number of items send on one processor have to equal the number Note2: number of items sent on one processor have to equal the number
of items received on the other processor. of items received on the other processor.
Constructors using compact numbering: all my own elements first To aid constructing these maps there are the constructors from global
(whether used or not) followed by used-only remote elements. numbering, either with or without transforms.
- without transforms:
Constructors using compact numbering: layout is
- all my own elements first (whether used or not)
- followed by used-only remote elements sorted by remote processor.
So e.g 4 procs and on proc 1 the compact So e.g 4 procs and on proc 1 the compact
table will first have all globalIndex.localSize() elements from proc1 table will first have all globalIndex.localSize() elements from proc1
followed by used-only elements of proc0, proc2, proc3. followed by used-only elements of proc0, proc2, proc3.
The constructed mapDistribute sends the local elements from and The constructed mapDistribute sends the local elements from and
receives the remote elements into their compact position. receives the remote elements into their compact position.
compactMap[procI] is the position of elements from procI in the compact compactMap[procI] is the position of elements from procI in the compact
map. compactMap[myProcNo()] is empty since trivial addressing. The indices map. compactMap[myProcNo()] is empty since trivial addressing.
into compactMap[procI] are local, not global, indices.
It rewrites the input global indices into indices into the constructed
data.
- with transforms:
This requires the precalculated set of possible transforms
(globalIndexAndTransform). These are given as permutations (+, -, or none)
of up to 3 independent transforms.
The layout of the data is
- all my own elements first (whether used or not)
- followed by used-only remote elements sorted by remote processor.
- followed by - for each transformation index - the set of local or
remote elements with that transformation.
The inputs for the constructor are
- the set of untransformed local or remote indices in globalIndex
numbering. These get rewritten to be indices into the layout of the data.
- the set of transformed local or remote indices in globalIndexAndTransform
encoding. These are labelPairs.
Any distribute with transforms is now done as:
1. exchange data with other processors and receive these into the
slots for that processor
2. for all transformations transform a subset of the data according
to transformElements_[transformI] and store this starting from
transformStart_[transformI]
In the same way a reverse distribute will
1. apply the inverse transform to the data starting at
transformStart_[transformI] and copy the result back into the
transformElements_[transformI]. These might be local or remote slots.
2. the data in the remote slots will now be sent back to the correct
location in the originating processor.
E.g. a map to handle
- mesh points on a mesh with
- 1 cyclic so 3 permutations (+,-,none) will have layout
- on e.g. processor 1 out of 2:
+------+ <- transformStart[2]
| |
| | <- transform2 applied to data in local or remote slots
| |
+------+ <- transformStart[1]
| |
| | <- transform1 applied to data in local or remote slots
| |
+------+ <- transformStart[1]
| |
| | <- transform0 applied to data in local or remote slots
| |
+------+ <- transformStart[0]
| |
| | <- data from proc2
| |
+------+
| |
| | <- data from proc0
| |
+------+ <- mesh.nPoints()
| |
| |
| |
+------+ 0
SourceFiles SourceFiles
mapDistribute.C mapDistribute.C
@ -63,6 +132,7 @@ SourceFiles
#include "Pstream.H" #include "Pstream.H"
#include "boolList.H" #include "boolList.H"
#include "Map.H" #include "Map.H"
#include "point.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -114,13 +184,6 @@ class mapDistribute
const label receivedSize const label receivedSize
); );
void printLayout
(
const label localSize,
List<Map<label> >& compactMap,
Ostream& os
) const;
void calcCompactAddressing void calcCompactAddressing
( (
const globalIndex& globalNumbering, const globalIndex& globalNumbering,
@ -152,23 +215,28 @@ class mapDistribute
//- Helper function: copy transformElements without transformation //- Helper function: copy transformElements without transformation
template<class T> template<class T>
void copyElements(List<T>& field) const; void applyDummyTransforms(List<T>& field) const;
template<class T, class CombineOp> template<class T> //, class CombineOp>
void applyTransforms void applyTransforms
( (
const globalIndexAndTransform& globalTransforms, const globalIndexAndTransform& globalTransforms,
List<T>& field, List<T>& field,
const bool isPosition, const bool isPosition
const CombineOp& cop //const CombineOp& cop
) const; ) const;
template<class T, class CombineOp>
//- Helper function: copy transformElements without transformation
template<class T>
void applyDummyInverseTransforms(List<T>& field) const;
template<class T> //, class CombineOp>
void applyInverseTransforms void applyInverseTransforms
( (
const globalIndexAndTransform& globalTransforms, const globalIndexAndTransform& globalTransforms,
List<T>& field, List<T>& field,
const bool isPosition, const bool isPosition
const CombineOp& cop //const CombineOp& cop
) const; ) const;
@ -180,6 +248,9 @@ public:
// Constructors // Constructors
//- Construct null
mapDistribute();
//- Construct from components //- Construct from components
mapDistribute mapDistribute
( (
@ -217,8 +288,20 @@ public:
List<Map<label> >& compactMap List<Map<label> >& compactMap
); );
//- Construct from list of (possibly) remote elements in globalIndex //- Special variant that works with the info sorted into bins
// numbering (or -1). Determines compact numbering (see above) and // according to local indices. E.g. think cellCells where
// cellCells[localCellI] is a list of global cells
mapDistribute
(
const globalIndex&,
labelListList& cellCells,
List<Map<label> >& compactMap
);
//- Construct from list of (possibly remote) untransformed elements
// in globalIndex numbering (or -1) and (possibly remote)
// transformded elements in globalIndexAndTransform numbering.
// Determines compact numbering (see above) and
// distribute map to get data into this ordering and renumbers the // distribute map to get data into this ordering and renumbers the
// elements to be in compact numbering. // elements to be in compact numbering.
mapDistribute mapDistribute
@ -231,27 +314,20 @@ public:
List<Map<label> >& compactMap List<Map<label> >& compactMap
); );
//- Special variant that works with the info sorted into bins //- As above but with ListLists.
// according to local indices. E.g. think cellCells where
// cellCells[localCellI] is a list of global cells
mapDistribute mapDistribute
( (
const globalIndex&, const globalIndex&,
labelListList& cellCells, labelListList& cellCells,
List<Map<label> >& compactMap const globalIndexAndTransform&,
);
//- As above but with transformed elements as well
mapDistribute
(
const globalIndex&,
labelListList& cellCells,
const globalIndexAndTransform& ,
const List<labelPairList>& transformedElements, const List<labelPairList>& transformedElements,
labelListList& transformedIndices, labelListList& transformedIndices,
List<Map<label> >& compactMap List<Map<label> >& compactMap
); );
//- Construct by transferring parameter content
mapDistribute(const Xfer<mapDistribute>&);
//- Construct copy //- Construct copy
mapDistribute(const mapDistribute&); mapDistribute(const mapDistribute&);
@ -296,6 +372,19 @@ public:
return constructMap_; return constructMap_;
} }
//- For every globalIndexAndTransform::transformPermutations
// gives the elements that need to be transformed
const labelListList& transformElements() const
{
return transformElements_;
}
//- Destination in constructMap for transformed elements
const labelList& transformStart() const
{
return transformStart_;
}
//- Calculate a schedule. See above. //- Calculate a schedule. See above.
static List<labelPair> schedule static List<labelPair> schedule
( (
@ -309,6 +398,12 @@ public:
// Other // Other
//- Transfer the contents of the argument and annul the argument.
void transfer(mapDistribute&);
//- Transfer contents to the Xfer container
Xfer<mapDistribute> xfer();
//- Helper for construct from globalIndex. Renumbers element //- Helper for construct from globalIndex. Renumbers element
// (in globalIndex numbering) into compact indices. // (in globalIndex numbering) into compact indices.
static label renumber static label renumber
@ -354,7 +449,8 @@ public:
//- Distribute data using default commsType. //- Distribute data using default commsType.
template<class T> template<class T>
void distribute(List<T>& fld) const; void distribute(List<T>& fld, const bool dummyTransform = true)
const;
//- Same but with transforms //- Same but with transforms
template<class T> template<class T>
@ -367,7 +463,12 @@ public:
//- Reverse distribute data using default commsType. //- Reverse distribute data using default commsType.
template<class T> template<class T>
void reverseDistribute(const label constructSize, List<T>&) const; void reverseDistribute
(
const label constructSize,
List<T>&,
const bool dummyTransform = true
) const;
//- Same but with transforms //- Same but with transforms
template<class T> template<class T>
@ -387,7 +488,8 @@ public:
( (
const label constructSize, const label constructSize,
const T& nullValue, const T& nullValue,
List<T>& fld List<T>& fld,
const bool dummyTransform = true
) const; ) const;
//- Same but with transforms //- Same but with transforms
@ -408,6 +510,9 @@ public:
template<class T> template<class T>
void receive(PstreamBuffers&, List<T>&) const; void receive(PstreamBuffers&, List<T>&) const;
//- Debug: print layout
void printLayout(Ostream& os) const;
//- Correct for topo change. //- Correct for topo change.
void updateMesh(const mapPolyMesh&) void updateMesh(const mapPolyMesh&)
{ {
@ -423,6 +528,24 @@ public:
}; };
//- Specialisation for transforms that can apply positional transform
template<>
void mapDistribute::applyTransforms
(
const globalIndexAndTransform& globalTransforms,
List<point>& field,
const bool isPosition
//const CombineOp& cop
) const;
template<> //, class CombineOp>
void mapDistribute::applyInverseTransforms
(
const globalIndexAndTransform& globalTransforms,
List<point>& field,
const bool isPosition
//const CombineOp& cop
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -27,6 +27,7 @@ License
#include "PstreamBuffers.H" #include "PstreamBuffers.H"
#include "PstreamCombineReduceOps.H" #include "PstreamCombineReduceOps.H"
#include "globalIndexAndTransform.H" #include "globalIndexAndTransform.H"
#include "transformField.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -777,7 +778,7 @@ void Foam::mapDistribute::receive(PstreamBuffers& pBufs, List<T>& field) const
// In case of no transform: copy elements // In case of no transform: copy elements
template<class T> template<class T>
void Foam::mapDistribute::copyElements(List<T>& field) const void Foam::mapDistribute::applyDummyTransforms(List<T>& field) const
{ {
forAll(transformElements_, trafoI) forAll(transformElements_, trafoI)
{ {
@ -793,58 +794,48 @@ void Foam::mapDistribute::copyElements(List<T>& field) const
} }
// Calculate transformed elements. // In case of no transform: copy elements
template<class T, class CombineOp> template<class T>
void Foam::mapDistribute::applyTransforms void Foam::mapDistribute::applyDummyInverseTransforms(List<T>& field) const
(
const globalIndexAndTransform& globalTransforms,
List<T>& field,
const bool isPosition,
const CombineOp& cop
) const
{ {
const List<vectorTensorTransform>& totalTransform = forAll(transformElements_, trafoI)
globalTransforms.transformPermutations();
forAll(totalTransform, trafoI)
{ {
const vectorTensorTransform& vt = totalTransform[trafoI];
const labelList& elems = transformElements_[trafoI]; const labelList& elems = transformElements_[trafoI];
label n = transformStart_[trafoI]; label n = transformStart_[trafoI];
// Could be optimised to avoid memory allocations forAll(elems, i)
if (isPosition)
{ {
Field<T> transformFld(vt.transformPosition(Field<T>(field, elems))); field[elems[i]] = field[n++];
forAll(transformFld, i)
{
cop(field[n++], transformFld[i]);
}
}
else
{
Field<T> transformFld(transform(vt.R(), Field<T>(field, elems)));
forAll(transformFld, i)
{
cop(field[n++], transformFld[i]);
}
} }
} }
} }
// Calculate transformed elements. // Calculate transformed elements.
template<class T, class CombineOp> template<class T> //, class CombineOp>
void Foam::mapDistribute::applyInverseTransforms void Foam::mapDistribute::applyTransforms
( (
const globalIndexAndTransform& globalTransforms, const globalIndexAndTransform& globalTransforms,
List<T>& field, List<T>& field,
const bool isPosition, const bool isPosition
const CombineOp& cop //const CombineOp& cop
) const ) const
{ {
if (isPosition)
{
FatalErrorIn
(
"mapDistribute::applyTransforms\n"
"(\n"
" const globalIndexAndTransform&,\n"
" List<T>&,\n"
" const bool\n"
") const\n"
) << "It does not make sense to apply position transformation"
<< " for anything else than pointFields."
<< abort(FatalError);
}
const List<vectorTensorTransform>& totalTransform = const List<vectorTensorTransform>& totalTransform =
globalTransforms.transformPermutations(); globalTransforms.transformPermutations();
@ -855,36 +846,59 @@ void Foam::mapDistribute::applyInverseTransforms
label n = transformStart_[trafoI]; label n = transformStart_[trafoI];
// Could be optimised to avoid memory allocations // Could be optimised to avoid memory allocations
Field<T> transformFld(transform(vt.R(), Field<T>(field, elems)));
if (isPosition) forAll(transformFld, i)
{ {
Field<T> transformFld //cop(field[n++], transformFld[i]);
( field[n++] = transformFld[i];
vt.invTransformPosition
(
SubField<T>(field, n, elems.size())
)
);
forAll(transformFld, i)
{
cop(field[elems[i]], transformFld[i]);
}
} }
else }
{ }
Field<T> transformFld
(
transform
(
vt.R().T(),
SubField<T>(field, n, elems)
)
);
forAll(transformFld, i)
{ // Calculate transformed elements.
cop(field[elems[i]], transformFld[i]); template<class T> //, class CombineOp>
} void Foam::mapDistribute::applyInverseTransforms
(
const globalIndexAndTransform& globalTransforms,
List<T>& field,
const bool isPosition
//const CombineOp& cop
) const
{
if (isPosition)
{
FatalErrorIn
(
"mapDistribute::applyInverseTransforms\n"
"(\n"
" const globalIndexAndTransform&,\n"
" List<T>&,\n"
" const bool\n"
") const\n"
) << "It does not make sense to apply position transformation"
<< " for anything else than pointFields."
<< abort(FatalError);
}
const List<vectorTensorTransform>& totalTransform =
globalTransforms.transformPermutations();
forAll(totalTransform, trafoI)
{
const vectorTensorTransform& vt = totalTransform[trafoI];
const labelList& elems = transformElements_[trafoI];
label n = transformStart_[trafoI];
// Could be optimised to avoid memory allocations
Field<T> transformFld(SubField<T>(field, elems.size(), n));
transform(transformFld, vt.R().T(), transformFld);
forAll(transformFld, i)
{
//cop(field[elems[i]], transformFld[i]);
field[elems[i]] = transformFld[i];
} }
} }
} }
@ -892,7 +906,11 @@ void Foam::mapDistribute::applyInverseTransforms
//- Distribute data using default commsType. //- Distribute data using default commsType.
template<class T> template<class T>
void Foam::mapDistribute::distribute(List<T>& fld) const void Foam::mapDistribute::distribute
(
List<T>& fld,
const bool dummyTransform
) const
{ {
if (Pstream::defaultCommsType == Pstream::nonBlocking) if (Pstream::defaultCommsType == Pstream::nonBlocking)
{ {
@ -930,6 +948,12 @@ void Foam::mapDistribute::distribute(List<T>& fld) const
fld fld
); );
} }
//- Fill in transformed slots with copies
if (dummyTransform)
{
applyDummyTransforms(fld);
}
} }
@ -938,9 +962,17 @@ template<class T>
void Foam::mapDistribute::reverseDistribute void Foam::mapDistribute::reverseDistribute
( (
const label constructSize, const label constructSize,
List<T>& fld List<T>& fld,
const bool dummyTransform
) const ) const
{ {
fld.setSize(constructSize);
if (dummyTransform)
{
applyDummyInverseTransforms(fld);
}
if (Pstream::defaultCommsType == Pstream::nonBlocking) if (Pstream::defaultCommsType == Pstream::nonBlocking)
{ {
distribute distribute
@ -988,9 +1020,17 @@ void Foam::mapDistribute::reverseDistribute
( (
const label constructSize, const label constructSize,
const T& nullValue, const T& nullValue,
List<T>& fld List<T>& fld,
const bool dummyTransform
) const ) const
{ {
fld.setSize(constructSize);
if (dummyTransform)
{
applyDummyInverseTransforms(fld);
}
if (Pstream::defaultCommsType == Pstream::nonBlocking) if (Pstream::defaultCommsType == Pstream::nonBlocking)
{ {
distribute distribute
@ -1045,8 +1085,10 @@ void Foam::mapDistribute::distribute
const bool isPosition const bool isPosition
) const ) const
{ {
distribute(fld); // Distribute. Leave out dummy transforms since we're doing them ourselves
applyTransforms(git, fld, isPosition, eqOp<T>()); distribute(fld, false);
// Do transforms
applyTransforms(git, fld, isPosition); //, eqOp<T>());
} }
@ -1059,13 +1101,13 @@ void Foam::mapDistribute::reverseDistribute
const bool isPosition const bool isPosition
) const ) const
{ {
fld.setSize(constructSize); // Fill slots with reverse-transformed data. Note that it also copies
// back into the non-remote part of fld even though these values are not
// used.
applyInverseTransforms(git, fld, isPosition); //, eqOp<T>());
// Fill slots with reverse-transformed data // And send back (the remote slots). Disable dummy transformations.
applyInverseTransforms(git, fld, isPosition, eqOp<T>()); reverseDistribute(constructSize, fld, false);
// And send back
reverseDistribute(constructSize, fld);
} }
@ -1079,13 +1121,13 @@ void Foam::mapDistribute::reverseDistribute
const bool isPosition const bool isPosition
) const ) const
{ {
fld = List<T>(constructSize, nullValue); // Fill slots with reverse-transformed data Note that it also copies
// back into the non-remote part of fld even though these values are not
// used.
applyInverseTransforms(git, fld, isPosition); //, eqOp<T>());
// Fill slots with reverse-transformed data // And send back (the remote slots) Disable dummy transformations.
applyInverseTransforms(git, fld, isPosition, eqOp<T>()); reverseDistribute(constructSize, nullValue, fld, false);
// And send back
reverseDistribute(constructSize, fld);
} }

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-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -24,7 +24,6 @@ License
\*----------------------------------------------------------------------------*/ \*----------------------------------------------------------------------------*/
#include "syncTools.H" #include "syncTools.H"
#include "polyMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -99,24 +98,6 @@ void Foam::syncTools::transform::operator()
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Does anyone have couples? Since meshes might have 0 cells and 0 proc
// boundaries need to reduce this info.
bool Foam::syncTools::hasCouples(const polyBoundaryMesh& patches)
{
bool hasAnyCouples = false;
forAll(patches, patchI)
{
if (patches[patchI].coupled())
{
hasAnyCouples = true;
break;
}
}
return returnReduce(hasAnyCouples, orOp<bool>());
}
// Determines for every point whether it is coupled and if so sets only one. // Determines for every point whether it is coupled and if so sets only one.
Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh) Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
{ {
@ -125,12 +106,21 @@ Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
const globalMeshData& globalData = mesh.globalData(); const globalMeshData& globalData = mesh.globalData();
const labelList& meshPoints = globalData.coupledPatch().meshPoints(); const labelList& meshPoints = globalData.coupledPatch().meshPoints();
const labelListList& pointSlaves = globalData.globalPointAllSlaves(); const labelListList& slaves = globalData.globalPointSlaves();
const labelListList& transformedSlaves =
globalData.globalPointTransformedSlaves();
forAll(meshPoints, coupledPointI) forAll(meshPoints, coupledPointI)
{ {
label meshPointI = meshPoints[coupledPointI]; label meshPointI = meshPoints[coupledPointI];
if (pointSlaves[coupledPointI].size() > 0) if
(
(
slaves[coupledPointI].size()
+ transformedSlaves[coupledPointI].size()
)
> 0
)
{ {
isMasterPoint[meshPointI] = true; isMasterPoint[meshPointI] = true;
} }
@ -161,12 +151,21 @@ Foam::PackedBoolList Foam::syncTools::getMasterEdges(const polyMesh& mesh)
const globalMeshData& globalData = mesh.globalData(); const globalMeshData& globalData = mesh.globalData();
const labelList& meshEdges = globalData.coupledPatchMeshEdges(); const labelList& meshEdges = globalData.coupledPatchMeshEdges();
const labelListList& edgeSlaves = globalData.globalEdgeAllSlaves(); const labelListList& slaves = globalData.globalEdgeSlaves();
const labelListList& transformedSlaves =
globalData.globalEdgeTransformedSlaves();
forAll(meshEdges, coupledEdgeI) forAll(meshEdges, coupledEdgeI)
{ {
label meshEdgeI = meshEdges[coupledEdgeI]; label meshEdgeI = meshEdges[coupledEdgeI];
if (edgeSlaves[coupledEdgeI].size() > 0) if
(
(
slaves[coupledEdgeI].size()
+ transformedSlaves[coupledEdgeI].size()
)
> 0
)
{ {
isMasterEdge[meshEdgeI] = true; isMasterEdge[meshEdgeI] = true;
} }

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-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -33,12 +33,6 @@ Description
- null value which gets overridden by any valid value. - null value which gets overridden by any valid value.
- transform function - transform function
note:Can apply coordinate rotation/separation on cyclics but only for faces
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
syncToolsTemplates.C syncToolsTemplates.C
@ -48,9 +42,7 @@ SourceFiles
#ifndef syncTools_H #ifndef syncTools_H
#define syncTools_H #define syncTools_H
#include "UList.H"
#include "Pstream.H" #include "Pstream.H"
#include "Map.H"
#include "EdgeMap.H" #include "EdgeMap.H"
#include "PackedBoolList.H" #include "PackedBoolList.H"
#include "polyMesh.H" #include "polyMesh.H"
@ -72,9 +64,6 @@ class syncTools
{ {
// Private Member Functions // Private Member Functions
//- Check whether uses couples.
static bool hasCouples(const polyBoundaryMesh&);
//- Combine value with existing value in map. //- Combine value with existing value in map.
template <class T, class CombineOp> template <class T, class CombineOp>
static void combine static void combine
@ -174,41 +163,41 @@ public:
const CombineOp& cop, const CombineOp& cop,
const TransformOp& top const TransformOp& top
); );
//
//- Synchronize values on all mesh points. // //- Synchronize values on all mesh points.
template <class T, class CombineOp, class TransformOp> // template <class T, class CombineOp, class TransformOp>
static void syncPointList // static void syncPointList
( // (
const polyMesh&, // const polyMesh&,
UList<T>&, // UList<T>&,
const CombineOp& cop, // const CombineOp& cop,
const T& nullValue, // const T& nullValue,
const TransformOp& top // const TransformOp& top
); // );
//
//- Synchronize values on selected mesh points. // //- Synchronize values on selected mesh points.
template <class T, class CombineOp, class TransformOp> // template <class T, class CombineOp, class TransformOp>
static void syncPointList // static void syncPointList
( // (
const polyMesh&, // const polyMesh&,
const labelList& meshPoints, // const labelList& meshPoints,
UList<T>&, // UList<T>&,
const CombineOp& cop, // const CombineOp& cop,
const T& nullValue, // const T& nullValue,
const TransformOp& top // const TransformOp& top
); // );
//
//- Synchronize values on all mesh edges. // //- Synchronize values on all mesh edges.
template <class T, class CombineOp, class TransformOp> // template <class T, class CombineOp, class TransformOp>
static void syncEdgeList // static void syncEdgeList
( // (
const polyMesh&, // const polyMesh&,
UList<T>&, // UList<T>&,
const CombineOp& cop, // const CombineOp& cop,
const T& nullValue, // const T& nullValue,
const TransformOp& top // const TransformOp& top
); // );
//
//- Synchronize values on boundary faces only. //- Synchronize values on boundary faces only.
template <class T, class CombineOp, class TransformOp> template <class T, class CombineOp, class TransformOp>
static void syncBoundaryFaceList static void syncBoundaryFaceList
@ -227,26 +216,20 @@ public:
static void syncPointList static void syncPointList
( (
const polyMesh& mesh, const polyMesh& mesh,
UList<T>& l, List<T>& l,
const CombineOp& cop, const CombineOp& cop,
const T& nullValue const T& nullValue
) );
{
syncPointList(mesh, l, cop, nullValue, transform());
}
//- Synchronize locations on all mesh points. //- Synchronize locations on all mesh points.
template <class CombineOp> template <class CombineOp>
static void syncPointPositions static void syncPointPositions
( (
const polyMesh& mesh, const polyMesh& mesh,
UList<point>& l, List<point>& l,
const CombineOp& cop, const CombineOp& cop,
const point& nullValue const point& nullValue
) );
{
syncPointList(mesh, l, cop, nullValue, transformPosition());
}
//- Synchronize values on selected mesh points. //- Synchronize values on selected mesh points.
template <class T, class CombineOp> template <class T, class CombineOp>
@ -257,18 +240,7 @@ public:
UList<T>& l, UList<T>& l,
const CombineOp& cop, const CombineOp& cop,
const T& nullValue const T& nullValue
) );
{
syncPointList
(
mesh,
meshPoints,
l,
cop,
nullValue,
transform()
);
}
//- Synchronize locations on selected mesh points. //- Synchronize locations on selected mesh points.
template <class CombineOp> template <class CombineOp>
@ -279,18 +251,7 @@ public:
UList<point>& l, UList<point>& l,
const CombineOp& cop, const CombineOp& cop,
const point& nullValue const point& nullValue
) );
{
syncPointList
(
mesh,
meshPoints,
l,
cop,
nullValue,
transformPosition()
);
}
// Synchronise edge-wise data // Synchronise edge-wise data
@ -303,10 +264,7 @@ public:
UList<T>& l, UList<T>& l,
const CombineOp& cop, const CombineOp& cop,
const T& nullValue const T& nullValue
) );
{
syncEdgeList(mesh, l, cop, nullValue, transform());
}
//- Synchronize values on all mesh edges. //- Synchronize values on all mesh edges.
template <class CombineOp> template <class CombineOp>
@ -316,10 +274,7 @@ public:
UList<point>& l, UList<point>& l,
const CombineOp& cop, const CombineOp& cop,
const point& nullValue const point& nullValue
) );
{
syncEdgeList(mesh, l, cop, nullValue, transformPosition());
}
// Synchronise face-wise data // Synchronise face-wise data

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-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -32,8 +32,6 @@ License
#include "transform.H" #include "transform.H"
#include "transformList.H" #include "transformList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Combine val with existing value at index // Combine val with existing value at index
@ -93,11 +91,6 @@ void Foam::syncTools::syncPointMap
{ {
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun()) if (Pstream::parRun())
{ {
PstreamBuffers pBufs(Pstream::nonBlocking); PstreamBuffers pBufs(Pstream::nonBlocking);
@ -398,11 +391,6 @@ void Foam::syncTools::syncEdgeMap
{ {
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
// Do synchronisation without constructing globalEdge addressing // Do synchronisation without constructing globalEdge addressing
// (since this constructs mesh edge addressing) // (since this constructs mesh edge addressing)
@ -767,14 +755,232 @@ void Foam::syncTools::syncEdgeMap
} }
template <class T, class CombineOp, class TransformOp> //template <class T, class CombineOp, class TransformOp>
//void Foam::syncTools::syncPointList
//(
// const polyMesh& mesh,
// UList<T>& pointValues,
// const CombineOp& cop,
// const T& nullValue,
// const TransformOp& top
//)
//{
// if (pointValues.size() != mesh.nPoints())
// {
// FatalErrorIn
// (
// "syncTools<class T, class CombineOp>::syncPointList"
// "(const polyMesh&, UList<T>&, const CombineOp&, const T&"
// ", const bool)"
// ) << "Number of values " << pointValues.size()
// << " is not equal to the number of points in the mesh "
// << mesh.nPoints() << abort(FatalError);
// }
//
// const polyBoundaryMesh& patches = mesh.boundaryMesh();
//
//
// if (Pstream::parRun())
// {
// PstreamBuffers pBufs(Pstream::nonBlocking);
//
// // Send
//
// forAll(patches, patchI)
// {
// if
// (
// isA<processorPolyPatch>(patches[patchI])
// && patches[patchI].nPoints() > 0
// )
// {
// const processorPolyPatch& procPatch =
// refCast<const processorPolyPatch>(patches[patchI]);
//
// // Get data per patchPoint in neighbouring point numbers.
// Field<T> patchInfo(procPatch.nPoints());
//
// const labelList& meshPts = procPatch.meshPoints();
// const labelList& nbrPts = procPatch.neighbPoints();
//
// forAll(nbrPts, pointI)
// {
// label nbrPointI = nbrPts[pointI];
// patchInfo[nbrPointI] = pointValues[meshPts[pointI]];
// }
//
// UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
// toNbr << patchInfo;
// }
// }
//
// pBufs.finishedSends();
//
// // Receive and combine.
//
// forAll(patches, patchI)
// {
// if
// (
// isA<processorPolyPatch>(patches[patchI])
// && patches[patchI].nPoints() > 0
// )
// {
// const processorPolyPatch& procPatch =
// refCast<const processorPolyPatch>(patches[patchI]);
//
// Field<T> nbrPatchInfo(procPatch.nPoints());
// {
// UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
// fromNbr >> nbrPatchInfo;
// }
//
// // Transform to this side
// top(procPatch, nbrPatchInfo);
//
// const labelList& meshPts = procPatch.meshPoints();
//
// forAll(meshPts, pointI)
// {
// label meshPointI = meshPts[pointI];
// cop(pointValues[meshPointI], nbrPatchInfo[pointI]);
// }
// }
// }
// }
//
// // Do the cyclics.
// forAll(patches, patchI)
// {
// if (isA<cyclicPolyPatch>(patches[patchI]))
// {
// const cyclicPolyPatch& cycPatch =
// refCast<const cyclicPolyPatch>(patches[patchI]);
//
// if (cycPatch.owner())
// {
// // Owner does all.
//
// const edgeList& coupledPoints = cycPatch.coupledPoints();
// const labelList& meshPts = cycPatch.meshPoints();
// const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
// const labelList& nbrMeshPoints = nbrPatch.meshPoints();
//
// Field<T> half0Values(coupledPoints.size());
// Field<T> half1Values(coupledPoints.size());
//
// forAll(coupledPoints, i)
// {
// const edge& e = coupledPoints[i];
// half0Values[i] = pointValues[meshPts[e[0]]];
// half1Values[i] = pointValues[nbrMeshPoints[e[1]]];
// }
//
// //SubField<T> slice0(half0Values, half0Values.size());
// //SubField<T> slice1(half1Values, half1Values.size());
// //top(cycPatch, reinterpret_cast<Field<T>&>(slice1));
// //top(nbrPatch, reinterpret_cast<Field<T>&>(slice0));
//
// top(cycPatch, half1Values);
// top(nbrPatch, half0Values);
//
// forAll(coupledPoints, i)
// {
// const edge& e = coupledPoints[i];
// cop(pointValues[meshPts[e[0]]], half1Values[i]);
// cop(pointValues[nbrMeshPoints[e[1]]], half0Values[i]);
// }
// }
// }
// }
//
// // Synchronize multiple shared points.
// const globalMeshData& pd = mesh.globalData();
//
// if (pd.nGlobalPoints() > 0)
// {
// // Values on shared points.
// Field<T> sharedPts(pd.nGlobalPoints(), nullValue);
//
// forAll(pd.sharedPointLabels(), i)
// {
// label meshPointI = pd.sharedPointLabels()[i];
// // Fill my entries in the shared points
// sharedPts[pd.sharedPointAddr()[i]] = pointValues[meshPointI];
// }
//
// // Combine on master.
// Pstream::listCombineGather(sharedPts, cop);
// Pstream::listCombineScatter(sharedPts);
//
// // Now we will all have the same information. Merge it back with
// // my local information.
// forAll(pd.sharedPointLabels(), i)
// {
// label meshPointI = pd.sharedPointLabels()[i];
// pointValues[meshPointI] = sharedPts[pd.sharedPointAddr()[i]];
// }
// }
//}
//template <class T, class CombineOp, class TransformOp>
//void Foam::syncTools::syncPointList
//(
// const polyMesh& mesh,
// const labelList& meshPoints,
// UList<T>& pointValues,
// const CombineOp& cop,
// const T& nullValue,
// const TransformOp& top
//)
//{
// if (pointValues.size() != meshPoints.size())
// {
// FatalErrorIn
// (
// "syncTools<class T, class CombineOp>::syncPointList"
// "(const polyMesh&, const labelList&, UList<T>&, const CombineOp&"
// ", const T&, const bool)"
// ) << "Number of values " << pointValues.size()
// << " is not equal to the number of points "
// << meshPoints.size() << abort(FatalError);
// }
//
// if (!hasCouples(mesh.boundaryMesh()))
// {
// return;
// }
//
// Field<T> meshValues(mesh.nPoints(), nullValue);
//
// forAll(meshPoints, i)
// {
// meshValues[meshPoints[i]] = pointValues[i];
// }
//
// syncTools::syncPointList
// (
// mesh,
// meshValues,
// cop, // combine op
// nullValue, // null value
// top // position or field
// );
//
// forAll(meshPoints, i)
// {
// pointValues[i] = meshValues[meshPoints[i]];
// }
//}
template <class T, class CombineOp>
void Foam::syncTools::syncPointList void Foam::syncTools::syncPointList
( (
const polyMesh& mesh, const polyMesh& mesh,
UList<T>& pointValues, List<T>& pointValues,
const CombineOp& cop, const CombineOp& cop,
const T& nullValue, const T& nullValue
const TransformOp& top
) )
{ {
if (pointValues.size() != mesh.nPoints()) if (pointValues.size() != mesh.nPoints())
@ -782,173 +988,48 @@ void Foam::syncTools::syncPointList
FatalErrorIn FatalErrorIn
( (
"syncTools<class T, class CombineOp>::syncPointList" "syncTools<class T, class CombineOp>::syncPointList"
"(const polyMesh&, UList<T>&, const CombineOp&, const T&" "(const polyMesh&, UList<T>&, const CombineOp&, const T&)"
", const bool)"
) << "Number of values " << pointValues.size() ) << "Number of values " << pointValues.size()
<< " is not equal to the number of points in the mesh " << " is not equal to the number of points in the mesh "
<< mesh.nPoints() << abort(FatalError); << mesh.nPoints() << abort(FatalError);
} }
const polyBoundaryMesh& patches = mesh.boundaryMesh(); mesh.globalData().syncPointData(pointValues, cop, false);
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun())
{
PstreamBuffers pBufs(Pstream::nonBlocking);
// Send
forAll(patches, patchI)
{
if
(
isA<processorPolyPatch>(patches[patchI])
&& patches[patchI].nPoints() > 0
)
{
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(patches[patchI]);
// Get data per patchPoint in neighbouring point numbers.
Field<T> patchInfo(procPatch.nPoints());
const labelList& meshPts = procPatch.meshPoints();
const labelList& nbrPts = procPatch.neighbPoints();
forAll(nbrPts, pointI)
{
label nbrPointI = nbrPts[pointI];
patchInfo[nbrPointI] = pointValues[meshPts[pointI]];
}
UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
toNbr << patchInfo;
}
}
pBufs.finishedSends();
// Receive and combine.
forAll(patches, patchI)
{
if
(
isA<processorPolyPatch>(patches[patchI])
&& patches[patchI].nPoints() > 0
)
{
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(patches[patchI]);
Field<T> nbrPatchInfo(procPatch.nPoints());
{
UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
fromNbr >> nbrPatchInfo;
}
// Transform to this side
top(procPatch, nbrPatchInfo);
const labelList& meshPts = procPatch.meshPoints();
forAll(meshPts, pointI)
{
label meshPointI = meshPts[pointI];
cop(pointValues[meshPointI], nbrPatchInfo[pointI]);
}
}
}
}
// Do the cyclics.
forAll(patches, patchI)
{
if (isA<cyclicPolyPatch>(patches[patchI]))
{
const cyclicPolyPatch& cycPatch =
refCast<const cyclicPolyPatch>(patches[patchI]);
if (cycPatch.owner())
{
// Owner does all.
const edgeList& coupledPoints = cycPatch.coupledPoints();
const labelList& meshPts = cycPatch.meshPoints();
const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
const labelList& nbrMeshPoints = nbrPatch.meshPoints();
Field<T> half0Values(coupledPoints.size());
Field<T> half1Values(coupledPoints.size());
forAll(coupledPoints, i)
{
const edge& e = coupledPoints[i];
half0Values[i] = pointValues[meshPts[e[0]]];
half1Values[i] = pointValues[nbrMeshPoints[e[1]]];
}
//SubField<T> slice0(half0Values, half0Values.size());
//SubField<T> slice1(half1Values, half1Values.size());
//top(cycPatch, reinterpret_cast<Field<T>&>(slice1));
//top(nbrPatch, reinterpret_cast<Field<T>&>(slice0));
top(cycPatch, half1Values);
top(nbrPatch, half0Values);
forAll(coupledPoints, i)
{
const edge& e = coupledPoints[i];
cop(pointValues[meshPts[e[0]]], half1Values[i]);
cop(pointValues[nbrMeshPoints[e[1]]], half0Values[i]);
}
}
}
}
// Synchronize multiple shared points.
const globalMeshData& pd = mesh.globalData();
if (pd.nGlobalPoints() > 0)
{
// Values on shared points.
Field<T> sharedPts(pd.nGlobalPoints(), nullValue);
forAll(pd.sharedPointLabels(), i)
{
label meshPointI = pd.sharedPointLabels()[i];
// Fill my entries in the shared points
sharedPts[pd.sharedPointAddr()[i]] = pointValues[meshPointI];
}
// Combine on master.
Pstream::listCombineGather(sharedPts, cop);
Pstream::listCombineScatter(sharedPts);
// Now we will all have the same information. Merge it back with
// my local information.
forAll(pd.sharedPointLabels(), i)
{
label meshPointI = pd.sharedPointLabels()[i];
pointValues[meshPointI] = sharedPts[pd.sharedPointAddr()[i]];
}
}
} }
template <class T, class CombineOp, class TransformOp> template <class CombineOp>
void Foam::syncTools::syncPointPositions
(
const polyMesh& mesh,
List<point>& pointValues,
const CombineOp& cop,
const point& nullValue
)
{
if (pointValues.size() != mesh.nPoints())
{
FatalErrorIn
(
"syncTools<class CombineOp>::syncPointPositions"
"(const polyMesh&, List<point>&, const CombineOp&, const point&)"
) << "Number of values " << pointValues.size()
<< " is not equal to the number of points in the mesh "
<< mesh.nPoints() << abort(FatalError);
}
mesh.globalData().syncPointData(pointValues, cop, true);
}
template <class T, class CombineOp>
void Foam::syncTools::syncPointList void Foam::syncTools::syncPointList
( (
const polyMesh& mesh, const polyMesh& mesh,
const labelList& meshPoints, const labelList& meshPoints,
UList<T>& pointValues, UList<T>& pointValues,
const CombineOp& cop, const CombineOp& cop,
const T& nullValue, const T& nullValue
const TransformOp& top
) )
{ {
if (pointValues.size() != meshPoints.size()) if (pointValues.size() != meshPoints.size())
@ -956,49 +1037,116 @@ void Foam::syncTools::syncPointList
FatalErrorIn FatalErrorIn
( (
"syncTools<class T, class CombineOp>::syncPointList" "syncTools<class T, class CombineOp>::syncPointList"
"(const polyMesh&, const labelList&, UList<T>&, const CombineOp&" "(const polyMesh&, UList<T>&, const CombineOp&, const T&)"
", const T&, const bool)"
) << "Number of values " << pointValues.size() ) << "Number of values " << pointValues.size()
<< " is not equal to the number of points " << " is not equal to the number of meshPoints "
<< meshPoints.size() << abort(FatalError); << meshPoints.size() << abort(FatalError);
} }
const globalMeshData& gd = mesh.globalData();
const indirectPrimitivePatch& cpp = gd.coupledPatch();
const Map<label>& mpm = cpp.meshPointMap();
if (!hasCouples(mesh.boundaryMesh())) List<T> cppFld(cpp.nPoints(), nullValue);
{
return;
}
Field<T> meshValues(mesh.nPoints(), nullValue);
forAll(meshPoints, i) forAll(meshPoints, i)
{ {
meshValues[meshPoints[i]] = pointValues[i]; label pointI = meshPoints[i];
Map<label>::const_iterator iter = mpm.find(pointI);
if (iter != mpm.end())
{
cppFld[iter()] = pointValues[i];
}
} }
syncTools::syncPointList globalMeshData::syncData
( (
mesh, cppFld,
meshValues, gd.globalPointSlaves(),
cop, // combine op gd.globalPointTransformedSlaves(),
nullValue, // null value gd.globalPointSlavesMap(),
top // position or field gd.globalTransforms(),
cop,
false //position?
); );
forAll(meshPoints, i) forAll(meshPoints, i)
{ {
pointValues[i] = meshValues[meshPoints[i]]; label pointI = meshPoints[i];
Map<label>::const_iterator iter = mpm.find(pointI);
if (iter != mpm.end())
{
pointValues[i] = cppFld[iter()];
}
} }
} }
template <class T, class CombineOp, class TransformOp> template <class CombineOp>
void Foam::syncTools::syncPointPositions
(
const polyMesh& mesh,
const labelList& meshPoints,
UList<point>& pointValues,
const CombineOp& cop,
const point& nullValue
)
{
if (pointValues.size() != meshPoints.size())
{
FatalErrorIn
(
"syncTools<class CombineOp>::syncPointList"
"(const polyMesh&, UList<point>&, const CombineOp&, const point&)"
) << "Number of values " << pointValues.size()
<< " is not equal to the number of meshPoints "
<< meshPoints.size() << abort(FatalError);
}
const globalMeshData& gd = mesh.globalData();
const indirectPrimitivePatch& cpp = gd.coupledPatch();
const Map<label>& mpm = cpp.meshPointMap();
List<point> cppFld(cpp.nPoints(), nullValue);
forAll(meshPoints, i)
{
label pointI = meshPoints[i];
Map<label>::const_iterator iter = mpm.find(pointI);
if (iter != mpm.end())
{
cppFld[iter()] = pointValues[i];
}
}
globalMeshData::syncData
(
cppFld,
gd.globalPointSlaves(),
gd.globalPointTransformedSlaves(),
gd.globalPointSlavesMap(),
gd.globalTransforms(),
cop,
true //position?
);
forAll(meshPoints, i)
{
label pointI = meshPoints[i];
Map<label>::const_iterator iter = mpm.find(pointI);
if (iter != mpm.end())
{
pointValues[i] = cppFld[iter()];
}
}
}
template <class T, class CombineOp>
void Foam::syncTools::syncEdgeList void Foam::syncTools::syncEdgeList
( (
const polyMesh& mesh, const polyMesh& mesh,
UList<T>& edgeValues, UList<T>& edgeValues,
const CombineOp& cop, const CombineOp& cop,
const T& nullValue, const T& nullValue
const TransformOp& top
) )
{ {
if (edgeValues.size() != mesh.nEdges()) if (edgeValues.size() != mesh.nEdges())
@ -1006,168 +1154,78 @@ void Foam::syncTools::syncEdgeList
FatalErrorIn FatalErrorIn
( (
"syncTools<class T, class CombineOp>::syncEdgeList" "syncTools<class T, class CombineOp>::syncEdgeList"
"(const polyMesh&, UList<T>&, const CombineOp&, const T&" "(const polyMesh&, UList<T>&, const CombineOp&, const T&)"
", const bool)"
) << "Number of values " << edgeValues.size() ) << "Number of values " << edgeValues.size()
<< " is not equal to the number of edges in the mesh " << " is not equal to the number of edges in the mesh "
<< mesh.nEdges() << abort(FatalError); << mesh.nEdges() << abort(FatalError);
} }
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const globalMeshData& gd = mesh.globalData();
const labelList& meshEdges = gd.coupledPatchMeshEdges();
const globalIndexAndTransform& git = gd.globalTransforms();
const mapDistribute& edgeMap = gd.globalEdgeSlavesMap();
if (!hasCouples(patches)) List<T> cppFld(UIndirectList<T>(edgeValues, meshEdges));
globalMeshData::syncData
(
cppFld,
gd.globalEdgeSlaves(),
gd.globalEdgeTransformedSlaves(),
edgeMap,
git,
cop,
false //position?
);
// Extract back onto mesh
forAll(meshEdges, i)
{ {
return; edgeValues[meshEdges[i]] = cppFld[i];
}
}
template <class CombineOp>
void Foam::syncTools::syncEdgePositions
(
const polyMesh& mesh,
UList<point>& edgeValues,
const CombineOp& cop,
const point& nullValue
)
{
if (edgeValues.size() != mesh.nEdges())
{
FatalErrorIn
(
"syncTools<class CombineOp>::syncEdgePositions"
"(const polyMesh&, UList<point>&, const CombineOp&, const point&)"
) << "Number of values " << edgeValues.size()
<< " is not equal to the number of edges in the mesh "
<< mesh.nEdges() << abort(FatalError);
} }
if (Pstream::parRun()) const globalMeshData& gd = mesh.globalData();
const labelList& meshEdges = gd.coupledPatchMeshEdges();
List<point> cppFld(UIndirectList<point>(edgeValues, meshEdges));
globalMeshData::syncData
(
cppFld,
gd.globalEdgeSlaves(),
gd.globalEdgeTransformedSlaves(),
gd.globalEdgeSlavesMap(),
gd.globalTransforms(),
cop,
true //position?
);
// Extract back onto mesh
forAll(meshEdges, i)
{ {
PstreamBuffers pBufs(Pstream::nonBlocking); edgeValues[meshEdges[i]] = cppFld[i];
// Send
forAll(patches, patchI)
{
if
(
isA<processorPolyPatch>(patches[patchI])
&& patches[patchI].nEdges() > 0
)
{
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(patches[patchI]);
const labelList& meshEdges = procPatch.meshEdges();
const labelList& neighbEdges = procPatch.neighbEdges();
// Get region per patch edge in neighbouring edge numbers.
Field<T> patchInfo(procPatch.nEdges(), nullValue);
forAll(neighbEdges, edgeI)
{
label nbrEdgeI = neighbEdges[edgeI];
patchInfo[nbrEdgeI] = edgeValues[meshEdges[edgeI]];
}
UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
toNbr << patchInfo;
}
}
pBufs.finishedSends();
// Receive and combine.
forAll(patches, patchI)
{
if
(
isA<processorPolyPatch>(patches[patchI])
&& patches[patchI].nEdges() > 0
)
{
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(patches[patchI]);
const labelList& meshEdges = procPatch.meshEdges();
// Receive from neighbour. Is per patch edge the region of the
// neighbouring patch edge.
Field<T> nbrPatchInfo(procPatch.nEdges());
{
UIPstream fromNeighb(procPatch.neighbProcNo(), pBufs);
fromNeighb >> nbrPatchInfo;
}
// Transform to this side
top(procPatch, nbrPatchInfo);
forAll(meshEdges, edgeI)
{
label meshEdgeI = meshEdges[edgeI];
cop(edgeValues[meshEdgeI], nbrPatchInfo[edgeI]);
}
}
}
}
// Do the cyclics.
forAll(patches, patchI)
{
if (isA<cyclicPolyPatch>(patches[patchI]))
{
const cyclicPolyPatch& cycPatch =
refCast<const cyclicPolyPatch>(patches[patchI]);
if (cycPatch.owner())
{
// Owner does all.
const edgeList& coupledEdges = cycPatch.coupledEdges();
const labelList& meshEdges = cycPatch.meshEdges();
const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
const labelList& nbrMeshEdges = nbrPatch.meshEdges();
Field<T> half0Values(coupledEdges.size());
Field<T> half1Values(coupledEdges.size());
forAll(coupledEdges, i)
{
const edge& e = coupledEdges[i];
half0Values[i] = edgeValues[meshEdges[e[0]]];
half1Values[i] = edgeValues[nbrMeshEdges[e[1]]];
}
//SubField<T> slice0(half0Values, half0Values.size());
//SubField<T> slice1(half1Values, half1Values.size());
//top(cycPatch, reinterpret_cast<Field<T>&>(slice1));
//top(nbrPatch, reinterpret_cast<Field<T>&>(slice0));
top(cycPatch, half1Values);
top(nbrPatch, half0Values);
forAll(coupledEdges, i)
{
const edge& e = coupledEdges[i];
cop(edgeValues[meshEdges[e[0]]], half1Values[i]);
cop(edgeValues[nbrMeshEdges[e[1]]], half0Values[i]);
}
}
}
}
//- Note: hasTransformation is only used for warning messages so
// reduction not strictly nessecary.
//reduce(hasTransformation, orOp<bool>());
// Do the multiple shared edges
const globalMeshData& pd = mesh.globalData();
if (pd.nGlobalEdges() > 0)
{
// Values on shared edges.
Field<T> sharedPts(pd.nGlobalEdges(), nullValue);
forAll(pd.sharedEdgeLabels(), i)
{
label meshEdgeI = pd.sharedEdgeLabels()[i];
// Fill my entries in the shared edges
sharedPts[pd.sharedEdgeAddr()[i]] = edgeValues[meshEdgeI];
}
// Combine on master.
Pstream::listCombineGather(sharedPts, cop);
Pstream::listCombineScatter(sharedPts);
// Now we will all have the same information. Merge it back with
// my local information.
forAll(pd.sharedEdgeLabels(), i)
{
label meshEdgeI = pd.sharedEdgeLabels()[i];
edgeValues[meshEdgeI] = sharedPts[pd.sharedEdgeAddr()[i]];
}
} }
} }
@ -1197,12 +1255,6 @@ void Foam::syncTools::syncBoundaryFaceList
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun()) if (Pstream::parRun())
{ {
PstreamBuffers pBufs(Pstream::nonBlocking); PstreamBuffers pBufs(Pstream::nonBlocking);
@ -1223,13 +1275,7 @@ void Foam::syncTools::syncBoundaryFaceList
label patchStart = procPatch.start()-mesh.nInternalFaces(); label patchStart = procPatch.start()-mesh.nInternalFaces();
UOPstream toNbr(procPatch.neighbProcNo(), pBufs); UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
toNbr << toNbr << SubField<T>(faceValues, procPatch.size(), patchStart);
SubField<T>
(
faceValues,
procPatch.size(),
patchStart
);
} }
} }
@ -1331,11 +1377,6 @@ void Foam::syncTools::syncFaceList
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun()) if (Pstream::parRun())
{ {
PstreamBuffers pBufs(Pstream::nonBlocking); PstreamBuffers pBufs(Pstream::nonBlocking);
@ -1466,11 +1507,6 @@ void Foam::syncTools::syncPointList
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun()) if (Pstream::parRun())
{ {
PstreamBuffers pBufs(Pstream::nonBlocking); PstreamBuffers pBufs(Pstream::nonBlocking);
@ -1630,11 +1666,6 @@ void Foam::syncTools::syncEdgeList
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun()) if (Pstream::parRun())
{ {
PstreamBuffers pBufs(Pstream::nonBlocking); PstreamBuffers pBufs(Pstream::nonBlocking);

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-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -104,8 +104,7 @@ Foam::labelListList Foam::addPatchCellLayer::calcGlobalEdgeFaces
mesh, mesh,
globalEdgeFaces, globalEdgeFaces,
uniqueEqOp(), uniqueEqOp(),
labelList(), // null value labelList() // null value
Foam::dummyTransform() // dummy transform
); );
// Extract pp part // Extract pp part

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-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -39,6 +39,104 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type, class CombineOp>
void volPointInterpolation::syncUntransformedData
(
List<Type>& pointData,
const CombineOp& cop
) const
{
// Transfer onto coupled patch
const globalMeshData& gmd = mesh().globalData();
const indirectPrimitivePatch& cpp = gmd.coupledPatch();
const labelList& meshPoints = cpp.meshPoints();
const mapDistribute& slavesMap = gmd.globalPointSlavesMap();
const labelListList& slaves = gmd.globalPointSlaves();
List<Type> elems(slavesMap.constructSize());
forAll(meshPoints, i)
{
elems[i] = pointData[meshPoints[i]];
}
// Pull slave data onto master. No need to update transformed slots.
slavesMap.distribute(elems, false);
// Combine master data with slave data
forAll(slaves, i)
{
Type& elem = elems[i];
const labelList& slavePoints = slaves[i];
// Combine master with untransformed slave data
forAll(slavePoints, j)
{
cop(elem, elems[slavePoints[j]]);
}
// Copy result back to slave slots
forAll(slavePoints, j)
{
elems[slavePoints[j]] = elem;
}
}
// Push slave-slot data back to slaves
slavesMap.reverseDistribute(elems.size(), elems, false);
// Extract back onto mesh
forAll(meshPoints, i)
{
pointData[meshPoints[i]] = elems[i];
}
}
template<class Type>
void volPointInterpolation::pushUntransformedData
(
List<Type>& pointData
) const
{
// Transfer onto coupled patch
const globalMeshData& gmd = mesh().globalData();
const indirectPrimitivePatch& cpp = gmd.coupledPatch();
const labelList& meshPoints = cpp.meshPoints();
const mapDistribute& slavesMap = gmd.globalPointSlavesMap();
const labelListList& slaves = gmd.globalPointSlaves();
List<Type> elems(slavesMap.constructSize());
forAll(meshPoints, i)
{
elems[i] = pointData[meshPoints[i]];
}
// Combine master data with slave data
forAll(slaves, i)
{
const labelList& slavePoints = slaves[i];
// Copy master data to slave slots
forAll(slaves, j)
{
elems[slavePoints[j]] = elems[i];
}
}
// Push slave-slot data back to slaves
slavesMap.reverseDistribute(elems.size(), elems, false);
// Extract back onto mesh
forAll(meshPoints, i)
{
pointData[meshPoints[i]] = elems[i];
}
}
template<class Type> template<class Type>
void volPointInterpolation::addSeparated void volPointInterpolation::addSeparated
( (
@ -204,7 +302,8 @@ void volPointInterpolation::interpolateBoundaryField
} }
// Sum collocated contributions // Sum collocated contributions
mesh().globalData().syncPointData(pfi, plusEqOp<Type>()); //mesh().globalData().syncPointData(pfi, plusEqOp<Type>());
syncUntransformedData(pfi, plusEqOp<Type>());
// And add separated contributions // And add separated contributions
addSeparated(pf); addSeparated(pf);
@ -213,7 +312,8 @@ void volPointInterpolation::interpolateBoundaryField
// a coupled point to have its master on a different patch so // a coupled point to have its master on a different patch so
// to make sure just push master data to slaves. Reuse the syncPointData // to make sure just push master data to slaves. Reuse the syncPointData
// structure. // structure.
mesh().globalData().syncPointData(pfi, nopEqOp<Type>()); //mesh().globalData().syncPointData(pfi, nopEqOp<Type>());
pushUntransformedData(pfi);
@ -238,7 +338,8 @@ void volPointInterpolation::interpolateBoundaryField
pf.correctBoundaryConditions(); pf.correctBoundaryConditions();
// Sync any dangling points // Sync any dangling points
mesh().globalData().syncPointData(pfi, nopEqOp<Type>()); //mesh().globalData().syncPointData(pfi, nopEqOp<Type>());
pushUntransformedData(pfi);
// Apply multiple constraints on edge/corner points // Apply multiple constraints on edge/corner points
applyCornerConstraints(pf); applyCornerConstraints(pf);

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-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -101,10 +101,11 @@ void volPointInterpolation::calcBoundaryAddressing()
// no face of a certain patch still can have boundary points marked. // no face of a certain patch still can have boundary points marked.
if (debug) if (debug)
{ {
boolList oldData(isPatchPoint_); boolList oldData(isPatchPoint_);
mesh().globalData().syncPointData(isPatchPoint_, orEqOp<bool>()); //mesh().globalData().syncPointData(isPatchPoint_, orEqOp<bool>());
syncUntransformedData(isPatchPoint_, orEqOp<bool>());
forAll(isPatchPoint_, pointI) forAll(isPatchPoint_, pointI)
{ {
@ -281,7 +282,8 @@ void volPointInterpolation::makeWeights()
// Sum collocated contributions // Sum collocated contributions
mesh().globalData().syncPointData(sumWeights, plusEqOp<scalar>()); //mesh().globalData().syncPointData(sumWeights, plusEqOp<scalar>());
syncUntransformedData(sumWeights, plusEqOp<scalar>());
// And add separated contributions // And add separated contributions
addSeparated(sumWeights); addSeparated(sumWeights);
@ -290,7 +292,8 @@ void volPointInterpolation::makeWeights()
// a coupled point to have its master on a different patch so // a coupled point to have its master on a different patch so
// to make sure just push master data to slaves. Reuse the syncPointData // to make sure just push master data to slaves. Reuse the syncPointData
// structure. // structure.
mesh().globalData().syncPointData(sumWeights, nopEqOp<scalar>()); //mesh().globalData().syncPointData(sumWeights, nopEqOp<scalar>());
pushUntransformedData(sumWeights);
// Normalise internal weights // Normalise internal weights

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-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -105,6 +105,18 @@ class volPointInterpolation
//- Make patch-patch constraints //- Make patch-patch constraints
void makePatchPatchAddressing(); void makePatchPatchAddressing();
//- Helper: sync data on collocated points only
template<class Type, class CombineOp>
void syncUntransformedData
(
List<Type>& pointData,
const CombineOp& cop
) const;
//- Helper: push master point data to collocated points
template<class Type>
void pushUntransformedData(List<Type>&) const;
//- Get boundary field in same order as boundary faces. Field is //- Get boundary field in same order as boundary faces. Field is
// zero on all coupled and empty patches // zero on all coupled and empty patches
template<class Type> template<class Type>