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-------------------------------------------------------------------------------
10License
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
29#include "polyMesh.H"
30
31// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
32
33template<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.
98template<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:
110 FaceCellWave<Type, TrackingData>
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
140template<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
257template<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// ************************************************************************* //
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:391
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:503
Wave propagation of information through grid. Every iteration information goes through one layer of c...
Definition: FaceCellWave.H:81
DynamicList< label > changedCells_
Definition: FaceCellWave.H:125
DynamicList< label > changedFaces_
List of changed faces.
Definition: FaceCellWave.H:122
virtual label iterate(const label maxIter)
Iterate until no changes or maxIter reached.
Version of FaceCellWave that walks through prismatic cells only.
void opposingFaceLabels(const label celli, const label facei, DynamicList< label > &) const
Determine 'opposite' faces (= faces not sharing a vertex) on cell.
virtual label faceToCell()
Propagate from face to cell. Returns total number of cells.
virtual label cellToFace()
Propagate from cell to face. Returns total number of faces.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333