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 "emptyPolyPatch.H"
31 #include "syncTools.H"
32 #include "dummyTransform.H"
33 
34 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
35 
37 (
38  const label global0,
39  const label global1,
40  const labelList& listA,
41  labelList& listB
42 )
43 {
44  sort(listB);
45 
46  // See if global0, global1 already present in listB
47  label nGlobalInsert = 0;
48 
49  if (global0 != -1)
50  {
51  label index0 = findSortedIndex(listB, global0);
52  if (index0 == -1)
53  {
54  nGlobalInsert++;
55  }
56  }
57 
58  if (global1 != -1)
59  {
60  label index1 = findSortedIndex(listB, global1);
61  if (index1 == -1)
62  {
63  nGlobalInsert++;
64  }
65  }
66 
67 
68  // For all in listA see if they are present
69  label nInsert = 0;
70 
71  for (const label elem : listA)
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  for (const label elem : listB)
100  {
101  if (elem != global0 && elem != global1)
102  {
103  result[resultI++] = elem;
104  }
105  }
106 
107 
108  // Insert listA
109  for (const label elem : listA)
110  {
111  if (elem != global0 && elem != global1)
112  {
113  if (findSortedIndex(listB, elem) == -1)
114  {
115  result[resultI++] = elem;
116  }
117  }
118  }
119 
120  if (resultI != result.size())
121  {
123  << "problem" << abort(FatalError);
124  }
125 
126  listB.transfer(result);
127 }
128 
129 
131 (
132  const label globalI,
133  const labelList& pGlobals,
134  labelList& cCells
135 )
136 {
138  forAll(cCells, i)
139  {
140  if (cCells[i] != globalI)
141  {
142  set.insert(cCells[i]);
143  }
144  }
145 
146  forAll(pGlobals, i)
147  {
148  if (pGlobals[i] != globalI)
149  {
150  set.insert(pGlobals[i]);
151  }
152  }
153 
154  cCells.setSize(set.size()+1);
155  label n = 0;
156  cCells[n++] = globalI;
157 
158  for (const label seti : set)
159  {
160  cCells[n++] = seti;
161  }
162 }
163 
164 
166 {
168 
169  isValidBFace.setSize(mesh().nBoundaryFaces(), true);
170 
171  forAll(patches, patchi)
172  {
173  const polyPatch& pp = patches[patchi];
174 
175  if (pp.coupled() || isA<emptyPolyPatch>(pp))
176  {
177  label bFacei = pp.start()-mesh().nInternalFaces();
178  forAll(pp, i)
179  {
180  isValidBFace[bFacei++] = false;
181  }
182  }
183  }
184 }
185 
186 
189 {
191 
192  label nCoupled = 0;
193 
194  forAll(patches, patchi)
195  {
196  const polyPatch& pp = patches[patchi];
197 
198  if (pp.coupled())
199  {
200  nCoupled += pp.size();
201  }
202  }
203  labelList coupledFaces(nCoupled);
204  nCoupled = 0;
205 
206  forAll(patches, patchi)
207  {
208  const polyPatch& pp = patches[patchi];
209 
210  if (pp.coupled())
211  {
212  label facei = pp.start();
213 
214  forAll(pp, i)
215  {
216  coupledFaces[nCoupled++] = facei++;
217  }
218  }
219  }
220 
222  (
224  (
225  mesh().faces(),
226  coupledFaces
227  ),
228  mesh().points()
229  );
230 }
231 
232 
234 (
235  const label exclude0,
236  const label exclude1,
237  const boolList& isValidBFace,
238  const labelList& faceLabels,
239  labelHashSet& globals
240 ) const
241 {
242  const labelList& own = mesh().faceOwner();
243  const labelList& nei = mesh().faceNeighbour();
244 
245  forAll(faceLabels, i)
246  {
247  label facei = faceLabels[i];
248 
249  label globalOwn = globalNumbering().toGlobal(own[facei]);
250  if (globalOwn != exclude0 && globalOwn != exclude1)
251  {
252  globals.insert(globalOwn);
253  }
254 
255  if (mesh().isInternalFace(facei))
256  {
257  label globalNei = globalNumbering().toGlobal(nei[facei]);
258  if (globalNei != exclude0 && globalNei != exclude1)
259  {
260  globals.insert(globalNei);
261  }
262  }
263  else
264  {
265  label bFacei = facei-mesh().nInternalFaces();
266 
267  if (isValidBFace[bFacei])
268  {
269  label globalI = globalNumbering().toGlobal
270  (
271  mesh().nCells()
272  + bFacei
273  );
274 
275  if (globalI != exclude0 && globalI != exclude1)
276  {
277  globals.insert(globalI);
278  }
279  }
280  }
281  }
282 }
283 
284 
286 (
287  const boolList& isValidBFace,
288  const labelList& faceLabels,
289  labelHashSet& globals
290 ) const
291 {
292  globals.clear();
293 
294  insertFaceCells
295  (
296  -1,
297  -1,
298  isValidBFace,
299  faceLabels,
300  globals
301  );
302 
303  return globals.toc();
304 }
305 
306 
308 (
309  const labelListList& globalCellCells,
310  labelListList& faceStencil
311 ) const
312 {
313  // Calculates per face a list of global cell/face indices.
314 
315  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
316  const label nBnd = mesh_.nBoundaryFaces();
317  const labelList& own = mesh_.faceOwner();
318  const labelList& nei = mesh_.faceNeighbour();
319 
320 
321  // Determine neighbouring global cell Cells
322  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
323 
324  labelListList neiGlobalCellCells(nBnd);
325  forAll(patches, patchi)
326  {
327  const polyPatch& pp = patches[patchi];
328 
329  if (pp.coupled())
330  {
331  label facei = pp.start();
332 
333  forAll(pp, i)
334  {
335  neiGlobalCellCells[facei-mesh_.nInternalFaces()] =
336  globalCellCells[own[facei]];
337  facei++;
338  }
339  }
340  }
341  //syncTools::swapBoundaryFaceList(mesh_, neiGlobalCellCells);
343  (
344  mesh_,
345  neiGlobalCellCells,
346  eqOp<labelList>(),
348  );
349 
350 
351 
352  // Construct stencil in global numbering
353  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
354 
355  faceStencil.setSize(mesh_.nFaces());
356 
357  labelHashSet faceStencilSet;
358 
359  for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
360  {
361  faceStencilSet.clear();
362 
363  const labelList& ownCCells = globalCellCells[own[facei]];
364  label globalOwn = ownCCells[0];
365  faceStencilSet.insert(ownCCells); // Insert cellCells
366 
367  const labelList& neiCCells = globalCellCells[nei[facei]];
368  label globalNei = neiCCells[0];
369  faceStencilSet.insert(neiCCells); // Insert cellCells
370 
371  // Guarantee owner first, neighbour second.
372  faceStencil[facei].setSize(faceStencilSet.size());
373  label n = 0;
374  faceStencil[facei][n++] = globalOwn;
375  faceStencil[facei][n++] = globalNei;
376  for (const label stencili : faceStencilSet)
377  {
378  if (stencili != globalOwn && stencili != globalNei)
379  {
380  faceStencil[facei][n++] = stencili;
381  }
382  }
383  //Pout<< "internalface:" << facei << " toc:" << faceStencilSet.toc()
384  // << " faceStencil:" << faceStencil[facei] << endl;
385  }
386  forAll(patches, patchi)
387  {
388  const polyPatch& pp = patches[patchi];
389  label facei = pp.start();
390 
391  if (pp.coupled())
392  {
393  forAll(pp, i)
394  {
395  faceStencilSet.clear();
396 
397  const labelList& ownCCells = globalCellCells[own[facei]];
398  label globalOwn = ownCCells[0];
399  faceStencilSet.insert(ownCCells);
400 
401  // And the neighbours of the coupled cell
402  const labelList& neiCCells =
403  neiGlobalCellCells[facei-mesh_.nInternalFaces()];
404  label globalNei = neiCCells[0];
405  faceStencilSet.insert(neiCCells);
406 
407  // Guarantee owner first, neighbour second.
408  faceStencil[facei].setSize(faceStencilSet.size());
409  label n = 0;
410  faceStencil[facei][n++] = globalOwn;
411  faceStencil[facei][n++] = globalNei;
412  for (const label stencili : faceStencilSet)
413  {
414  if (stencili != globalOwn && stencili != globalNei)
415  {
416  faceStencil[facei][n++] = stencili;
417  }
418  }
419 
420  //Pout<< "coupledface:" << facei
421  // << " toc:" << faceStencilSet.toc()
422  // << " faceStencil:" << faceStencil[facei] << endl;
423 
424  facei++;
425  }
426  }
427  else if (!isA<emptyPolyPatch>(pp))
428  {
429  forAll(pp, i)
430  {
431  faceStencilSet.clear();
432 
433  const labelList& ownCCells = globalCellCells[own[facei]];
434  label globalOwn = ownCCells[0];
435  faceStencilSet.insert(ownCCells);
436 
437  // Guarantee owner first
438  faceStencil[facei].setSize(faceStencilSet.size());
439  label n = 0;
440  faceStencil[facei][n++] = globalOwn;
441  for (const label stencili : faceStencilSet)
442  {
443  if (stencili != globalOwn)
444  {
445  faceStencil[facei][n++] = stencili;
446  }
447  }
448 
449  //Pout<< "boundaryface:" << facei
450  // << " toc:" << faceStencilSet.toc()
451  // << " faceStencil:" << faceStencil[facei] << endl;
452 
453  facei++;
454  }
455  }
456  }
457 }
458 
459 
460 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
461 
463 :
464  mesh_(mesh),
465  globalNumbering_(mesh_.nCells()+mesh_.nBoundaryFaces())
466 {}
467 
468 
469 // ************************************************************************* //
Foam::cellToFaceStencil::cellToFaceStencil
cellToFaceStencil(const polyMesh &)
Construct from mesh.
Definition: cellToFaceStencil.C:462
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::cellToFaceStencil::validBoundaryFaces
void validBoundaryFaces(boolList &isValidBFace) const
Valid boundary faces (not empty and not coupled)
Definition: cellToFaceStencil.C:165
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:63
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:998
Foam::polyPatch::coupled
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
Definition: polyPatch.H:377
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
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
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:261
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:37
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:188
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:308
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:361
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:234
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:453
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const noexcept
Number of internal faces.
Definition: primitiveMeshI.H:78
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:286
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:191
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::polyMesh::faceNeighbour
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1113