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-2019 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<class FaceList, class PointField>
35 (
36  const scalar mergeDist,
39  mergedPoints,
41  labelList& pointMergeMap
42 )
43 {
44  typedef typename PrimitivePatch<FaceList, PointField>::FaceType FaceType;
45  typedef typename PrimitivePatch<FaceList, PointField>::PointType PointType;
46 
47  // Collect points from all processors
48  labelList pointSizes;
49  {
50  List<Field<PointType>> gatheredPoints(Pstream::nProcs());
51  gatheredPoints[Pstream::myProcNo()] = p.points();
52 
53  Pstream::gatherList(gatheredPoints);
54 
55  if (Pstream::master())
56  {
57  pointSizes = ListListOps::subSizes
58  (
59  gatheredPoints,
61  );
62 
63  mergedPoints = ListListOps::combine<Field<PointType>>
64  (
65  gatheredPoints,
67  );
68  }
69  }
70 
71  // Collect faces from all processors and renumber using sizes of
72  // gathered points
73  {
74  List<List<FaceType>> gatheredFaces(Pstream::nProcs());
75  gatheredFaces[Pstream::myProcNo()] = p;
76  Pstream::gatherList(gatheredFaces);
77 
78  if (Pstream::master())
79  {
80  mergedFaces = static_cast<const List<FaceType>&>
81  (
82  ListListOps::combineOffset<List<FaceType>>
83  (
84  gatheredFaces,
85  pointSizes,
88  )
89  );
90  }
91  }
92 
93  if (Pstream::master())
94  {
95  Field<PointType> newPoints;
96  labelList oldToNew;
97 
98  bool hasMerged = mergePoints
99  (
100  mergedPoints,
101  mergeDist,
102  false, // verbosity
103  oldToNew,
104  newPoints
105  );
106 
107  if (hasMerged)
108  {
109  // Store point mapping
110  pointMergeMap.transfer(oldToNew);
111 
112  // Copy points
113  mergedPoints.transfer(newPoints);
114 
115  // Relabel faces
116  List<FaceType>& faces = mergedFaces;
117 
118  forAll(faces, facei)
119  {
120  inplaceRenumber(pointMergeMap, faces[facei]);
121  }
122  }
123  }
124 }
125 
126 
127 template<class FaceList>
129 (
130  const polyMesh& mesh,
131  const FaceList& localFaces,
132  const labelList& meshPoints,
133  const Map<label>& meshPointMap,
134 
135  labelList& pointToGlobal,
136  labelList& uniqueMeshPointLabels,
137  autoPtr<globalIndex>& globalPointsPtr,
138  autoPtr<globalIndex>& globalFacesPtr,
140  pointField& mergedPoints
141 )
142 {
143  typedef typename FaceList::value_type FaceType;
144 
145  if (Pstream::parRun())
146  {
147  // Renumber the setPatch points/faces into unique points
148  globalPointsPtr = mesh.globalData().mergePoints
149  (
150  meshPoints,
151  meshPointMap,
152  pointToGlobal,
153  uniqueMeshPointLabels
154  );
155 
156  globalFacesPtr.reset(new globalIndex(localFaces.size()));
157 
158  if (Pstream::master())
159  {
160  // Get renumbered local data
161  pointField myPoints(mesh.points(), uniqueMeshPointLabels);
162  List<FaceType> myFaces(localFaces);
163  forAll(myFaces, i)
164  {
165  inplaceRenumber(pointToGlobal, myFaces[i]);
166  }
167 
168 
169  mergedFaces.setSize(globalFacesPtr().size());
170  mergedPoints.setSize(globalPointsPtr().size());
171 
172  // Insert master data first
173  label pOffset = globalPointsPtr().offset(Pstream::masterNo());
174  SubList<point>(mergedPoints, myPoints.size(), pOffset) = myPoints;
175 
176  label fOffset = globalFacesPtr().offset(Pstream::masterNo());
177  SubList<FaceType>(mergedFaces, myFaces.size(), fOffset) = myFaces;
178 
179 
180  // Receive slave ones
181  for (int slave=1; slave<Pstream::nProcs(); slave++)
182  {
183  IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
184 
185  pointField slavePoints(fromSlave);
186  List<FaceType> slaveFaces(fromSlave);
187 
188  label pOffset = globalPointsPtr().offset(slave);
189  SubList<point>(mergedPoints, slavePoints.size(), pOffset) =
190  slavePoints;
191 
192  label fOffset = globalFacesPtr().offset(slave);
193  SubList<FaceType>(mergedFaces, slaveFaces.size(), fOffset) =
194  slaveFaces;
195  }
196  }
197  else
198  {
199  // Get renumbered local data
200  pointField myPoints(mesh.points(), uniqueMeshPointLabels);
201  List<FaceType> myFaces(localFaces);
202  forAll(myFaces, i)
203  {
204  inplaceRenumber(pointToGlobal, myFaces[i]);
205  }
206 
207  // Construct processor stream with estimate of size. Could
208  // be improved.
209  OPstream toMaster
210  (
211  Pstream::commsTypes::scheduled,
212  Pstream::masterNo(),
213  myPoints.byteSize() + 4*sizeof(label)*myFaces.size()
214  );
215  toMaster << myPoints << myFaces;
216  }
217  }
218  else
219  {
220  pointToGlobal = identity(meshPoints.size());
221  uniqueMeshPointLabels = pointToGlobal;
222 
223  globalPointsPtr.reset(new globalIndex(meshPoints.size()));
224  globalFacesPtr.reset(new globalIndex(localFaces.size()));
225 
226  mergedFaces = localFaces;
227  mergedPoints = pointField(mesh.points(), meshPoints);
228  }
229 }
230 
231 
232 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
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:1131
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
A List obtained as a section of another List.
Definition: SubList.H:53
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
Pre-declare SubField and related Field type.
Definition: Field.H:56
static void gatherAndMerge(const scalar mergeDist, const PrimitivePatch< FaceList, PointField > &p, Field< typename PrimitivePatch< FaceList, PointField >::PointType > &mergedPoints, List< typename PrimitivePatch< FaceList, PointField >::FaceType > &mergedFaces, labelList &pointMergeMap)
Gather points and faces onto master and merge into single patch.
const Field< PointType > & points() const
Return reference to global points.
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1394
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
std::remove_reference< FaceList >::type::value_type FaceType
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
std::remove_reference< PointField >::type::value_type PointType
volScalarField & p
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342