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 processorPatches to have their transforms set.
The shared point addressing is quite interesting. It gives on each processor
the vertices that cannot be set using a normal swap on processor patches.
These are the vertices that are shared between more than 2 processors.
The shared point and edge addressing is quite interesting.
It calculates addressing for points and edges on coupled patches. In
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
cyclics (i.e. are now separated processor patches). They will all be
mapped to the same global point (so even though the processor points are
not on the same location) since topologically they are one and the same.
The alternative is to have an exchange schedule (through a 'mapDistribute')
which sends all point/edge data (no distinction is made between
those on two and those on more than two coupled patches) to the local
'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 topologically shared points.
The exchange needs
- 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
that are shared between more than two patches (i.e. the edges on which
data cannot be synchronized by a straightforward edge data swap). Note
that shared edges will use shared points but not all edges between shared
points need to be shared edges (e.g. there might be an edge connecting
two disconnected regions of shared points).
Currently an edge is considered shared
Notes:
- compared to 17x nTotalFaces, nTotalPoints do not compensate for
shared points since this would trigger full connectivity analysis
- most calculation is demand driven and uses parallel communication
so make sure to invoke on all processors at the same time.
- old sharedEdge calculation: currently an edge is considered shared
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
of shared edges. Doing full analysis of how many patches use the edge
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
globalMeshData.C
globalMeshDataTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef globalMeshData_H
#define globalMeshData_H
#include "Switch.H"
#include "processorTopology.H"
#include "labelPair.H"
#include "indirectPrimitivePatch.H"
#include "boundBox.H"
#include "IOobject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -86,13 +90,11 @@ namespace Foam
// Forward declaration of friend functions and operators
class globalMeshData;
Ostream& operator<<(Ostream&, const globalMeshData&);
class globalIndex;
class polyMesh;
class mapDistribute;
template<class T> class EdgeMap;
class globalPoints;
class globalIndex;
class globalIndexAndTransform;
/*---------------------------------------------------------------------------*\
Class globalMeshData Declaration
@ -134,9 +136,6 @@ class globalMeshData
// Data related to the complete mesh
//- Bounding box of complete mesh
boundBox bb_;
//- Total number of points in the complete mesh
label nTotalPoints_;
@ -162,23 +161,70 @@ class globalMeshData
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
//- Total number of global points
label nGlobalPoints_;
mutable label nGlobalPoints_;
//- Indices of local points that are globally shared
labelList sharedPointLabels_;
mutable autoPtr<labelList> sharedPointLabelsPtr_;
//- Indices of globally shared points in the master list
// This list contains all the shared points in the mesh
labelList sharedPointAddr_;
mutable autoPtr<labelList> sharedPointAddrPtr_;
//- Shared point global labels.
// Global point index for every local shared point.
// Only valid if constructed with this information or if
// pointProcAddressing read.
mutable labelList* sharedPointGlobalLabelsPtr_;
mutable autoPtr<labelList> sharedPointGlobalLabelsPtr_;
// Globally shared edge addressing. Derived from shared points.
@ -188,68 +234,11 @@ class globalMeshData
mutable label nGlobalEdges_;
//- Indices of local edges that are globally shared
mutable labelList* sharedEdgeLabelsPtr_;
mutable autoPtr<labelList> sharedEdgeLabelsPtr_;
//- Indices of globally shared edge in the master list
// This list contains all the shared edges in the mesh
mutable 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_;
mutable autoPtr<labelList> sharedEdgeAddrPtr_;
// Private Member Functions
@ -265,70 +254,18 @@ class globalMeshData
label&
);
//- Calculate shared point addressing
void calcSharedPoints() const;
//- Calculate shared edge addressing
void calcSharedEdges() const;
//- Count coincident faces.
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.
//- Calculate global point addressing.
void calcGlobalPointSlaves() const;
//- Calculate global edge addressing.
void calcGlobalEdgeSlaves
(
const labelListList&,
const mapDistribute&,
const globalIndex&,
autoPtr<labelListList>&,
autoPtr<mapDistribute>&
) const;
//- Calculate global edge addressing.
void calcGlobalEdgeSlaves() const;
//- Calculate coupled point to uncoupled boundary faces. Local only.
void calcPointBoundaryFaces(labelListList& pointBoundaryFaces) const;
//- Calculate global point to global boundary face addressing.
void calcGlobalPointBoundaryFaces() const;
//- Calculate global point to global boundary cell addressing.
void calcGlobalPointBoundaryCells() const;
// 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
globalMeshData(const globalMeshData&);
@ -345,7 +282,7 @@ public:
// Static data members
//- Geomtric tolerance (fraction of bounding box)
//- Geomteric tolerance (fraction of bounding box)
static const Foam::scalar matchTol_;
@ -354,10 +291,6 @@ public:
//- Construct from mesh, derive rest (does parallel communication!)
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
~globalMeshData();
@ -383,24 +316,21 @@ public:
return processorPatches_.size() > 0;
}
const boundBox& bb() const
{
return bb_;
}
//- Return total number of points in decomposed mesh
//- Return total number of points in decomposed mesh. Not
// compensated for duplicate points!
label nTotalPoints() const
{
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
{
return nTotalFaces_;
}
//- Return total number of cells in decomposed mesh
//- Return total number of cells in decomposed mesh.
label nTotalCells() const
{
return nTotalCells_;
@ -435,16 +365,10 @@ public:
// Globally shared point addressing
//- Return number of globally shared points
label nGlobalPoints() const
{
return nGlobalPoints_;
}
label nGlobalPoints() const;
//- Return indices of local points that are globally shared
const labelList& sharedPointLabels() const
{
return sharedPointLabels_;
}
const labelList& sharedPointLabels() const;
//- Return addressing into the complete globally shared points
// list
@ -454,10 +378,7 @@ public:
// points. Shared point addressing gives the index in the
// list of all globally shared points for each of the locally
// shared points.
const labelList& sharedPointAddr() const
{
return sharedPointAddr_;
}
const labelList& sharedPointAddr() const;
//- Return shared point global labels. Tries to read
// 'pointProcAddressing' and returns list or -1 if none
@ -512,70 +433,47 @@ public:
//- Return map from mesh edges to coupledPatch edges
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.
//- Numbering of coupled points is according to coupledPatch.
const globalIndex& globalPointNumbering() const;
//- For every coupled point the indices into the field
// distributed by below map.
const labelListList& globalPointSlaves() const;
const labelListList& globalPointTransformedSlaves() const;
const mapDistribute& globalPointSlavesMap() const;
//- Helper to synchronise mesh data
//- Helper to synchronise mesh point data
template<class Type, class CombineOp>
void syncPointData
(
List<Type>& pointData,
const CombineOp& cop
const CombineOp& cop,
const bool isPosition
) const;
// Coupled edge to coupled edges.
const globalIndex& globalEdgeNumbering() const;
const labelListList& globalEdgeSlaves() const;
const labelListList& globalEdgeTransformedSlaves() 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
@ -614,16 +512,6 @@ public:
// full parallel analysis to determine shared points and
// boundaries.
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
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -29,13 +29,73 @@ License
// * * * * * * * * * * * * * * * 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>
void Foam::globalMeshData::syncPointData
(
List<Type>& pointData,
const labelListList& slaves,
const mapDistribute& slavesMap,
const CombineOp& cop
const CombineOp& cop,
const bool isPosition
) const
{
if (pointData.size() != mesh_.nPoints())
@ -46,81 +106,26 @@ void Foam::globalMeshData::syncPointData
<< abort(FatalError);
}
// Transfer onto coupled patch
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
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
syncData
(
pointData,
slaves,
map,
cop
cppFld,
globalPointSlaves(),
globalPointTransformedSlaves(),
globalPointSlavesMap(),
globalTransforms(),
cop,
isPosition
);
}
template<class Type, class CombineOp>
void Foam::globalMeshData::syncPointAllData
(
List<Type>& pointData,
const CombineOp& cop
) const
{
syncPointData
(
pointData,
globalPointAllSlaves(),
globalPointAllSlavesMap(),
cop
);
// Extract back onto mesh
forAll(cpp.meshPoints(), i)
{
pointData[cpp.meshPoints()[i]] = cppFld[i];
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -39,17 +39,15 @@ Description
- f[0] ordering on patch faces to be ok.
Works by constructing equivalence lists for all the points on processor
patches. These list are in globalIndex numbering (so consecutively numbered
per processor)
patches. These list are in globalIndexAndTransform numbering
E.g.
@verbatim
((7 93)(4 731)(3 114))
@endverbatim
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
sharedPoint label from processor0 and it redistributes this label back to
the other processors in the equivalence list.
It then assigns the lowest numbered processor to be the local 'master' and
constructs a mapDistribute to send all data to this master.
Algorithm:
- get meshPoints of all my points on processor patches and initialize
@ -64,24 +62,9 @@ Description
endloop until nothing changes
At this point one will have complete point-point connectivity for all
points on processor patches. Now
- (optional)remove point equivalences of size 2. These are
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.
points on processor patches. Now (optionally) remove point
equivalences of size 2. These are just normal points shared
between two neighbouring procPatches.
Note: the data held is either mesh point labels (construct from mesh only)
or patch point labels (construct from mesh and patch).
@ -95,12 +78,9 @@ SourceFiles
#define globalPoints_H
#include "DynamicList.H"
#include "Map.H"
#include "primitivePatch.H"
#include "edgeList.H"
#include "globalIndex.H"
#include "indirectPrimitivePatch.H"
#include "PackedBoolList.H"
#include "globalIndex.H"
#include "globalIndexAndTransform.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -112,7 +92,7 @@ class polyMesh;
class polyBoundaryMesh;
class cyclicPolyPatch;
class polyPatch;
class coupledPolyPatch;
class mapDistribute;
/*---------------------------------------------------------------------------*\
Class globalPoints Declaration
@ -120,91 +100,85 @@ class coupledPolyPatch;
class globalPoints
{
// Static data members
//- Offset to add to points (in globalIndices) originating from
// collocated coupled points.
static const label fromCollocated;
// Private data
//- Mesh reference
const polyMesh& mesh_;
//- Global numbering of points
//- Global numbering of untransformed points
globalIndex globalIndices_;
//- Global numbering of transformed points
const globalIndexAndTransform globalTransforms_;
//- Sum of points on processor patches (unfiltered, point on 2 patches
// counts as 2)
const label nPatchPoints_;
//- All points on boundaries and their corresponding connected points
// on other processors.
DynamicList<labelList> procPoints_;
DynamicList<labelPairList> procPoints_;
//- Map from mesh (or patch) point to index in procPoints
Map<label> meshToProcPoint_;
//- Shared points used by this processor (= global point number)
labelList sharedPointAddr_;
//- My mesh(or patch) points corresponding to the shared points
labelList sharedPointLabels_;
// Calculated mapDistribute addressing
//- 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
// Wrappers around global point numbering to add collocated bit
//- Convert into globalIndices and add collocated bit
label toGlobal(const label, const bool isCollocated) const;
//- Is collocated bit set
bool isCollocated(const label globalI) const;
//- Remove collocated bit
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;
//- Helper function to sort according minimum proc, minimum index,
// minimum transform
class globalIndexAndTransformLessThan
{
public:
bool operator()
(
const labelPair& a,
const labelPair& b
);
};
//- Count all points on processorPatches. Is all points for which
// information is collected.
static label countPatchPoints(const polyBoundaryMesh&);
labelPairList addSendTransform
(
const label patchI,
const labelPairList& info
) const;
//- Add information about patchPointI in relative indices to send
// buffers (patchFaces, indexInFace etc.)
static void addToSend
void addToSend
(
const primitivePatch&,
const polyPatch&,
const label patchPointI,
const labelList&,
const labelPairList&,
DynamicList<label>& patchFaces,
DynamicList<label>& indexInFace,
DynamicList<labelList>& allInfo
);
DynamicList<labelPairList>& allInfo
) const;
//- Merge info from neighbour into my data
static bool mergeInfo
(
const labelList& nbrInfo,
labelList& myInfo
const labelPairList& nbrInfo,
const label localPointI,
labelPairList& myInfo
);
//- From mesh point to 'local point'. Is the mesh point itself
@ -223,18 +197,26 @@ class globalPoints
);
//- Store (and merge) info for meshPointI
bool storeInfo
bool storeInitialInfo
(
const labelList& nbrInfo,
const label localPointI,
const bool isCollocated
const labelPairList& nbrInfo,
const label localPointI
);
//- 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
(
const labelList& patchToMeshPoint,
const labelList& pointInfo,
Ostream& os
const labelPairList& pointInfo
) const;
//- Initialize procPoints_ to my patch points. allPoints = true:
@ -260,6 +242,7 @@ class globalPoints
(
const bool mergeSeparated,
const Map<label>&,
const labelList&,
PstreamBuffers&,
labelHashSet&
);
@ -268,34 +251,6 @@ class globalPoints
// Used to remove normal face-face connected points.
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.
static labelList reverseMeshPoints(const cyclicPolyPatch&);
@ -325,7 +280,7 @@ public:
//- Construct from mesh.
// 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:
// true : merge coupled points across 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 only is that this stores the meshToProcPoint,
// procPoints and sharedPointLabels as patch local point labels
// instead of mesh point labels.
// procPoints as patch local point labels instead of mesh point labels.
globalPoints
(
const polyMesh& mesh,
@ -353,43 +307,68 @@ public:
// 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
const Map<label>& meshToProcPoint() const
{
return meshToProcPoint_;
}
//- procPoints is per point the connected points (in global
// point numbers)
const DynamicList<labelList>& procPoints() const
//- procPoints is per point the connected points (in
// globalTransformAndIndex point numbers)
const DynamicList<labelPairList>& procPoints() const
{
return procPoints_;
}
//- Global numbering of (mesh or patch) points
const globalIndex& globalIndices() const
{
return globalIndices_;
}
//- shared points used by this processor (= global point number)
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 "globalIndex.H"
#include "globalIndexAndTransform.H"
#include "transformField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -199,35 +200,66 @@ void Foam::mapDistribute::checkReceivedSize
}
void Foam::mapDistribute::printLayout
(
const label localSize,
List<Map<label> >& compactMap,
Ostream& os
) const
void Foam::mapDistribute::printLayout(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
<< "local (processor " << Pstream::myProcNo() << "):" << endl
<< " start : 0" << endl
<< " size : " << localSize << endl;
label offset = localSize;
forAll(compactMap, procI)
forAll(minIndex, procI)
{
if (procI != Pstream::myProcNo())
{
os << "processor " << procI << ':' << endl
<< " start : " << offset << endl
<< " size : " << compactMap[procI].size() << endl;
if (constructMap_[procI].size() > 0)
{
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)
{
os << "transform " << trafoI << ':' << endl
<< " start : " << transformStart_[trafoI] << endl
<< " size : " << transformElements_[trafoI].size() << endl;
if (transformElements_[trafoI].size() > 0)
{
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 * * * * * * * * * * * * * * //
//- Construct null
Foam::mapDistribute::mapDistribute()
:
constructSize_(0),
schedulePtr_()
{}
//- Construct from components
Foam::mapDistribute::mapDistribute
(
@ -663,7 +798,7 @@ Foam::mapDistribute::mapDistribute
if (debug)
{
printLayout(globalNumbering.localSize(), compactMap, Pout);
printLayout(Pout);
}
}
@ -719,7 +854,7 @@ Foam::mapDistribute::mapDistribute
if (debug)
{
printLayout(globalNumbering.localSize(), compactMap, Pout);
printLayout(Pout);
}
}
@ -821,10 +956,9 @@ Foam::mapDistribute::mapDistribute
n++;
}
if (debug)
{
printLayout(globalNumbering.localSize(), compactMap, Pout);
printLayout(Pout);
}
}
@ -939,10 +1073,9 @@ Foam::mapDistribute::mapDistribute
}
}
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 * * * * * * * * * * * * * * //
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
(
const globalIndex& globalNumbering,

View File

@ -35,19 +35,88 @@ Note:
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.
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.
Constructors using compact numbering: all my own elements first
(whether used or not) followed by used-only remote elements.
To aid constructing these maps there are the constructors from global
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
table will first have all globalIndex.localSize() elements from proc1
followed by used-only elements of proc0, proc2, proc3.
The constructed mapDistribute sends the local elements from and
receives the remote elements into their compact position.
compactMap[procI] is the position of elements from procI in the compact
map. compactMap[myProcNo()] is empty since trivial addressing. The indices
into compactMap[procI] are local, not global, indices.
map. compactMap[myProcNo()] is empty since trivial addressing.
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
mapDistribute.C
@ -63,6 +132,7 @@ SourceFiles
#include "Pstream.H"
#include "boolList.H"
#include "Map.H"
#include "point.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -114,13 +184,6 @@ class mapDistribute
const label receivedSize
);
void printLayout
(
const label localSize,
List<Map<label> >& compactMap,
Ostream& os
) const;
void calcCompactAddressing
(
const globalIndex& globalNumbering,
@ -152,23 +215,28 @@ class mapDistribute
//- Helper function: copy transformElements without transformation
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
(
const globalIndexAndTransform& globalTransforms,
List<T>& field,
const bool isPosition,
const CombineOp& cop
const bool isPosition
//const CombineOp& cop
) 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
(
const globalIndexAndTransform& globalTransforms,
List<T>& field,
const bool isPosition,
const CombineOp& cop
const bool isPosition
//const CombineOp& cop
) const;
@ -180,6 +248,9 @@ public:
// Constructors
//- Construct null
mapDistribute();
//- Construct from components
mapDistribute
(
@ -217,8 +288,20 @@ public:
List<Map<label> >& compactMap
);
//- Construct from list of (possibly) remote elements in globalIndex
// numbering (or -1). Determines compact numbering (see above) and
//- Special variant that works with the info sorted into bins
// 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
// elements to be in compact numbering.
mapDistribute
@ -231,27 +314,20 @@ public:
List<Map<label> >& compactMap
);
//- Special variant that works with the info sorted into bins
// according to local indices. E.g. think cellCells where
// cellCells[localCellI] is a list of global cells
//- As above but with ListLists.
mapDistribute
(
const globalIndex&,
labelListList& cellCells,
List<Map<label> >& compactMap
);
//- As above but with transformed elements as well
mapDistribute
(
const globalIndex&,
labelListList& cellCells,
const globalIndexAndTransform& ,
const globalIndexAndTransform&,
const List<labelPairList>& transformedElements,
labelListList& transformedIndices,
List<Map<label> >& compactMap
);
//- Construct by transferring parameter content
mapDistribute(const Xfer<mapDistribute>&);
//- Construct copy
mapDistribute(const mapDistribute&);
@ -296,6 +372,19 @@ public:
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.
static List<labelPair> schedule
(
@ -309,6 +398,12 @@ public:
// 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
// (in globalIndex numbering) into compact indices.
static label renumber
@ -354,7 +449,8 @@ public:
//- Distribute data using default commsType.
template<class T>
void distribute(List<T>& fld) const;
void distribute(List<T>& fld, const bool dummyTransform = true)
const;
//- Same but with transforms
template<class T>
@ -367,7 +463,12 @@ public:
//- Reverse distribute data using default commsType.
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
template<class T>
@ -387,7 +488,8 @@ public:
(
const label constructSize,
const T& nullValue,
List<T>& fld
List<T>& fld,
const bool dummyTransform = true
) const;
//- Same but with transforms
@ -408,6 +510,9 @@ public:
template<class T>
void receive(PstreamBuffers&, List<T>&) const;
//- Debug: print layout
void printLayout(Ostream& os) const;
//- Correct for topo change.
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 "PstreamCombineReduceOps.H"
#include "globalIndexAndTransform.H"
#include "transformField.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -777,7 +778,7 @@ void Foam::mapDistribute::receive(PstreamBuffers& pBufs, List<T>& field) const
// In case of no transform: copy elements
template<class T>
void Foam::mapDistribute::copyElements(List<T>& field) const
void Foam::mapDistribute::applyDummyTransforms(List<T>& field) const
{
forAll(transformElements_, trafoI)
{
@ -793,58 +794,48 @@ void Foam::mapDistribute::copyElements(List<T>& field) const
}
// Calculate transformed elements.
template<class T, class CombineOp>
void Foam::mapDistribute::applyTransforms
(
const globalIndexAndTransform& globalTransforms,
List<T>& field,
const bool isPosition,
const CombineOp& cop
) const
// In case of no transform: copy elements
template<class T>
void Foam::mapDistribute::applyDummyInverseTransforms(List<T>& field) const
{
const List<vectorTensorTransform>& totalTransform =
globalTransforms.transformPermutations();
forAll(totalTransform, trafoI)
forAll(transformElements_, trafoI)
{
const vectorTensorTransform& vt = totalTransform[trafoI];
const labelList& elems = transformElements_[trafoI];
label n = transformStart_[trafoI];
// Could be optimised to avoid memory allocations
if (isPosition)
forAll(elems, i)
{
Field<T> transformFld(vt.transformPosition(Field<T>(field, elems)));
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]);
}
field[elems[i]] = field[n++];
}
}
}
// Calculate transformed elements.
template<class T, class CombineOp>
void Foam::mapDistribute::applyInverseTransforms
template<class T> //, class CombineOp>
void Foam::mapDistribute::applyTransforms
(
const globalIndexAndTransform& globalTransforms,
List<T>& field,
const bool isPosition,
const CombineOp& cop
const bool isPosition
//const CombineOp& cop
) 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 =
globalTransforms.transformPermutations();
@ -855,36 +846,59 @@ void Foam::mapDistribute::applyInverseTransforms
label n = transformStart_[trafoI];
// 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
(
vt.invTransformPosition
(
SubField<T>(field, n, elems.size())
)
);
forAll(transformFld, i)
{
cop(field[elems[i]], transformFld[i]);
}
//cop(field[n++], transformFld[i]);
field[n++] = transformFld[i];
}
else
{
Field<T> transformFld
(
transform
(
vt.R().T(),
SubField<T>(field, n, elems)
)
);
}
}
forAll(transformFld, i)
{
cop(field[elems[i]], transformFld[i]);
}
// Calculate transformed elements.
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.
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)
{
@ -930,6 +948,12 @@ void Foam::mapDistribute::distribute(List<T>& fld) const
fld
);
}
//- Fill in transformed slots with copies
if (dummyTransform)
{
applyDummyTransforms(fld);
}
}
@ -938,9 +962,17 @@ template<class T>
void Foam::mapDistribute::reverseDistribute
(
const label constructSize,
List<T>& fld
List<T>& fld,
const bool dummyTransform
) const
{
fld.setSize(constructSize);
if (dummyTransform)
{
applyDummyInverseTransforms(fld);
}
if (Pstream::defaultCommsType == Pstream::nonBlocking)
{
distribute
@ -988,9 +1020,17 @@ void Foam::mapDistribute::reverseDistribute
(
const label constructSize,
const T& nullValue,
List<T>& fld
List<T>& fld,
const bool dummyTransform
) const
{
fld.setSize(constructSize);
if (dummyTransform)
{
applyDummyInverseTransforms(fld);
}
if (Pstream::defaultCommsType == Pstream::nonBlocking)
{
distribute
@ -1045,8 +1085,10 @@ void Foam::mapDistribute::distribute
const bool isPosition
) const
{
distribute(fld);
applyTransforms(git, fld, isPosition, eqOp<T>());
// Distribute. Leave out dummy transforms since we're doing them ourselves
distribute(fld, false);
// Do transforms
applyTransforms(git, fld, isPosition); //, eqOp<T>());
}
@ -1059,13 +1101,13 @@ void Foam::mapDistribute::reverseDistribute
const bool isPosition
) 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
applyInverseTransforms(git, fld, isPosition, eqOp<T>());
// And send back
reverseDistribute(constructSize, fld);
// And send back (the remote slots). Disable dummy transformations.
reverseDistribute(constructSize, fld, false);
}
@ -1079,13 +1121,13 @@ void Foam::mapDistribute::reverseDistribute
const bool isPosition
) 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
applyInverseTransforms(git, fld, isPosition, eqOp<T>());
// And send back
reverseDistribute(constructSize, fld);
// And send back (the remote slots) Disable dummy transformations.
reverseDistribute(constructSize, nullValue, fld, false);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -24,7 +24,6 @@ License
\*----------------------------------------------------------------------------*/
#include "syncTools.H"
#include "polyMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -99,24 +98,6 @@ void Foam::syncTools::transform::operator()
// * * * * * * * * * * * * * 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.
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 labelList& meshPoints = globalData.coupledPatch().meshPoints();
const labelListList& pointSlaves = globalData.globalPointAllSlaves();
const labelListList& slaves = globalData.globalPointSlaves();
const labelListList& transformedSlaves =
globalData.globalPointTransformedSlaves();
forAll(meshPoints, coupledPointI)
{
label meshPointI = meshPoints[coupledPointI];
if (pointSlaves[coupledPointI].size() > 0)
if
(
(
slaves[coupledPointI].size()
+ transformedSlaves[coupledPointI].size()
)
> 0
)
{
isMasterPoint[meshPointI] = true;
}
@ -161,12 +151,21 @@ Foam::PackedBoolList Foam::syncTools::getMasterEdges(const polyMesh& mesh)
const globalMeshData& globalData = mesh.globalData();
const labelList& meshEdges = globalData.coupledPatchMeshEdges();
const labelListList& edgeSlaves = globalData.globalEdgeAllSlaves();
const labelListList& slaves = globalData.globalEdgeSlaves();
const labelListList& transformedSlaves =
globalData.globalEdgeTransformedSlaves();
forAll(meshEdges, coupledEdgeI)
{
label meshEdgeI = meshEdges[coupledEdgeI];
if (edgeSlaves[coupledEdgeI].size() > 0)
if
(
(
slaves[coupledEdgeI].size()
+ transformedSlaves[coupledEdgeI].size()
)
> 0
)
{
isMasterEdge[meshEdgeI] = true;
}

View File

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

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -32,8 +32,6 @@ License
#include "transform.H"
#include "transformList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Combine val with existing value at index
@ -93,11 +91,6 @@ void Foam::syncTools::syncPointMap
{
const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun())
{
PstreamBuffers pBufs(Pstream::nonBlocking);
@ -398,11 +391,6 @@ void Foam::syncTools::syncEdgeMap
{
const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
// Do synchronisation without constructing globalEdge 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
(
const polyMesh& mesh,
UList<T>& pointValues,
List<T>& pointValues,
const CombineOp& cop,
const T& nullValue,
const TransformOp& top
const T& nullValue
)
{
if (pointValues.size() != mesh.nPoints())
@ -782,173 +988,48 @@ void Foam::syncTools::syncPointList
FatalErrorIn
(
"syncTools<class T, class CombineOp>::syncPointList"
"(const polyMesh&, UList<T>&, const CombineOp&, const T&"
", const bool)"
"(const polyMesh&, UList<T>&, const CombineOp&, const T&)"
) << "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 (!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]];
}
}
mesh.globalData().syncPointData(pointValues, cop, false);
}
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
(
const polyMesh& mesh,
const labelList& meshPoints,
UList<T>& pointValues,
const CombineOp& cop,
const T& nullValue,
const TransformOp& top
const T& nullValue
)
{
if (pointValues.size() != meshPoints.size())
@ -956,49 +1037,116 @@ void Foam::syncTools::syncPointList
FatalErrorIn
(
"syncTools<class T, class CombineOp>::syncPointList"
"(const polyMesh&, const labelList&, UList<T>&, const CombineOp&"
", const T&, const bool)"
"(const polyMesh&, UList<T>&, const CombineOp&, const T&)"
) << "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);
}
const globalMeshData& gd = mesh.globalData();
const indirectPrimitivePatch& cpp = gd.coupledPatch();
const Map<label>& mpm = cpp.meshPointMap();
if (!hasCouples(mesh.boundaryMesh()))
{
return;
}
Field<T> meshValues(mesh.nPoints(), nullValue);
List<T> cppFld(cpp.nPoints(), nullValue);
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,
meshValues,
cop, // combine op
nullValue, // null value
top // position or field
cppFld,
gd.globalPointSlaves(),
gd.globalPointTransformedSlaves(),
gd.globalPointSlavesMap(),
gd.globalTransforms(),
cop,
false //position?
);
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
(
const polyMesh& mesh,
UList<T>& edgeValues,
const CombineOp& cop,
const T& nullValue,
const TransformOp& top
const T& nullValue
)
{
if (edgeValues.size() != mesh.nEdges())
@ -1006,168 +1154,78 @@ void Foam::syncTools::syncEdgeList
FatalErrorIn
(
"syncTools<class T, class CombineOp>::syncEdgeList"
"(const polyMesh&, UList<T>&, const CombineOp&, const T&"
", const bool)"
"(const polyMesh&, UList<T>&, const CombineOp&, const T&)"
) << "Number of values " << edgeValues.size()
<< " is not equal to the number of edges in the mesh "
<< 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);
// 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]];
}
edgeValues[meshEdges[i]] = cppFld[i];
}
}
@ -1197,12 +1255,6 @@ void Foam::syncTools::syncBoundaryFaceList
const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun())
{
PstreamBuffers pBufs(Pstream::nonBlocking);
@ -1223,13 +1275,7 @@ void Foam::syncTools::syncBoundaryFaceList
label patchStart = procPatch.start()-mesh.nInternalFaces();
UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
toNbr <<
SubField<T>
(
faceValues,
procPatch.size(),
patchStart
);
toNbr << SubField<T>(faceValues, procPatch.size(), patchStart);
}
}
@ -1331,11 +1377,6 @@ void Foam::syncTools::syncFaceList
const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun())
{
PstreamBuffers pBufs(Pstream::nonBlocking);
@ -1466,11 +1507,6 @@ void Foam::syncTools::syncPointList
const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun())
{
PstreamBuffers pBufs(Pstream::nonBlocking);
@ -1630,11 +1666,6 @@ void Foam::syncTools::syncEdgeList
const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (!hasCouples(patches))
{
return;
}
if (Pstream::parRun())
{
PstreamBuffers pBufs(Pstream::nonBlocking);

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -104,8 +104,7 @@ Foam::labelListList Foam::addPatchCellLayer::calcGlobalEdgeFaces
mesh,
globalEdgeFaces,
uniqueEqOp(),
labelList(), // null value
Foam::dummyTransform() // dummy transform
labelList() // null value
);
// Extract pp part

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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>
void volPointInterpolation::addSeparated
(
@ -204,7 +302,8 @@ void volPointInterpolation::interpolateBoundaryField
}
// Sum collocated contributions
mesh().globalData().syncPointData(pfi, plusEqOp<Type>());
//mesh().globalData().syncPointData(pfi, plusEqOp<Type>());
syncUntransformedData(pfi, plusEqOp<Type>());
// And add separated contributions
addSeparated(pf);
@ -213,7 +312,8 @@ void volPointInterpolation::interpolateBoundaryField
// a coupled point to have its master on a different patch so
// to make sure just push master data to slaves. Reuse the syncPointData
// structure.
mesh().globalData().syncPointData(pfi, nopEqOp<Type>());
//mesh().globalData().syncPointData(pfi, nopEqOp<Type>());
pushUntransformedData(pfi);
@ -238,7 +338,8 @@ void volPointInterpolation::interpolateBoundaryField
pf.correctBoundaryConditions();
// 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
applyCornerConstraints(pf);

View File

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

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -105,6 +105,18 @@ class volPointInterpolation
//- Make patch-patch constraints
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
// zero on all coupled and empty patches
template<class Type>