OppositeFaceCellWave.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) 2016 OpenFOAM Foundation
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "OppositeFaceCellWave.H"
29 #include "polyMesh.H"
30 
31 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
32 
33 template<class Type, class TrackingData>
35 (
36  const label celli,
37  const label masterFaceLabel,
38  DynamicList<label>& oppositeFaceLabels
39 ) const
40 {
41  // Variant of cell::opposingFaceLabel
42 
43  // Algorithm:
44  // Go through all the faces of the cell and find the one which
45  // does not share a single vertex with the master face. If there
46  // are two or more such faces, return the first one and issue a
47  // warning; if there is no opposite face, return -1;
48 
49  const face& masterFace = this->mesh_.faces()[masterFaceLabel];
50 
51  const labelList& curFaceLabels = this->mesh_.cells()[celli];
52 
53  oppositeFaceLabels.clear();
54 
55  forAll(curFaceLabels, facei)
56  {
57  // Compare the face with the master
58  const face& curFace = this->mesh_.faces()[curFaceLabels[facei]];
59 
60  // Skip the master face
61  if (curFaceLabels[facei] != masterFaceLabel)
62  {
63  bool sharedPoint = false;
64 
65  // Compare every vertex of the current face against the
66  // vertices of the master face
67  forAll(curFace, pointi)
68  {
69  const label l = curFace[pointi];
70 
71  forAll(masterFace, masterPointi)
72  {
73  if (masterFace[masterPointi] == l)
74  {
75  sharedPoint = true;
76  break;
77  }
78  }
79 
80  if (sharedPoint) break;
81  }
82 
83  // If no points are shared, this is the opposite face
84  if (!sharedPoint)
85  {
86  // Found opposite face
87  oppositeFaceLabels.append(curFaceLabels[facei]);
88  }
89  }
90  }
91 }
92 
93 
94 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
95 
96 // Iterate, propagating changedFacesInfo across mesh, until no change (or
97 // maxIter reached). Initial cell values specified.
98 template<class Type, class TrackingData>
100 (
101  const polyMesh& mesh,
102  const labelList& changedFaces,
103  const List<Type>& changedFacesInfo,
104  UList<Type>& allFaceInfo,
105  UList<Type>& allCellInfo,
106  const label maxIter,
107  TrackingData& td
108 )
109 :
111  (
112  mesh,
113  changedFaces,
114  changedFacesInfo,
115  allFaceInfo,
116  allCellInfo,
117  0, //maxIter,
118  td
119  ),
120  changedOppositeFaces_(this->mesh_.nCells())
121 {
122  // Iterate until nothing changes
123  label iter = this->iterate(maxIter);
124 
125  if ((maxIter > 0) && (iter >= maxIter))
126  {
128  << "Maximum number of iterations reached. Increase maxIter."
129  << endl
130  << " maxIter:" << maxIter << endl
131  << " nChangedCells:" << this->changedCells_.size() << endl
132  << " nChangedFaces:" << this->changedFaces_.size() << endl
133  << exit(FatalError);
134  }
135 }
136 
137 
138 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
139 
140 template<class Type, class TrackingData>
142 {
143  const labelList& owner = this->mesh_.faceOwner();
144  const labelList& neighbour = this->mesh_.faceNeighbour();
145  label nInternalFaces = this->mesh_.nInternalFaces();
146 
147  DynamicList<label> oppositeFaceLabels;
148 
149  forAll(this->changedFaces_, changedFacei)
150  {
151  label facei = this->changedFaces_[changedFacei];
152 
153  if (!this->changedFace_.test(facei))
154  {
156  << "Face " << facei
157  << " not marked as having been changed"
158  << abort(FatalError);
159  }
160 
161 
162  const Type& neighbourWallInfo = this->allFaceInfo_[facei];
163 
164  // Evaluate all connected cells
165 
166  // Owner
167  {
168  label celli = owner[facei];
169  Type& currentWallInfo = this->allCellInfo_[celli];
170 
171  if (!currentWallInfo.equal(neighbourWallInfo, this->td_))
172  {
173  // Check if cell is prismatic w.r.t facei
174  opposingFaceLabels(celli, facei, oppositeFaceLabels);
175 
176  if (oppositeFaceLabels.size())
177  {
178  label sz = this->changedCells_.size();
179  this->updateCell
180  (
181  celli,
182  facei,
183  neighbourWallInfo,
184  this->propagationTol_,
185  currentWallInfo
186  );
187  if (this->changedCells_.size() > sz)
188  {
189  label oppFacei = -1;
190  if (oppositeFaceLabels.size() == 1)
191  {
192  oppFacei = oppositeFaceLabels[0];
193  }
194  changedOppositeFaces_.append(oppFacei);
195  }
196  }
197  }
198  }
199 
200  // Neighbour.
201  if (facei < nInternalFaces)
202  {
203  label celli = neighbour[facei];
204  Type& currentWallInfo2 = this->allCellInfo_[celli];
205 
206  if (!currentWallInfo2.equal(neighbourWallInfo, this->td_))
207  {
208  // Check if cell is prismatic w.r.t facei
209  opposingFaceLabels(celli, facei, oppositeFaceLabels);
210 
211  if (oppositeFaceLabels.size())
212  {
213  label sz = this->changedCells_.size();
214  this->updateCell
215  (
216  celli,
217  facei,
218  neighbourWallInfo,
219  this->propagationTol_,
220  currentWallInfo2
221  );
222  if (this->changedCells_.size() > sz)
223  {
224  label oppFacei = -1;
225  if (oppositeFaceLabels.size() == 1)
226  {
227  oppFacei = oppositeFaceLabels[0];
228  }
229  changedOppositeFaces_.append(oppFacei);
230  }
231  }
232  }
233  }
234 
235  // Reset status of face
236  this->changedFace_.unset(facei);
237  }
238 
239  // Handled all changed faces by now
240  this->changedFaces_.clear();
241 
242  if (debug & 2)
243  {
244  Pout<< " Changed cells : " << this->changedCells_.size()
245  << endl;
246  }
247 
248  // Sum changedCells over all procs
249  label totNChanged = this->changedCells_.size();
250 
251  reduce(totNChanged, sumOp<label>());
252 
253  return totNChanged;
254 }
255 
256 
257 template<class Type, class TrackingData>
259 {
260  forAll(this->changedCells_, changedCelli)
261  {
262  label celli = this->changedCells_[changedCelli];
263  label facei = changedOppositeFaces_[changedCelli];
264 
265  if (!this->changedCell_.test(celli))
266  {
268  << "Cell " << celli << " not marked as having been changed"
269  << abort(FatalError);
270  }
271 
272  if (facei != -1)
273  {
274  const Type& neighbourWallInfo = this->allCellInfo_[celli];
275 
276  // Evaluate facei
277 
278  Type& currentWallInfo = this->allFaceInfo_[facei];
279 
280  if (!currentWallInfo.equal(neighbourWallInfo, this->td_))
281  {
282  this->updateFace
283  (
284  facei,
285  celli,
286  neighbourWallInfo,
287  this->propagationTol_,
288  currentWallInfo
289  );
290  }
291  }
292 
293  // Reset status of cell
294  this->changedCell_.unset(celli);
295  }
296 
297  // Handled all changed cells by now
298  this->changedCells_.clear();
299  changedOppositeFaces_.clear();
300 
301  if (this->hasCyclicPatches_)
302  {
303  // Transfer changed faces across cyclic halves
304  this->handleCyclicPatches();
305  }
306 
307  if (this->hasCyclicAMIPatches_)
308  {
309  this->handleAMICyclicPatches();
310  }
311 
312  if (Pstream::parRun())
313  {
314  // Transfer changed faces from neighbouring processors.
315  this->handleProcPatches();
316  }
317 
318  if (debug & 2)
319  {
320  Pout<< " Changed faces : " << this->changedFaces_.size()
321  << endl;
322  }
323 
324  // Sum nChangedFaces over all procs
325  label totNChanged = this->changedFaces_.size();
326 
327  reduce(totNChanged, sumOp<label>());
328 
329  return totNChanged;
330 }
331 
332 
333 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::OppositeFaceCellWave::faceToCell
virtual label faceToCell()
Propagate from face to cell. Returns total number of cells.
Definition: OppositeFaceCellWave.C:141
Foam::DynamicList< label >
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
polyMesh.H
Foam::DynamicList::clear
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:391
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
Foam::FatalError
error FatalError
reduce
reduce(hasMovingMesh, orOp< bool >())
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::OppositeFaceCellWave::opposingFaceLabels
void opposingFaceLabels(const label celli, const label facei, DynamicList< label > &) const
Determine 'opposite' faces (= faces not sharing a vertex) on cell.
Definition: OppositeFaceCellWave.C:35
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::FaceCellWave
Wave propagation of information through grid. Every iteration information goes through one layer of c...
Definition: FaceCellWave.H:78
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OppositeFaceCellWave.H
Foam::OppositeFaceCellWave::OppositeFaceCellWave
OppositeFaceCellWave(const polyMesh &, const labelList &initialChangedFaces, const List< Type > &changedFacesInfo, UList< Type > &allFaceInfo, UList< Type > &allCellInfo, const label maxIter, TrackingData &td=FaceCellWave< Type, TrackingData >::dummyTrackData_)
Definition: OppositeFaceCellWave.C:100
Foam::List< label >
Foam::UList< Type >
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::OppositeFaceCellWave::cellToFace
virtual label cellToFace()
Propagate from cell to face. Returns total number of faces.
Definition: OppositeFaceCellWave.C:258