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 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
37 <
38  class Face,
39  template<class> class FaceList,
40  class PointField,
41  class PointType
42 >
44 (
45  const scalar mergeDist,
47  Field<PointType>& mergedPoints,
48  List<Face>& mergedFaces,
49  labelList& pointMergeMap
50 )
51 {
52  // Collect points from all processors
53  labelList pointSizes;
54  {
55  const globalIndex gi(p.points().size());
56 
57  gi.gather(p.points(), mergedPoints);
58 
59  pointSizes = gi.sizes();
60  }
61 
62  // Collect faces from all processors and renumber using sizes of
63  // gathered points
64  {
65  List<List<Face>> gatheredFaces(Pstream::nProcs());
66  gatheredFaces[Pstream::myProcNo()] = p;
67  Pstream::gatherList(gatheredFaces);
68 
69  if (Pstream::master())
70  {
71  mergedFaces = static_cast<const List<Face>&>
72  (
73  ListListOps::combineOffset<List<Face>>
74  (
75  gatheredFaces,
76  pointSizes,
79  )
80  );
81  }
82  }
83 
84  if (Pstream::master())
85  {
86  Field<PointType> newPoints;
87  labelList oldToNew;
88 
89  bool hasMerged = mergePoints
90  (
91  mergedPoints,
92  mergeDist,
93  false, // verbosity
94  oldToNew,
95  newPoints
96  );
97 
98  if (hasMerged)
99  {
100  // Store point mapping
101  pointMergeMap.transfer(oldToNew);
102 
103  // Copy points
104  mergedPoints.transfer(newPoints);
105 
106  // Relabel faces
107  List<Face>& faces = mergedFaces;
108 
109  forAll(faces, facei)
110  {
111  inplaceRenumber(pointMergeMap, faces[facei]);
112  }
113  }
114  }
115 }
116 
117 
118 template<class FaceList>
120 (
121  const polyMesh& mesh,
122  const FaceList& localFaces,
123  const labelList& meshPoints,
124  const Map<label>& meshPointMap,
125 
126  labelList& pointToGlobal,
127  labelList& uniqueMeshPointLabels,
128  autoPtr<globalIndex>& globalPointsPtr,
129  autoPtr<globalIndex>& globalFacesPtr,
131  pointField& mergedPoints
132 )
133 {
134  typedef typename FaceList::value_type FaceType;
135 
136  if (Pstream::parRun())
137  {
138  // Renumber the setPatch points/faces into unique points
139  globalPointsPtr = mesh.globalData().mergePoints
140  (
141  meshPoints,
142  meshPointMap,
143  pointToGlobal,
144  uniqueMeshPointLabels
145  );
146 
147  globalFacesPtr.reset(new globalIndex(localFaces.size()));
148 
149  if (Pstream::master())
150  {
151  // Get renumbered local data
152  pointField myPoints(mesh.points(), uniqueMeshPointLabels);
153  List<FaceType> myFaces(localFaces);
154  forAll(myFaces, i)
155  {
156  inplaceRenumber(pointToGlobal, myFaces[i]);
157  }
158 
159 
160  mergedFaces.setSize(globalFacesPtr().size());
161  mergedPoints.setSize(globalPointsPtr().size());
162 
163  // Insert master data first
164  label pOffset = globalPointsPtr().offset(Pstream::masterNo());
165  SubList<point>(mergedPoints, myPoints.size(), pOffset) = myPoints;
166 
167  label fOffset = globalFacesPtr().offset(Pstream::masterNo());
168  SubList<FaceType>(mergedFaces, myFaces.size(), fOffset) = myFaces;
169 
170 
171  // Receive slave ones
172  for (int slave=1; slave<Pstream::nProcs(); slave++)
173  {
174  IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
175 
176  pointField slavePoints(fromSlave);
177  List<FaceType> slaveFaces(fromSlave);
178 
179  label pOffset = globalPointsPtr().offset(slave);
180  SubList<point>(mergedPoints, slavePoints.size(), pOffset) =
181  slavePoints;
182 
183  label fOffset = globalFacesPtr().offset(slave);
184  SubList<FaceType>(mergedFaces, slaveFaces.size(), fOffset) =
185  slaveFaces;
186  }
187  }
188  else
189  {
190  // Get renumbered local data
191  pointField myPoints(mesh.points(), uniqueMeshPointLabels);
192  List<FaceType> myFaces(localFaces);
193  forAll(myFaces, i)
194  {
195  inplaceRenumber(pointToGlobal, myFaces[i]);
196  }
197 
198  // Construct processor stream with estimate of size. Could
199  // be improved.
200  OPstream toMaster
201  (
202  Pstream::commsTypes::scheduled,
203  Pstream::masterNo(),
204  myPoints.byteSize() + 4*sizeof(label)*myFaces.size()
205  );
206  toMaster << myPoints << myFaces;
207  }
208  }
209  else
210  {
211  pointToGlobal = identity(meshPoints.size());
212  uniqueMeshPointLabels = pointToGlobal;
213 
214  globalPointsPtr.reset(new globalIndex(meshPoints.size()));
215  globalFacesPtr.reset(new globalIndex(localFaces.size()));
216 
217  mergedFaces = localFaces;
218  mergedPoints = pointField(mesh.points(), meshPoints);
219  }
220 }
221 
222 
223 // ************************************************************************* //
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::autoPtr::reset
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:158
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::accessOp
Definition: UList.H:607
PatchTools.H
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:52
globalMeshData.H
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
Foam::Map< label >
polyMesh.H
Foam::inplaceRenumber
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:61
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::label
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:62
Foam::Field< PointType >
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:436
Foam::offsetOp
Offset operator for ListListOps::combineOffset()
Definition: ListListOps.H:101
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::mergePoints
label mergePoints(const PointList &points, const scalar mergeTol, const bool verbose, labelList &pointMap, typename PointList::const_reference origin=PointList::value_type::zero)
Sorts and merges points. All points closer than/equal mergeTol get merged.
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::List< Face >
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
mergePoints.H
Merge points. See below.
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:52
Foam::PatchTools::gatherAndMerge
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.
Definition: PatchToolsGatherAndMerge.C:44
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:90
Foam::globalIndex::gather
static void gather(const labelUList &offsets, const label comm, const Container &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const Pstream::commsTypes commsType=Pstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
Definition: globalIndexTemplates.C:35