CFCFaceToCellStencil.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-2016 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 "CFCFaceToCellStencil.H"
27 #include "syncTools.H"
28 #include "emptyPolyPatch.H"
29 #include "dummyTransform.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
33 void Foam::CFCFaceToCellStencil::calcFaceBoundaryData
34 (
35  labelListList& neiGlobal
36 ) const
37 {
38  const polyBoundaryMesh& patches = mesh().boundaryMesh();
39  const label nBnd = mesh().nFaces()-mesh().nInternalFaces();
40  const labelList& own = mesh().faceOwner();
41 
42  neiGlobal.setSize(nBnd);
43 
44  forAll(patches, patchi)
45  {
46  const polyPatch& pp = patches[patchi];
47  label facei = pp.start();
48 
49  if (pp.coupled())
50  {
51  // For coupled faces get the faces of the cell on the other side
52  forAll(pp, i)
53  {
54  const labelList& cFaces = mesh().cells()[own[facei]];
55 
56  labelList& globFaces = neiGlobal[facei-mesh().nInternalFaces()];
57  globFaces.setSize(cFaces.size()-1);
58  label globI = 0;
59 
60  forAll(cFaces, j)
61  {
62  if (cFaces[j] != facei)
63  {
64  globFaces[globI++] = globalNumbering().toGlobal
65  (
66  cFaces[j]
67  );
68  }
69  }
70  facei++;
71  }
72  }
73  else if (isA<emptyPolyPatch>(pp))
74  {
75  // Do nothing.
76  }
77  else
78  {
79  // Do nothing since face itself already in stencil
80  }
81  }
82 
84  (
85  mesh(),
86  neiGlobal,
87  eqOp<labelList>(),
88  dummyTransform()
89  );
90 }
91 
92 
93 void Foam::CFCFaceToCellStencil::calcCellStencil
94 (
95  labelListList& globalCellFaces
96 ) const
97 {
98  const label nBnd = mesh().nFaces()-mesh().nInternalFaces();
99  const labelList& own = mesh().faceOwner();
100  const labelList& nei = mesh().faceNeighbour();
101 
102 
103  // Calculate faces of coupled neighbour (in global numbering)
104  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105 
106  labelListList neiGlobal(nBnd);
107  calcFaceBoundaryData(neiGlobal);
108 
109 
110 
111  // Non-empty boundary faces
112  boolList validBFace(mesh().nFaces()-mesh().nInternalFaces(), true);
113 
114  const polyBoundaryMesh& patches = mesh().boundaryMesh();
115  forAll(patches, patchi)
116  {
117  const polyPatch& pp = patches[patchi];
118 
119  if (isA<emptyPolyPatch>(pp))
120  {
121  label bFacei = pp.start()-mesh().nInternalFaces();
122  forAll(pp, i)
123  {
124  validBFace[bFacei++] = false;
125  }
126  }
127  }
128 
129 
130  // Determine faces of cellCells in global numbering
131  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132 
133  DynamicList<label> allGlobalFaces(100);
134 
135  globalCellFaces.setSize(mesh().nCells());
136  forAll(globalCellFaces, celli)
137  {
138  const cell& cFaces = mesh().cells()[celli];
139 
140  allGlobalFaces.clear();
141 
142  // My faces first
143  forAll(cFaces, i)
144  {
145  label facei = cFaces[i];
146 
147  if
148  (
149  mesh().isInternalFace(facei)
150  || validBFace[facei-mesh().nInternalFaces()]
151  )
152  {
153  allGlobalFaces.append(globalNumbering().toGlobal(facei));
154  }
155  }
156 
157  // faces of neighbouring cells second
158  forAll(cFaces, i)
159  {
160  label facei = cFaces[i];
161 
162  if (mesh().isInternalFace(facei))
163  {
164  label nbrCelli = own[facei];
165  if (nbrCelli == celli)
166  {
167  nbrCelli = nei[facei];
168  }
169  const cell& nbrFaces = mesh().cells()[nbrCelli];
170 
171  forAll(nbrFaces, j)
172  {
173  label nbrFacei = nbrFaces[j];
174 
175  if
176  (
177  mesh().isInternalFace(nbrFacei)
178  || validBFace[nbrFacei-mesh().nInternalFaces()]
179  )
180  {
181  label nbrGlobalI = globalNumbering().toGlobal(nbrFacei);
182 
183  // Check if already there. Note:should use hashset?
184  if (findIndex(allGlobalFaces, nbrGlobalI) == -1)
185  {
186  allGlobalFaces.append(nbrGlobalI);
187  }
188  }
189  }
190  }
191  else
192  {
193  const labelList& nbrGlobalFaces =
194  neiGlobal[facei-mesh().nInternalFaces()];
195 
196  forAll(nbrGlobalFaces, j)
197  {
198  label nbrGlobalI = nbrGlobalFaces[j];
199 
200  // Check if already there. Note:should use hashset?
201  if (findIndex(allGlobalFaces, nbrGlobalI) == -1)
202  {
203  allGlobalFaces.append(nbrGlobalI);
204  }
205  }
206  }
207  }
208 
209  globalCellFaces[celli] = allGlobalFaces;
210  //Pout<< "** cell:" << celli
211  // << " at:" << mesh().cellCentres()[celli]
212  // << endl;
213  //const labelList& globalFaces = globalCellFaces[celli];
214  //forAll(globalFaces, i)
215  //{
216  // label facei = globalNumbering().toLocal(globalFaces[i]);
217  // Pout<< " face:" << facei
218  // << " at:" << mesh().faceCentres()[facei]
219  // << endl;
220  //}
221  }
222 }
223 
224 
225 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
226 
228 :
229  faceToCellStencil(mesh)
230 {
231  // Calculate per cell the (face) connected cells (in global numbering)
232  calcCellStencil(*this);
233 }
234 
235 
236 // ************************************************************************* //
static void syncBoundaryFaceList(const polyMesh &, UList< T > &, const CombineOp &cop, const TransformOp &top, const bool parRun=Pstream::parRun())
Synchronize values on boundary faces only.
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
CFCFaceToCellStencil(const polyMesh &)
Construct from mesh.
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
label toGlobal(const label i) const
From local to global.
Definition: globalIndexI.H:82
baseclass for extended cell centred addressing. Contains per cell a list of neighbouring faces in glo...
const cellList & cells() const
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
Dummy transform to be used with syncTools.
void clear()
Clear the list, i.e. set size to zero.
Definition: List.C:356
List< label > labelList
A List of labels.
Definition: labelList.H:56
const globalIndex & globalNumbering() const
Global numbering for faces.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
label nFaces() const
void setSize(const label)
Reset size of List.
Definition: List.C:295
label patchi
const polyMesh & mesh() const
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1023
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1017
label nInternalFaces() const