FreeFOAM The Cross-Platform CFD Toolkit
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) 1991-2010 OpenCFD Ltd.
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 <OpenFOAM/syncTools.H>
29 
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 
32 // Calculates per face the neighbour data (= faces of cell). Leaves out the
33 // face itself since this is already in stencil.
34 void Foam::CFCFaceToCellStencil::calcFaceBoundaryData
35 (
36  labelListList& neiGlobal
37 ) const
38 {
39  const polyBoundaryMesh& patches = mesh().boundaryMesh();
40  const label nBnd = mesh().nFaces()-mesh().nInternalFaces();
41  const labelList& own = mesh().faceOwner();
42 
43  neiGlobal.setSize(nBnd);
44 
45  forAll(patches, patchI)
46  {
47  const polyPatch& pp = patches[patchI];
48  label faceI = pp.start();
49 
50  if (pp.coupled())
51  {
52  // For coupled faces get the faces of the cell on the other side
53  forAll(pp, i)
54  {
55  const labelList& cFaces = mesh().cells()[own[faceI]];
56 
57  labelList& globFaces = neiGlobal[faceI-mesh().nInternalFaces()];
58  globFaces.setSize(cFaces.size()-1);
59  label globI = 0;
60 
61  forAll(cFaces, j)
62  {
63  if (cFaces[j] != faceI)
64  {
65  globFaces[globI++] = globalNumbering().toGlobal
66  (
67  cFaces[j]
68  );
69  }
70  }
71  faceI++;
72  }
73  }
74  else if (isA<emptyPolyPatch>(pp))
75  {
76  // Do nothing.
77  }
78  else
79  {
80  // Do nothing since face itself already in stencil
81  }
82  }
83  syncTools::swapBoundaryFaceList(mesh(), neiGlobal, false);
84 }
85 
86 
87 // Calculates per cell the neighbour data (= cell or boundary in global
88 // numbering). First element is always cell itself!
89 void Foam::CFCFaceToCellStencil::calcCellStencil(labelListList& globalCellFaces)
90  const
91 {
92  const label nBnd = mesh().nFaces()-mesh().nInternalFaces();
93  const labelList& own = mesh().faceOwner();
94  const labelList& nei = mesh().faceNeighbour();
95 
96 
97  // Calculate faces of coupled neighbour (in global numbering)
98  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99 
100  labelListList neiGlobal(nBnd);
101  calcFaceBoundaryData(neiGlobal);
102 
103 
104 
105  // Non-empty boundary faces
106  boolList validBFace(mesh().nFaces()-mesh().nInternalFaces(), true);
107 
108  const polyBoundaryMesh& patches = mesh().boundaryMesh();
109  forAll(patches, patchI)
110  {
111  const polyPatch& pp = patches[patchI];
112 
113  if (isA<emptyPolyPatch>(pp))
114  {
115  label bFaceI = pp.start()-mesh().nInternalFaces();
116  forAll(pp, i)
117  {
118  validBFace[bFaceI++] = false;
119  }
120  }
121  }
122 
123 
124  // Determine faces of cellCells in global numbering
125  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
126 
127  DynamicList<label> allGlobalFaces(100);
128 
129  globalCellFaces.setSize(mesh().nCells());
130  forAll(globalCellFaces, cellI)
131  {
132  const cell& cFaces = mesh().cells()[cellI];
133 
134  allGlobalFaces.clear();
135 
136  // My faces first
137  forAll(cFaces, i)
138  {
139  label faceI = cFaces[i];
140 
141  if
142  (
143  mesh().isInternalFace(faceI)
144  || validBFace[faceI-mesh().nInternalFaces()]
145  )
146  {
147  allGlobalFaces.append(globalNumbering().toGlobal(faceI));
148  }
149  }
150 
151  // faces of neighbouring cells second
152  forAll(cFaces, i)
153  {
154  label faceI = cFaces[i];
155 
156  if (mesh().isInternalFace(faceI))
157  {
158  label nbrCellI = own[faceI];
159  if (nbrCellI == cellI)
160  {
161  nbrCellI = nei[faceI];
162  }
163  const cell& nbrFaces = mesh().cells()[nbrCellI];
164 
165  forAll(nbrFaces, j)
166  {
167  label nbrFaceI = nbrFaces[j];
168 
169  if
170  (
171  mesh().isInternalFace(nbrFaceI)
172  || validBFace[nbrFaceI-mesh().nInternalFaces()]
173  )
174  {
175  label nbrGlobalI = globalNumbering().toGlobal(nbrFaceI);
176 
177  // Check if already there. Note:should use hashset?
178  if (findIndex(allGlobalFaces, nbrGlobalI) == -1)
179  {
180  allGlobalFaces.append(nbrGlobalI);
181  }
182  }
183  }
184  }
185  else
186  {
187  const labelList& nbrGlobalFaces =
188  neiGlobal[faceI-mesh().nInternalFaces()];
189 
190  forAll(nbrGlobalFaces, j)
191  {
192  label nbrGlobalI = nbrGlobalFaces[j];
193 
194  // Check if already there. Note:should use hashset?
195  if (findIndex(allGlobalFaces, nbrGlobalI) == -1)
196  {
197  allGlobalFaces.append(nbrGlobalI);
198  }
199  }
200  }
201  }
202 
203  globalCellFaces[cellI] = allGlobalFaces;
204  //Pout<< "** cell:" << cellI
205  // << " at:" << mesh().cellCentres()[cellI]
206  // << endl;
207  //const labelList& globalFaces = globalCellFaces[cellI];
208  //forAll(globalFaces, i)
209  //{
210  // label faceI = globalNumbering().toLocal(globalFaces[i]);
211  // Pout<< " face:" << faceI
212  // << " at:" << mesh().faceCentres()[faceI]
213  // << endl;
214  //}
215  }
216 }
217 
218 
219 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
220 
222 :
223  faceToCellStencil(mesh)
224 {
225  // Calculate per cell the (face) connected cells (in global numbering)
226  calcCellStencil(*this);
227 }
228 
229 
230 // ************************ vim: set sw=4 sts=4 et: ************************ //