cellToFaceStencil.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2018 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 "cellToFaceStencil.H"
30 #include "SortableList.H"
31 #include "emptyPolyPatch.H"
32 #include "syncTools.H"
33 #include "dummyTransform.H"
34 
35 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
36 
38 (
39  const label global0,
40  const label global1,
41  const labelList& listA,
42  labelList& listB
43 )
44 {
45  sort(listB);
46 
47  // See if global0, global1 already present in listB
48  label nGlobalInsert = 0;
49 
50  if (global0 != -1)
51  {
52  label index0 = findSortedIndex(listB, global0);
53  if (index0 == -1)
54  {
55  nGlobalInsert++;
56  }
57  }
58 
59  if (global1 != -1)
60  {
61  label index1 = findSortedIndex(listB, global1);
62  if (index1 == -1)
63  {
64  nGlobalInsert++;
65  }
66  }
67 
68 
69  // For all in listA see if they are present
70  label nInsert = 0;
71 
72  for (const label elem : listA)
73  {
74  if (elem != global0 && elem != global1)
75  {
76  if (findSortedIndex(listB, elem) == -1)
77  {
78  nInsert++;
79  }
80  }
81  }
82 
83  // Extend B with nInsert and whether global0,global1 need to be inserted.
84  labelList result(listB.size() + nGlobalInsert + nInsert);
85 
86  label resultI = 0;
87 
88  // Insert global0,1 first
89  if (global0 != -1)
90  {
91  result[resultI++] = global0;
92  }
93  if (global1 != -1)
94  {
95  result[resultI++] = global1;
96  }
97 
98 
99  // Insert listB
100  for (const label elem : listB)
101  {
102  if (elem != global0 && elem != global1)
103  {
104  result[resultI++] = elem;
105  }
106  }
107 
108 
109  // Insert listA
110  for (const label elem : listA)
111  {
112  if (elem != global0 && elem != global1)
113  {
114  if (findSortedIndex(listB, elem) == -1)
115  {
116  result[resultI++] = elem;
117  }
118  }
119  }
120 
121  if (resultI != result.size())
122  {
124  << "problem" << abort(FatalError);
125  }
126 
127  listB.transfer(result);
128 }
129 
130 
132 (
133  const label globalI,
134  const labelList& pGlobals,
135  labelList& cCells
136 )
137 {
139  forAll(cCells, i)
140  {
141  if (cCells[i] != globalI)
142  {
143  set.insert(cCells[i]);
144  }
145  }
146 
147  forAll(pGlobals, i)
148  {
149  if (pGlobals[i] != globalI)
150  {
151  set.insert(pGlobals[i]);
152  }
153  }
154 
155  cCells.setSize(set.size()+1);
156  label n = 0;
157  cCells[n++] = globalI;
158 
159  for (const label seti : set)
160  {
161  cCells[n++] = seti;
162  }
163 }
164 
165 
167 {
169 
170  isValidBFace.setSize(mesh().nBoundaryFaces(), true);
171 
172  forAll(patches, patchi)
173  {
174  const polyPatch& pp = patches[patchi];
175 
176  if (pp.coupled() || isA<emptyPolyPatch>(pp))
177  {
178  label bFacei = pp.start()-mesh().nInternalFaces();
179  forAll(pp, i)
180  {
181  isValidBFace[bFacei++] = false;
182  }
183  }
184  }
185 }
186 
187 
190 {
192 
193  label nCoupled = 0;
194 
195  forAll(patches, patchi)
196  {
197  const polyPatch& pp = patches[patchi];
198 
199  if (pp.coupled())
200  {
201  nCoupled += pp.size();
202  }
203  }
204  labelList coupledFaces(nCoupled);
205  nCoupled = 0;
206 
207  forAll(patches, patchi)
208  {
209  const polyPatch& pp = patches[patchi];
210 
211  if (pp.coupled())
212  {
213  label facei = pp.start();
214 
215  forAll(pp, i)
216  {
217  coupledFaces[nCoupled++] = facei++;
218  }
219  }
220  }
221 
223  (
225  (
226  mesh().faces(),
227  coupledFaces
228  ),
229  mesh().points()
230  );
231 }
232 
233 
235 (
236  const label exclude0,
237  const label exclude1,
238  const boolList& isValidBFace,
239  const labelList& faceLabels,
240  labelHashSet& globals
241 ) const
242 {
243  const labelList& own = mesh().faceOwner();
244  const labelList& nei = mesh().faceNeighbour();
245 
246  forAll(faceLabels, i)
247  {
248  label facei = faceLabels[i];
249 
250  label globalOwn = globalNumbering().toGlobal(own[facei]);
251  if (globalOwn != exclude0 && globalOwn != exclude1)
252  {
253  globals.insert(globalOwn);
254  }
255 
256  if (mesh().isInternalFace(facei))
257  {
258  label globalNei = globalNumbering().toGlobal(nei[facei]);
259  if (globalNei != exclude0 && globalNei != exclude1)
260  {
261  globals.insert(globalNei);
262  }
263  }
264  else
265  {
266  label bFacei = facei-mesh().nInternalFaces();
267 
268  if (isValidBFace[bFacei])
269  {
270  label globalI = globalNumbering().toGlobal
271  (
272  mesh().nCells()
273  + bFacei
274  );
275 
276  if (globalI != exclude0 && globalI != exclude1)
277  {
278  globals.insert(globalI);
279  }
280  }
281  }
282  }
283 }
284 
285 
287 (
288  const boolList& isValidBFace,
289  const labelList& faceLabels,
290  labelHashSet& globals
291 ) const
292 {
293  globals.clear();
294 
295  insertFaceCells
296  (
297  -1,
298  -1,
299  isValidBFace,
300  faceLabels,
301  globals
302  );
303 
304  return globals.toc();
305 }
306 
307 
309 (
310  const labelListList& globalCellCells,
311  labelListList& faceStencil
312 ) const
313 {
314  // Calculates per face a list of global cell/face indices.
315 
316  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
317  const label nBnd = mesh_.nBoundaryFaces();
318  const labelList& own = mesh_.faceOwner();
319  const labelList& nei = mesh_.faceNeighbour();
320 
321 
322  // Determine neighbouring global cell Cells
323  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
324 
325  labelListList neiGlobalCellCells(nBnd);
326  forAll(patches, patchi)
327  {
328  const polyPatch& pp = patches[patchi];
329 
330  if (pp.coupled())
331  {
332  label facei = pp.start();
333 
334  forAll(pp, i)
335  {
336  neiGlobalCellCells[facei-mesh_.nInternalFaces()] =
337  globalCellCells[own[facei]];
338  facei++;
339  }
340  }
341  }
342  //syncTools::swapBoundaryFaceList(mesh_, neiGlobalCellCells);
344  (
345  mesh_,
346  neiGlobalCellCells,
347  eqOp<labelList>(),
349  );
350 
351 
352 
353  // Construct stencil in global numbering
354  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
355 
356  faceStencil.setSize(mesh_.nFaces());
357 
358  labelHashSet faceStencilSet;
359 
360  for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
361  {
362  faceStencilSet.clear();
363 
364  const labelList& ownCCells = globalCellCells[own[facei]];
365  label globalOwn = ownCCells[0];
366  faceStencilSet.insert(ownCCells); // Insert cellCells
367 
368  const labelList& neiCCells = globalCellCells[nei[facei]];
369  label globalNei = neiCCells[0];
370  faceStencilSet.insert(neiCCells); // Insert cellCells
371 
372  // Guarantee owner first, neighbour second.
373  faceStencil[facei].setSize(faceStencilSet.size());
374  label n = 0;
375  faceStencil[facei][n++] = globalOwn;
376  faceStencil[facei][n++] = globalNei;
377  for (const label stencili : faceStencilSet)
378  {
379  if (stencili != globalOwn && stencili != globalNei)
380  {
381  faceStencil[facei][n++] = stencili;
382  }
383  }
384  //Pout<< "internalface:" << facei << " toc:" << faceStencilSet.toc()
385  // << " faceStencil:" << faceStencil[facei] << endl;
386  }
387  forAll(patches, patchi)
388  {
389  const polyPatch& pp = patches[patchi];
390  label facei = pp.start();
391 
392  if (pp.coupled())
393  {
394  forAll(pp, i)
395  {
396  faceStencilSet.clear();
397 
398  const labelList& ownCCells = globalCellCells[own[facei]];
399  label globalOwn = ownCCells[0];
400  faceStencilSet.insert(ownCCells);
401 
402  // And the neighbours of the coupled cell
403  const labelList& neiCCells =
404  neiGlobalCellCells[facei-mesh_.nInternalFaces()];
405  label globalNei = neiCCells[0];
406  faceStencilSet.insert(neiCCells);
407 
408  // Guarantee owner first, neighbour second.
409  faceStencil[facei].setSize(faceStencilSet.size());
410  label n = 0;
411  faceStencil[facei][n++] = globalOwn;
412  faceStencil[facei][n++] = globalNei;
413  for (const label stencili : faceStencilSet)
414  {
415  if (stencili != globalOwn && stencili != globalNei)
416  {
417  faceStencil[facei][n++] = stencili;
418  }
419  }
420 
421  //Pout<< "coupledface:" << facei
422  // << " toc:" << faceStencilSet.toc()
423  // << " faceStencil:" << faceStencil[facei] << endl;
424 
425  facei++;
426  }
427  }
428  else if (!isA<emptyPolyPatch>(pp))
429  {
430  forAll(pp, i)
431  {
432  faceStencilSet.clear();
433 
434  const labelList& ownCCells = globalCellCells[own[facei]];
435  label globalOwn = ownCCells[0];
436  faceStencilSet.insert(ownCCells);
437 
438  // Guarantee owner first
439  faceStencil[facei].setSize(faceStencilSet.size());
440  label n = 0;
441  faceStencil[facei][n++] = globalOwn;
442  for (const label stencili : faceStencilSet)
443  {
444  if (stencili != globalOwn)
445  {
446  faceStencil[facei][n++] = stencili;
447  }
448  }
449 
450  //Pout<< "boundaryface:" << facei
451  // << " toc:" << faceStencilSet.toc()
452  // << " faceStencil:" << faceStencil[facei] << endl;
453 
454  facei++;
455  }
456  }
457  }
458 }
459 
460 
461 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
462 
464 :
465  mesh_(mesh),
466  globalNumbering_(mesh_.nCells()+mesh_.nBoundaryFaces())
467 {}
468 
469 
470 // ************************************************************************* //
Foam::cellToFaceStencil::cellToFaceStencil
cellToFaceStencil(const polyMesh &)
Construct from mesh.
Definition: cellToFaceStencil.C:463
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::HashTable::size
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:52
Foam::cellToFaceStencil::validBoundaryFaces
void validBoundaryFaces(boolList &isValidBFace) const
Valid boundary faces (not empty and not coupled)
Definition: cellToFaceStencil.C:166
Foam::BitOps::set
void set(List< bool > &bools, const labelRange &range)
Set the specified range 'on' in a boolList.
Definition: BitOps.C:37
Foam::cellToFaceStencil::mesh
const polyMesh & mesh() const
Definition: cellToFaceStencil.H:131
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:62
Foam::HashTable::toc
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:121
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const
Number of internal faces.
Definition: primitiveMeshI.H:78
Foam::syncTools::syncBoundaryFaceList
static void syncBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues, const CombineOp &cop, const TransformOp &top, const bool parRun=Pstream::parRun())
Synchronize values on boundary faces only.
Definition: syncToolsTemplates.C:904
Foam::polyPatch::coupled
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
Definition: polyPatch.H:329
dummyTransform.H
Dummy transform to be used with syncTools.
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::dummyTransform
Definition: dummyTransform.H:47
Foam::HashSet< label, Hash< label > >
syncTools.H
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:296
n
label n
Definition: TABSMDCalcMethod2.H:31
SortableList.H
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1107
Foam::sort
void sort(UList< T > &a)
Definition: UList.C:254
Foam::IndirectList
A List with indirect addressing.
Definition: IndirectList.H:56
Foam::cellToFaceStencil::merge
static void merge(const label global0, const label global1, const labelList &listA, labelList &listB)
Merge two lists.
Definition: cellToFaceStencil.C:38
Foam::findSortedIndex
label findSortedIndex(const ListType &input, typename ListType::const_reference val, const label start=0)
Foam::FatalError
error FatalError
Foam::eqOp
Definition: ops.H:71
Foam::cellToFaceStencil::allCoupledFacesPatch
autoPtr< indirectPrimitivePatch > allCoupledFacesPatch() const
Return patch of all coupled faces.
Definition: cellToFaceStencil.C:189
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::cellToFaceStencil::calcFaceStencil
void calcFaceStencil(const labelListList &globalCellCells, labelListList &faceStencil) const
Collect cell neighbours into extended stencil.
Definition: cellToFaceStencil.C:309
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:313
emptyPolyPatch.H
Foam::cellToFaceStencil::insertFaceCells
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.
Definition: cellToFaceStencil.C:235
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::HashTable::clear
void clear()
Clear all entries from table.
Definition: HashTable.C:630
Foam::List< label >
Foam::cellToFaceStencil::calcFaceCells
labelList calcFaceCells(const boolList &nonEmptyFace, const labelList &faceLabels, labelHashSet &globals) const
Collect cell neighbours of faces in global numbering.
Definition: cellToFaceStencil.C:287
cellToFaceStencil.H
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:181
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::polyMesh::faceNeighbour
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1113