cellToCellStencil.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 | Copyright (C) 2011-2013 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 "cellToCellStencil.H"
27 #include "syncTools.H"
28 #include "SortableList.H"
29 #include "emptyPolyPatch.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
33 // Merge two list and guarantee global0,global1 are first.
35 (
36  const label global0,
37  const label global1,
38  const labelList& listA,
39  labelList& listB
40 )
41 {
42  sort(listB);
43 
44  // See if global0, global1 already present in listB
45  label nGlobalInsert = 0;
46 
47  if (global0 != -1)
48  {
49  label index0 = findSortedIndex(listB, global0);
50  if (index0 == -1)
51  {
52  nGlobalInsert++;
53  }
54  }
55 
56  if (global1 != -1)
57  {
58  label index1 = findSortedIndex(listB, global1);
59  if (index1 == -1)
60  {
61  nGlobalInsert++;
62  }
63  }
64 
65 
66  // For all in listA see if they are present
67  label nInsert = 0;
68 
69  forAll(listA, i)
70  {
71  label elem = listA[i];
72 
73  if (elem != global0 && elem != global1)
74  {
75  if (findSortedIndex(listB, elem) == -1)
76  {
77  nInsert++;
78  }
79  }
80  }
81 
82  // Extend B with nInsert and whether global0,global1 need to be inserted.
83  labelList result(listB.size() + nGlobalInsert + nInsert);
84 
85  label resultI = 0;
86 
87  // Insert global0,1 first
88  if (global0 != -1)
89  {
90  result[resultI++] = global0;
91  }
92  if (global1 != -1)
93  {
94  result[resultI++] = global1;
95  }
96 
97 
98  // Insert listB
99  forAll(listB, i)
100  {
101  label elem = listB[i];
102 
103  if (elem != global0 && elem != global1)
104  {
105  result[resultI++] = elem;
106  }
107  }
108 
109 
110  // Insert listA
111  forAll(listA, i)
112  {
113  label elem = listA[i];
114 
115  if (elem != global0 && elem != global1)
116  {
117  if (findSortedIndex(listB, elem) == -1)
118  {
119  result[resultI++] = elem;
120  }
121  }
122  }
123 
124  if (resultI != result.size())
125  {
126  FatalErrorIn("cellToCellStencil::merge(..)")
127  << "problem" << abort(FatalError);
128  }
129 
130  listB.transfer(result);
131 }
132 
133 
134 // Merge two list and guarantee globalI is first.
136 (
137  const label globalI,
138  const labelList& pGlobals,
139  labelList& cCells
140 )
141 {
142  labelHashSet set;
143  forAll(cCells, i)
144  {
145  if (cCells[i] != globalI)
146  {
147  set.insert(cCells[i]);
148  }
149  }
150 
151  forAll(pGlobals, i)
152  {
153  if (pGlobals[i] != globalI)
154  {
155  set.insert(pGlobals[i]);
156  }
157  }
158 
159  cCells.setSize(set.size()+1);
160  label n = 0;
161  cCells[n++] = globalI;
162 
163  forAllConstIter(labelHashSet, set, iter)
164  {
165  cCells[n++] = iter.key();
166  }
167 }
168 
169 
171 {
173 
174  isValidBFace.setSize(mesh().nFaces()-mesh().nInternalFaces(), true);
175 
176  forAll(patches, patchI)
177  {
178  const polyPatch& pp = patches[patchI];
179 
180  if (pp.coupled() || isA<emptyPolyPatch>(pp))
181  {
182  label bFaceI = pp.start()-mesh().nInternalFaces();
183  forAll(pp, i)
184  {
185  isValidBFace[bFaceI++] = false;
186  }
187  }
188  }
189 }
190 
191 
194 {
196 
197  label nCoupled = 0;
198 
199  forAll(patches, patchI)
200  {
201  const polyPatch& pp = patches[patchI];
202 
203  if (pp.coupled())
204  {
205  nCoupled += pp.size();
206  }
207  }
208  labelList coupledFaces(nCoupled);
209  nCoupled = 0;
210 
211  forAll(patches, patchI)
212  {
213  const polyPatch& pp = patches[patchI];
214 
215  if (pp.coupled())
216  {
217  label faceI = pp.start();
218 
219  forAll(pp, i)
220  {
221  coupledFaces[nCoupled++] = faceI++;
222  }
223  }
224  }
225 
227  (
229  (
231  (
232  mesh().faces(),
233  coupledFaces
234  ),
235  mesh().points()
236  )
237  );
238 }
239 
240 
241 void Foam::cellToCellStencil::unionEqOp::operator()
242 (
243  labelList& x,
244  const labelList& y
245 ) const
246 {
247  if (y.size())
248  {
249  if (x.empty())
250  {
251  x = y;
252  }
253  else
254  {
255  labelHashSet set(x);
256  forAll(y, i)
257  {
258  set.insert(y[i]);
259  }
260  x = set.toc();
261  }
262  }
263 }
264 
265 
267 (
268  const label exclude0,
269  const label exclude1,
270  const boolList& isValidBFace,
271  const labelList& faceLabels,
272  labelHashSet& globals
273 ) const
274 {
275  const labelList& own = mesh().faceOwner();
276  const labelList& nei = mesh().faceNeighbour();
277 
278  forAll(faceLabels, i)
279  {
280  label faceI = faceLabels[i];
281 
282  label globalOwn = globalNumbering().toGlobal(own[faceI]);
283  if (globalOwn != exclude0 && globalOwn != exclude1)
284  {
285  globals.insert(globalOwn);
286  }
287 
288  if (mesh().isInternalFace(faceI))
289  {
290  label globalNei = globalNumbering().toGlobal(nei[faceI]);
291  if (globalNei != exclude0 && globalNei != exclude1)
292  {
293  globals.insert(globalNei);
294  }
295  }
296  else
297  {
298  label bFaceI = faceI-mesh().nInternalFaces();
299 
300  if (isValidBFace[bFaceI])
301  {
302  label globalI = globalNumbering().toGlobal
303  (
304  mesh().nCells()
305  + bFaceI
306  );
307 
308  if (globalI != exclude0 && globalI != exclude1)
309  {
310  globals.insert(globalI);
311  }
312  }
313  }
314  }
315 }
316 
317 
319 (
320  const boolList& isValidBFace,
321  const labelList& faceLabels,
322  labelHashSet& globals
323 ) const
324 {
325  globals.clear();
326 
328  (
329  -1,
330  -1,
331  isValidBFace,
332  faceLabels,
333  globals
334  );
335 
336  return globals.toc();
337 }
338 
339 
340 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
341 
343 :
344  mesh_(mesh),
345  globalNumbering_(mesh_.nCells()+mesh_.nFaces()-mesh_.nInternalFaces())
346 {}
347 
348 
349 // ************************************************************************* //
A List with indirect addressing.
Definition: IndirectList.H:102
const pointField & points
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
Definition: polyPatch.H:310
void sort(UList< T > &)
Definition: UList.C:107
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:390
bool empty() const
Return true if the UList is empty (ie, size() is zero).
Definition: UListI.H:313
static void merge(const label, const label, const labelList &, labelList &)
Merge two lists.
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 size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
labelList calcFaceCells(const boolList &nonEmptyFace, const labelList &faceLabels, labelHashSet &globals) const
Collect cell neighbours of faces in global numbering.
const polyMesh & mesh() const
PrimitivePatch< face, IndirectList, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
patches[0]
void validBoundaryFaces(boolList &isValidBFace) const
Valid boundary faces (not empty and not coupled)
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
label n
void setSize(const label)
Reset size of List.
Definition: List.C:318
void clear()
Clear all entries from table.
Definition: HashTable.C:473
Foam::polyBoundaryMesh.
#define forAll(list, i)
Definition: UList.H:421
autoPtr< indirectPrimitivePatch > allCoupledFacesPatch() const
Return patch of all coupled faces.
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:201
errorManip< error > abort(error &err)
Definition: errorManip.H:131
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1073
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:300
label nInternalFaces() const
const globalIndex & globalNumbering() const
Global numbering for cells and boundary faces.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
label toGlobal(const label i) const
From local to global.
Definition: globalIndexI.H:82
error FatalError
scalar y
void insertFaceCells(const label exclude0, const label exclude1, const boolList &nonEmptyFace, const labelList &faceLabels, labelHashSet &globals) const
Collect cell neighbours of faces in global numbering.
label findSortedIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element in sorted list and return index,.
cellToCellStencil(const polyMesh &)
Construct from mesh.
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1079
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116