PatchToolsGatherAndMerge.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2012-2017 OpenFOAM Foundation
9  Copyright (C) 2019-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "PatchTools.H"
30 #include "polyMesh.H"
31 #include "globalMeshData.H"
32 #include "mergePoints.H"
33 
34 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
35 
36 template<class FaceList, class PointField>
38 (
39  const scalar mergeDist,
41  Field
42  <
44  >& mergedPoints,
45  List
46  <
48  >& mergedFaces,
49  globalIndex& pointAddr,
50  globalIndex& faceAddr,
51  labelList& pointMergeMap,
52  const bool useLocal
53 )
54 {
55  typedef typename PrimitivePatch<FaceList, PointField>::face_type FaceType;
56 
57  // Faces from all ranks
58  faceAddr.reset(globalIndex::gatherOnly{}, pp.size());
59 
60  // Points from all ranks
61  pointAddr.reset
62  (
64  (useLocal ? pp.localPoints().size() : pp.points().size())
65  );
66 
67  if (useLocal)
68  {
69  faceAddr.gather(pp.localFaces(), mergedFaces);
70  pointAddr.gather(pp.localPoints(), mergedPoints);
71  }
72  else
73  {
74  faceAddr.gather(pp, mergedFaces);
75  pointAddr.gather(pp.points(), mergedPoints);
76  }
77 
78  // Relabel faces according to global point offsets
79  for (const label proci : faceAddr.subProcs())
80  {
81  SubList<FaceType> slot(mergedFaces, faceAddr.range(proci));
82 
83  for (auto& f : slot)
84  {
85  pointAddr.inplaceToGlobal(proci, f);
86  }
87  }
88 
89 
90  // Merging points
91  label nPointsChanged(0);
92 
93  labelList boundaryPoints;
94 
95  if (UPstream::parRun())
96  {
97  const globalIndex localPointAddr
98  (
100  pp.localPoints().size()
101  );
102 
103  const globalIndex bndPointAddr
104  (
106  pp.boundaryPoints().size()
107  );
108 
109  bndPointAddr.gather(pp.boundaryPoints(), boundaryPoints);
110 
111  // Relabel according to global point offsets
112  for (const label proci : localPointAddr.subProcs())
113  {
114  SubList<label> slot(boundaryPoints, bndPointAddr.range(proci));
115  localPointAddr.inplaceToGlobal(proci, slot);
116  }
117  }
118 
119 
121  {
122  labelList pointToUnique;
123 
124  nPointsChanged = Foam::inplaceMergePoints
125  (
126  mergedPoints,
127  boundaryPoints, // selection of points to merge
128  mergeDist,
129  false, // verbose = false
130  pointToUnique
131  );
132 
133  if (nPointsChanged)
134  {
135  // Renumber faces to use unique point numbers
136  for (auto& f : mergedFaces)
137  {
138  inplaceRenumber(pointToUnique, f);
139  }
140 
141  // Store point mapping
142  if (notNull(pointMergeMap))
143  {
144  pointMergeMap.transfer(pointToUnique);
145  }
146  }
147  }
148 
149  if (!nPointsChanged && notNull(pointMergeMap))
150  {
151  // Safety
152  pointMergeMap = identity(mergedPoints.size());
153  }
154 }
155 
156 
157 template<class FaceList, class PointField>
159 (
160  const scalar mergeDist,
161  const PrimitivePatch<FaceList, PointField>& pp,
162  Field
163  <
165  >& mergedPoints,
166  List
167  <
169  >& mergedFaces,
170  labelList& pointMergeMap,
171  const bool useLocal
172 )
173 {
174  globalIndex pointAddr;
175  globalIndex faceAddr;
176 
177  PatchTools::gatherAndMerge<FaceList, PointField>
178  (
179  mergeDist,
180  pp,
181  mergedPoints,
182  mergedFaces,
183  pointAddr,
184  faceAddr,
185  pointMergeMap,
186  useLocal
187  );
188 }
189 
190 
191 template<class FaceList>
193 (
194  const polyMesh& mesh,
195  const FaceList& localFaces,
196  const labelList& meshPoints,
197  const Map<label>& meshPointMap,
198 
199  labelList& pointToGlobal,
200  labelList& uniqueMeshPointLabels,
201  autoPtr<globalIndex>& globalPointsPtr,
202  autoPtr<globalIndex>& globalFacesPtr,
204  pointField& mergedPoints
205 )
206 {
207  typedef typename FaceList::value_type FaceType;
208 
209  if (UPstream::parRun())
210  {
211  // Renumber the points/faces into unique points
212  globalPointsPtr = mesh.globalData().mergePoints
213  (
214  meshPoints,
215  meshPointMap,
216  pointToGlobal,
217  uniqueMeshPointLabels
218  );
219 
220  globalFacesPtr.reset(new globalIndex(localFaces.size()));
221 
222  // Renumber faces locally
223  List<FaceType> myFaces(localFaces);
224  for (auto& f : myFaces)
225  {
226  inplaceRenumber(pointToGlobal, f);
227  }
228 
229  // Can also use
230  // UIndirectList<point>(mesh.points(), uniqueMeshPointLabels)
231  // but favour communication over local memory use
232  globalPointsPtr().gather
233  (
234  pointField(mesh.points(), uniqueMeshPointLabels),
235  mergedPoints
236  );
237  globalFacesPtr().gather(myFaces, mergedFaces);
238  }
239  else
240  {
241  pointToGlobal = identity(meshPoints.size());
242  uniqueMeshPointLabels = pointToGlobal;
243 
244  globalPointsPtr.reset(new globalIndex(meshPoints.size()));
245  globalFacesPtr.reset(new globalIndex(localFaces.size()));
246 
247  mergedFaces = localFaces;
248  mergedPoints = pointField(mesh.points(), meshPoints);
249  }
250 }
251 
252 
253 // ************************************************************************* //
labelRange range(const label proci) const
Return start/size range of proci data.
Definition: globalIndexI.H:282
std::remove_reference< PointField >::type::value_type point_type
The point type.
void reset(const label localSize, const label comm=UPstream::worldComm, const bool parallel=UPstream::parRun())
Reset from local size, using gather/broadcast with default/specified communicator if parallel...
Definition: globalIndex.C:346
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition: List.C:326
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1049
Dispatch tag: Construct &#39;one-sided&#39; from local sizes, using gather but no broadcast.
Definition: globalIndex.H:110
autoPtr< globalIndex > mergePoints(labelList &pointToGlobal, labelList &uniquePoints) const
Helper for merging (collocated!) mesh point data.
std::remove_reference< FaceList >::type::value_type face_type
The face type.
void inplaceToGlobal(const label proci, labelUList &labels) const
From local to global index on proci (inplace)
Definition: globalIndexI.H:351
static void gatherAndMerge(const scalar mergeDist, const PrimitivePatch< FaceList, PointField > &pp, Field< typename PrimitivePatch< FaceList, PointField >::point_type > &mergedPoints, List< typename PrimitivePatch< FaceList, PointField >::face_type > &mergedFaces, globalIndex &pointAddr, globalIndex &faceAddr, labelList &pointMergeMap=const_cast< labelList &>(labelList::null()), const bool useLocal=false)
Gather points and faces onto master and merge into single patch.
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1078
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:37
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:61
A List obtained as a section of another List.
Definition: SubList.H:50
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
dynamicFvMesh & mesh
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
Generic templated field type.
Definition: Field.H:62
const globalMeshData & globalData() const
Return parallel info (demand-driven)
Definition: polyMesh.C:1311
label inplaceMergePoints(PointList &points, const scalar mergeTol, const bool verbose, labelList &pointToUnique)
Inplace merge points, preserving the original point order. All points closer/equal mergeTol are to be...
Geometric merging of points. See below.
labelList f(nPoints)
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes)
Definition: globalIndexI.H:197
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
List< label > labelList
A List of labels.
Definition: List.H:62
bool notNull(const T *ptr)
True if ptr is not a pointer (of type T) to the nullObject.
Definition: nullObject.H:246
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())