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-------------------------------------------------------------------------------
11License
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{
137 labelHashSet set;
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,
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// ************************************************************************* //
label n
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:191
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:122
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:52
void clear()
Clear all entries from table.
Definition: HashTable.C:678
A List with indirect addressing.
Definition: IndirectList.H:119
void transfer(List< T > &list)
Definition: List.C:447
void setSize(const label n)
Alias for resize()
Definition: List.H:218
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
Base class for extended cell-to-face stencils (face values from neighbouring cells)
autoPtr< indirectPrimitivePatch > allCoupledFacesPatch() const
Return patch of all coupled faces.
void calcFaceStencil(const labelListList &globalCellCells, labelListList &faceStencil) const
Collect cell neighbours into extended stencil.
void validBoundaryFaces(boolList &isValidBFace) const
Valid boundary faces (not empty and not coupled)
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.
labelList calcFaceCells(const boolList &nonEmptyFace, const labelList &faceLabels, labelHashSet &globals) const
Collect cell neighbours of faces in global numbering.
virtual bool merge() const
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1121
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:456
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1127
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:75
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
Definition: polyPatch.H:380
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:364
label nInternalFaces() const noexcept
Number of internal faces.
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.
const polyBoundaryMesh & patches
dynamicFvMesh & mesh
Dummy transform to be used with syncTools.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
const pointField & points
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:342
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError
label findSortedIndex(const ListType &input, typename ListType::const_reference val, const label start=0)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
Definition: ops.H:71