OppositeFaceCellWave.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2016-2018 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 "OppositeFaceCellWave.H"
27 #include "polyMesh.H"
28 
29 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
30 
31 template<class Type, class TrackingData>
33 (
34  const label celli,
35  const label masterFaceLabel,
36  DynamicList<label>& oppositeFaceLabels
37 ) const
38 {
39  // Variant of cell::opposingFaceLabel
40 
41  // Algorithm:
42  // Go through all the faces of the cell and find the one which
43  // does not share a single vertex with the master face. If there
44  // are two or more such faces, return the first one and issue a
45  // warning; if there is no opposite face, return -1;
46 
47  const face& masterFace = this->mesh_.faces()[masterFaceLabel];
48 
49  const labelList& curFaceLabels = this->mesh_.cells()[celli];
50 
51  oppositeFaceLabels.clear();
52 
53  forAll(curFaceLabels, facei)
54  {
55  // Compare the face with the master
56  const face& curFace = this->mesh_.faces()[curFaceLabels[facei]];
57 
58  // Skip the master face
59  if (curFaceLabels[facei] != masterFaceLabel)
60  {
61  bool sharedPoint = false;
62 
63  // Compare every vertex of the current face against the
64  // vertices of the master face
65  forAll(curFace, pointi)
66  {
67  const label l = curFace[pointi];
68 
69  forAll(masterFace, masterPointi)
70  {
71  if (masterFace[masterPointi] == l)
72  {
73  sharedPoint = true;
74  break;
75  }
76  }
77 
78  if (sharedPoint) break;
79  }
80 
81  // If no points are shared, this is the opposite face
82  if (!sharedPoint)
83  {
84  // Found opposite face
85  oppositeFaceLabels.append(curFaceLabels[facei]);
86  }
87  }
88  }
89 }
90 
91 
92 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
93 
94 // Iterate, propagating changedFacesInfo across mesh, until no change (or
95 // maxIter reached). Initial cell values specified.
96 template<class Type, class TrackingData>
98 (
99  const polyMesh& mesh,
100  const labelList& changedFaces,
101  const List<Type>& changedFacesInfo,
102  UList<Type>& allFaceInfo,
103  UList<Type>& allCellInfo,
104  const label maxIter,
105  TrackingData& td
106 )
107 :
109  (
110  mesh,
111  changedFaces,
112  changedFacesInfo,
113  allFaceInfo,
114  allCellInfo,
115  0, // maxIter,
116  td
117  ),
118  changedOppositeFaces_(this->mesh_.nCells())
119 {
120  // Iterate until nothing changes
121  label iter = this->iterate(maxIter);
122 
123  if ((maxIter > 0) && (iter >= maxIter))
124  {
126  << "Maximum number of iterations reached. Increase maxIter."
127  << endl
128  << " maxIter:" << maxIter << endl
129  << " nChangedCells:" << this->changedCells_.size() << endl
130  << " nChangedFaces:" << this->changedFaces_.size() << endl
131  << exit(FatalError);
132  }
133 }
134 
135 
136 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
137 
138 template<class Type, class TrackingData>
140 {
141  const labelList& owner = this->mesh_.faceOwner();
142  const labelList& neighbour = this->mesh_.faceNeighbour();
143  label nInternalFaces = this->mesh_.nInternalFaces();
144 
145  DynamicList<label> oppositeFaceLabels;
146 
147  forAll(this->changedFaces_, changedFacei)
148  {
149  label facei = this->changedFaces_[changedFacei];
150 
151  if (!this->changedFace_[facei])
152  {
154  << "Face " << facei
155  << " not marked as having been changed"
156  << abort(FatalError);
157  }
158 
159 
160  const Type& neighbourWallInfo = this->allFaceInfo_[facei];
161 
162  // Evaluate all connected cells
163 
164  // Owner
165  {
166  label celli = owner[facei];
167  Type& currentWallInfo = this->allCellInfo_[celli];
168 
169  if (!currentWallInfo.equal(neighbourWallInfo, this->td_))
170  {
171  // Check if cell is prismatic w.r.t facei
172  opposingFaceLabels(celli, facei, oppositeFaceLabels);
173 
174  if (oppositeFaceLabels.size())
175  {
176  label sz = this->changedCells_.size();
177  this->updateCell
178  (
179  celli,
180  facei,
181  neighbourWallInfo,
182  this->propagationTol_,
183  currentWallInfo
184  );
185  if (this->changedCells_.size() > sz)
186  {
187  label oppFacei = -1;
188  if (oppositeFaceLabels.size() == 1)
189  {
190  oppFacei = oppositeFaceLabels[0];
191  }
192  changedOppositeFaces_.append(oppFacei);
193  }
194  }
195  }
196  }
197 
198  // Neighbour.
199  if (facei < nInternalFaces)
200  {
201  label celli = neighbour[facei];
202  Type& currentWallInfo2 = this->allCellInfo_[celli];
203 
204  if (!currentWallInfo2.equal(neighbourWallInfo, this->td_))
205  {
206  // Check if cell is prismatic w.r.t facei
207  opposingFaceLabels(celli, facei, oppositeFaceLabels);
208 
209  if (oppositeFaceLabels.size())
210  {
211  label sz = this->changedCells_.size();
212  this->updateCell
213  (
214  celli,
215  facei,
216  neighbourWallInfo,
217  this->propagationTol_,
218  currentWallInfo2
219  );
220  if (this->changedCells_.size() > sz)
221  {
222  label oppFacei = -1;
223  if (oppositeFaceLabels.size() == 1)
224  {
225  oppFacei = oppositeFaceLabels[0];
226  }
227  changedOppositeFaces_.append(oppFacei);
228  }
229  }
230  }
231  }
232 
233  // Reset status of face
234  this->changedFace_[facei] = false;
235  }
236 
237  // Handled all changed faces by now
238  this->changedFaces_.clear();
239 
240  if (debug & 2)
241  {
242  Pout<< " Changed cells : " << this->changedCells_.size()
243  << endl;
244  }
245 
246  // Sum changedCells over all procs
247  label totNChanged = this->changedCells_.size();
248 
249  reduce(totNChanged, sumOp<label>());
250 
251  return totNChanged;
252 }
253 
254 
255 template<class Type, class TrackingData>
257 {
258  forAll(this->changedCells_, changedCelli)
259  {
260  label celli = this->changedCells_[changedCelli];
261  label facei = changedOppositeFaces_[changedCelli];
262 
263  if (!this->changedCell_[celli])
264  {
266  << "Cell " << celli << " not marked as having been changed"
267  << abort(FatalError);
268  }
269 
270  if (facei != -1)
271  {
272  const Type& neighbourWallInfo = this->allCellInfo_[celli];
273 
274  // Evaluate facei
275 
276  Type& currentWallInfo = this->allFaceInfo_[facei];
277 
278  if (!currentWallInfo.equal(neighbourWallInfo, this->td_))
279  {
280  this->updateFace
281  (
282  facei,
283  celli,
284  neighbourWallInfo,
285  this->propagationTol_,
286  currentWallInfo
287  );
288  }
289  }
290 
291  // Reset status of cell
292  this->changedCell_[celli] = false;
293  }
294 
295  // Handled all changed cells by now
296  this->changedCells_.clear();
297  changedOppositeFaces_.clear();
298 
299  if (this->hasCyclicPatches_)
300  {
301  // Transfer changed faces across cyclic halves
302  this->handleCyclicPatches();
303  }
304 
305  if (this->hasCyclicAMIPatches_)
306  {
307  this->handleAMICyclicPatches();
308  }
309 
310  if (Pstream::parRun())
311  {
312  // Transfer changed faces from neighbouring processors.
313  this->handleProcPatches();
314  }
315 
316  if (debug & 2)
317  {
318  Pout<< " Changed faces : " << this->changedFaces_.size()
319  << endl;
320  }
321 
322  // Sum nChangedFaces over all procs
323  label totNChanged = this->changedFaces_.size();
324 
325  reduce(totNChanged, sumOp<label>());
326 
327  return totNChanged;
328 }
329 
330 
331 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
virtual label cellToFace()
Propagate from cell to face. Returns total number of faces.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Wave propagation of information through grid. Every iteration information goes through one layer of c...
Definition: FaceCellWave.H:76
fvMesh & mesh
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
void opposingFaceLabels(const label celli, const label facei, DynamicList< label > &) const
Determine &#39;opposite&#39; faces (= faces not sharing a vertex) on cell.
OppositeFaceCellWave(const polyMesh &, const labelList &initialChangedFaces, const List< Type > &changedFacesInfo, UList< Type > &allFaceInfo, UList< Type > &allCellInfo, const label maxIter, TrackingData &td=FaceCellWave< Type, TrackingData >::defaultTrackingData_)
Construct from mesh and list of changed faces with the Type.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
errorManip< error > abort(error &err)
Definition: errorManip.H:131
virtual label faceToCell()
Propagate from face to cell. Returns total number of cells.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:76
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:236