PatchToolsGatherAndMerge.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2012-2018 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "PatchTools.H"
27 #include "polyMesh.H"
28 #include "globalMeshData.H"
29 #include "mergePoints.H"
30 
31 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
32 
33 template
34 <
35  class Face,
36  template<class> class FaceList,
37  class PointField,
38  class PointType
39 >
41 (
42  const scalar mergeDist,
44  Field<PointType>& mergedPoints,
45  List<Face>& mergedFaces,
46  labelList& pointMergeMap
47 )
48 {
49  // Collect points from all processors
50  labelList pointSizes;
51  {
52  List<Field<PointType>> gatheredPoints(Pstream::nProcs());
53  gatheredPoints[Pstream::myProcNo()] = p.points();
54 
55  Pstream::gatherList(gatheredPoints);
56 
57  if (Pstream::master())
58  {
59  pointSizes = ListListOps::subSizes
60  (
61  gatheredPoints,
63  );
64 
65  mergedPoints = ListListOps::combine<Field<PointType>>
66  (
67  gatheredPoints,
69  );
70  }
71  }
72 
73  // Collect faces from all processors and renumber using sizes of
74  // gathered points
75  {
76  List<List<Face>> gatheredFaces(Pstream::nProcs());
77  gatheredFaces[Pstream::myProcNo()] = p;
78  Pstream::gatherList(gatheredFaces);
79 
80  if (Pstream::master())
81  {
82  mergedFaces = static_cast<const List<Face>&>
83  (
84  ListListOps::combineOffset<List<Face>>
85  (
86  gatheredFaces,
87  pointSizes,
90  )
91  );
92  }
93  }
94 
95  if (Pstream::master())
96  {
97  Field<PointType> newPoints;
98  labelList oldToNew;
99 
100  bool hasMerged = mergePoints
101  (
102  mergedPoints,
103  mergeDist,
104  false, // verbosity
105  oldToNew,
106  newPoints
107  );
108 
109  if (hasMerged)
110  {
111  // Store point mapping
112  pointMergeMap.transfer(oldToNew);
113 
114  // Copy points
115  mergedPoints.transfer(newPoints);
116 
117  // Relabel faces
118  List<Face>& faces = mergedFaces;
119 
120  forAll(faces, facei)
121  {
122  inplaceRenumber(pointMergeMap, faces[facei]);
123  }
124  }
125  }
126 }
127 
128 
129 template<class FaceList>
131 (
132  const polyMesh& mesh,
133  const FaceList& localFaces,
134  const labelList& meshPoints,
135  const Map<label>& meshPointMap,
136 
137  labelList& pointToGlobal,
138  labelList& uniqueMeshPointLabels,
139  autoPtr<globalIndex>& globalPointsPtr,
140  autoPtr<globalIndex>& globalFacesPtr,
142  pointField& mergedPoints
143 )
144 {
145  typedef typename FaceList::value_type FaceType;
146 
147  if (Pstream::parRun())
148  {
149  // Renumber the setPatch points/faces into unique points
150  globalPointsPtr = mesh.globalData().mergePoints
151  (
152  meshPoints,
153  meshPointMap,
154  pointToGlobal,
155  uniqueMeshPointLabels
156  );
157 
158  globalFacesPtr.reset(new globalIndex(localFaces.size()));
159 
160  if (Pstream::master())
161  {
162  // Get renumbered local data
163  pointField myPoints(mesh.points(), uniqueMeshPointLabels);
164  List<FaceType> myFaces(localFaces);
165  forAll(myFaces, i)
166  {
167  inplaceRenumber(pointToGlobal, myFaces[i]);
168  }
169 
170 
171  mergedFaces.setSize(globalFacesPtr().size());
172  mergedPoints.setSize(globalPointsPtr().size());
173 
174  // Insert master data first
175  label pOffset = globalPointsPtr().offset(Pstream::masterNo());
176  SubList<point>(mergedPoints, myPoints.size(), pOffset) = myPoints;
177 
178  label fOffset = globalFacesPtr().offset(Pstream::masterNo());
179  SubList<FaceType>(mergedFaces, myFaces.size(), fOffset) = myFaces;
180 
181 
182  // Receive slave ones
183  for (int slave=1; slave<Pstream::nProcs(); slave++)
184  {
185  IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
186 
187  pointField slavePoints(fromSlave);
188  List<FaceType> slaveFaces(fromSlave);
189 
190  label pOffset = globalPointsPtr().offset(slave);
191  SubList<point>(mergedPoints, slavePoints.size(), pOffset) =
192  slavePoints;
193 
194  label fOffset = globalFacesPtr().offset(slave);
195  SubList<FaceType>(mergedFaces, slaveFaces.size(), fOffset) =
196  slaveFaces;
197  }
198  }
199  else
200  {
201  // Get renumbered local data
202  pointField myPoints(mesh.points(), uniqueMeshPointLabels);
203  List<FaceType> myFaces(localFaces);
204  forAll(myFaces, i)
205  {
206  inplaceRenumber(pointToGlobal, myFaces[i]);
207  }
208 
209  // Construct processor stream with estimate of size. Could
210  // be improved.
211  OPstream toMaster
212  (
213  Pstream::commsTypes::scheduled,
214  Pstream::masterNo(),
215  myPoints.byteSize() + 4*sizeof(label)*myFaces.size()
216  );
217  toMaster << myPoints << myFaces;
218  }
219  }
220  else
221  {
222  pointToGlobal = identity(meshPoints.size());
223  uniqueMeshPointLabels = pointToGlobal;
224 
225  globalPointsPtr.reset(new globalIndex(meshPoints.size()));
226  globalFacesPtr.reset(new globalIndex(localFaces.size()));
227 
228  mergedFaces = localFaces;
229  mergedPoints = pointField(mesh.points(), meshPoints);
230  }
231 }
232 
233 
234 // ************************************************************************* //
static void gatherAndMerge(const scalar mergeDist, const PrimitivePatch< Face, FaceList, PointField, PointType > &p, Field< PointType > &mergedPoints, List< Face > &mergedFaces, labelList &pointMergeMap)
Gather points and faces onto master and merge into single patch.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void inplaceRenumber(const labelUList &oldToNew, ListType &)
Inplace renumber the values of a list.
void reset(T *=nullptr)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
autoPtr< globalIndex > mergePoints(labelList &pointToGlobal, labelList &uniquePoints) const
Helper for merging (collocated!) mesh point data.
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1003
Input inter-processor communications stream.
Definition: IPstream.H:50
A list of faces which address into the list of points.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
const Field< PointType > & points() const
Return reference to global points.
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1174
labelList subSizes(const List< T > &, AccessOp aop=accessOp< T >())
Gets sizes of sublists.
Definition: ListListOps.C:61
Merge points. See below.
Output inter-processor communications stream.
Definition: OPstream.H:50
void setSize(const label)
Reset size of List.
Definition: List.C:281
label mergePoints(const UList< Type > &points, const scalar mergeTol, const bool verbose, labelList &pointMap, const Type &origin=Type::zero)
Sorts and merges points. All points closer than/equal mergeTol get merged.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:52
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
volScalarField & p
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342