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  Copyright (C) 2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 
30 #include "polyMesh.H"
31 
32 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
33 
34 template<class Type, class TrackingData>
36 (
37  const label celli,
38  const label masterFaceLabel,
39  DynamicList<label>& oppositeFaceLabels
40 ) const
41 {
42  // Variant of cell::opposingFaceLabel
43 
44  // Algorithm:
45  // Go through all the faces of the cell and find the one which
46  // does not share a single vertex with the master face. If there
47  // are two or more such faces, return the first one and issue a
48  // warning; if there is no opposite face, return -1;
49 
50  const face& masterFace = this->mesh_.faces()[masterFaceLabel];
51 
52  oppositeFaceLabels.clear();
53 
54  for (const label facei : this->mesh_.cells()[celli])
55  {
56  // Compare the face with the master
57  const face& f = this->mesh_.faces()[facei];
58 
59  // Skip the master face
60  if
61  (
62  facei != masterFaceLabel
63  && !f.connected(masterFace)
64  )
65  {
66  // Not connected : this is an opposite face
67  oppositeFaceLabels.push_back(facei);
68  }
69  }
70 }
71 
72 
73 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
74 
75 // Iterate, propagating changedFacesInfo across mesh, until no change (or
76 // maxIter reached). Initial cell values specified.
77 template<class Type, class TrackingData>
79 (
80  const polyMesh& mesh,
81  const labelList& changedFaces,
82  const List<Type>& changedFacesInfo,
83  UList<Type>& allFaceInfo,
84  UList<Type>& allCellInfo,
85  const label maxIter,
86  TrackingData& td
87 )
88 :
89  FaceCellWave<Type, TrackingData>
90  (
91  mesh,
92  changedFaces,
93  changedFacesInfo,
94  allFaceInfo,
95  allCellInfo,
96  0, //maxIter,
97  td
98  ),
100 {
101  // Iterate until nothing changes
102  label iter = this->iterate(maxIter);
103 
104  if ((maxIter > 0) && (iter >= maxIter))
105  {
107  << "Maximum number of iterations reached. Increase maxIter."
108  << endl
109  << " maxIter:" << maxIter << endl
110  << " nChangedCells:" << this->nChangedCells() << endl
111  << " nChangedFaces:" << this->nChangedFaces() << endl
112  << exit(FatalError);
113  }
114 }
115 
116 
117 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
118 
119 template<class Type, class TrackingData>
121 {
122  const labelList& owner = this->mesh_.faceOwner();
123  const labelList& neighbour = this->mesh_.faceNeighbour();
124  label nInternalFaces = this->mesh_.nInternalFaces();
125 
126  DynamicList<label> oppositeFaceLabels;
127 
128  for (const label facei : this->changedFaces_)
129  {
130  if (!this->changedFace_.test(facei))
131  {
133  << "Face " << facei
134  << " not marked as having been changed"
135  << abort(FatalError);
136  }
137 
138 
139  const Type& neighbourWallInfo = this->allFaceInfo_[facei];
140 
141  // Evaluate all connected cells
142 
143  // Owner
144  {
145  label celli = owner[facei];
146  Type& currentWallInfo = this->allCellInfo_[celli];
147 
148  if (!currentWallInfo.equal(neighbourWallInfo, this->td_))
149  {
150  // Check if cell is prismatic w.r.t facei
151  opposingFaceLabels(celli, facei, oppositeFaceLabels);
152 
153  if (oppositeFaceLabels.size())
154  {
155  label sz = this->nChangedCells();
156  this->updateCell
157  (
158  celli,
159  facei,
160  neighbourWallInfo,
161  this->propagationTol_,
162  currentWallInfo
163  );
164  if (this->nChangedCells() > sz)
165  {
166  label oppFacei = -1;
167  if (oppositeFaceLabels.size() == 1)
168  {
169  oppFacei = oppositeFaceLabels.front();
170  }
171  changedOppositeFaces_.push_back(oppFacei);
172  }
173  }
174  }
175  }
176 
177  // Neighbour.
178  if (facei < nInternalFaces)
179  {
180  label celli = neighbour[facei];
181  Type& currentWallInfo2 = this->allCellInfo_[celli];
182 
183  if (!currentWallInfo2.equal(neighbourWallInfo, this->td_))
184  {
185  // Check if cell is prismatic w.r.t facei
186  opposingFaceLabels(celli, facei, oppositeFaceLabels);
187 
188  if (oppositeFaceLabels.size())
189  {
190  label sz = this->nChangedCells();
191  this->updateCell
192  (
193  celli,
194  facei,
195  neighbourWallInfo,
196  this->propagationTol_,
197  currentWallInfo2
198  );
199  if (this->nChangedCells() > sz)
200  {
201  label oppFacei = -1;
202  if (oppositeFaceLabels.size() == 1)
203  {
204  oppFacei = oppositeFaceLabels.front();
205  }
206  changedOppositeFaces_.push_back(oppFacei);
207  }
208  }
209  }
210  }
211 
212  // Reset status of face
213  this->changedFace_.unset(facei);
214  }
215 
216  // Handled all changed faces by now
217  this->changedFaces_.clear();
218 
219  if (debug & 2)
220  {
221  Pout<< " Changed cells : " << this->nChangedCells() << endl;
222  }
224  // Sum changedCells over all procs
225  return returnReduce(this->nChangedCells(), sumOp<label>());
226 }
227 
228 
229 template<class Type, class TrackingData>
231 {
232  forAll(this->changedCells_, changedCelli)
233  {
234  label celli = this->changedCells_[changedCelli];
235  label facei = changedOppositeFaces_[changedCelli];
236 
237  if (!this->changedCell_.test(celli))
238  {
240  << "Cell " << celli << " not marked as having been changed"
241  << abort(FatalError);
242  }
243 
244  if (facei != -1)
245  {
246  const Type& neighbourWallInfo = this->allCellInfo_[celli];
247 
248  // Evaluate facei
249 
250  Type& currentWallInfo = this->allFaceInfo_[facei];
251 
252  if (!currentWallInfo.equal(neighbourWallInfo, this->td_))
253  {
254  this->updateFace
255  (
256  facei,
257  celli,
258  neighbourWallInfo,
259  this->propagationTol_,
260  currentWallInfo
261  );
262  }
263  }
264 
265  // Reset status of cell
266  this->changedCell_.unset(celli);
267  }
268 
269  // Handled all changed cells by now
270  this->changedCells_.clear();
271  changedOppositeFaces_.clear();
272 
273  if (this->hasCyclicPatches_)
274  {
275  // Transfer changed faces across cyclic halves
276  this->handleCyclicPatches();
277  }
278 
279  if (this->hasCyclicAMIPatches_)
280  {
281  this->handleAMICyclicPatches();
282  }
283 
284  if (Pstream::parRun())
285  {
286  // Transfer changed faces from neighbouring processors.
287  this->handleProcPatches();
288  }
289 
290  if (debug & 2)
291  {
292  Pout<< " Changed faces : " << this->nChangedFaces()
293  << endl;
294  }
295 
296  // Sum changedFaces over all procs
297  return returnReduce(this->nChangedFaces(), sumOp<label>());
298 }
299 
300 
301 // ************************************************************************* //
OppositeFaceCellWave(const polyMesh &, const labelList &initialChangedFaces, const List< Type > &changedFacesInfo, UList< Type > &allFaceInfo, UList< Type > &allCellInfo, const label maxIter, TrackingData &td=FaceCellWaveBase::dummyTrackData_)
Construct from mesh and list of changed faces with the Type for these faces.
virtual label iterate(const label maxIter)
Iterate until no changes or maxIter reached.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:68
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
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:531
Wave propagation of information through grid. Every iteration information goes through one layer of c...
Definition: FaceCellWave.H:206
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1049
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
dynamicFvMesh & mesh
void opposingFaceLabels(const label celli, const label facei, DynamicList< label > &) const
Determine &#39;opposite&#39; faces (= faces not sharing a vertex) on cell.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
virtual label faceToCell()
Propagate from face to cell. Returns total number of cells.
int debug
Static debugging option.
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:405
labelList f(nPoints)
void push_back(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:555
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
List< label > labelList
A List of labels.
Definition: List.H:62
label nChangedFaces() const noexcept
Current number of changed faces.
Definition: FaceCellWave.H:181
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
label nChangedCells() const noexcept
Current number of changed cells.
Definition: FaceCellWave.H:176