walkPatch.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) 2011-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 "walkPatch.H"
27 #include "ListOps.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
34 }
35 
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 Foam::label Foam::walkPatch::getNeighbour
40 (
41  const label facei,
42  const label fp,
43  const label v0,
44  const label v1
45 ) const
46 {
47  const labelList& fEdges = pp_.faceEdges()[facei];
48 
49  const edgeList& edges = pp_.edges();
50 
51 
52  label nbrEdgeI = -1;
53 
54  // Shortcut: maybe faceEdges are sorted(?) in which case fEdges[fp] is
55  // edge between v0 and v1.
56  const edge& e = edges[fEdges[fp]];
57 
58  if ((e[0] == v0 && e[1] == v1) || (e[0] == v1 && e[1] == v0))
59  {
60  // Correct edge.
61  nbrEdgeI = fEdges[fp];
62  }
63  else
64  {
65  // Loop over all faceEdges.
66  forAll(fEdges, i)
67  {
68  label edgeI = fEdges[i];
69 
70  const edge& e = edges[edgeI];
71 
72  if
73  (
74  (e[0] == v0 && e[1] == v1)
75  || (e[0] == v1 && e[1] == v0)
76  )
77  {
78  // Found edge on face which uses v0, v1.
79  nbrEdgeI = edgeI;
80 
81  break;
82  }
83  }
84  }
85 
86 
87  if (nbrEdgeI == -1)
88  {
90  << "Did not find edge on face " << facei << " that uses vertices"
91  << v0 << " and " << v1 << abort(FatalError);
92  }
93 
94 
95  // Get neighbouring face.
96 
97  const labelList& eFaces = pp_.edgeFaces()[nbrEdgeI];
98 
99  if (eFaces.size() == 1)
100  {
101  return -1;
102  }
103  else if (eFaces.size() == 2)
104  {
105  label nbrFacei = eFaces[0];
106 
107  if (nbrFacei == facei)
108  {
109  nbrFacei = eFaces[1];
110  }
111 
112  return nbrFacei;
113  }
114  else
115  {
117  << "Illegal surface on patch. Face " << facei
118  << " at vertices " << v0 << ',' << v1
119  << " has fewer than 1 or more than 2 neighbours"
120  << abort(FatalError);
121  return -1;
122  }
123 }
124 
125 
126 void Foam::walkPatch::faceToFace
127 (
128  const labelList& changedFaces,
129  const labelList& enterVerts,
130 
131  labelList& nbrFaces,
132  labelList& nbrEnterVerts
133 )
134 {
135  nbrFaces.setSize(pp_.size());
136  nbrEnterVerts.setSize(pp_.size());
137  label changedI = 0;
138 
139  forAll(changedFaces, i)
140  {
141  label facei = changedFaces[i];
142  label enterVertI = enterVerts[i];
143 
144  if (!visited_[facei])
145  {
146  // Do this face
147  visited_[facei] = true;
148  visitOrder_.append(facei);
149 
150  const face& f = pp_.localFaces()[facei];
151 
152  label fp = findIndex(f, enterVertI);
153 
154  indexInFace_.append(fp);
155 
156  // Visit neighbouring faces in order, starting at fp.
157  forAll(f, i)
158  {
159  label fp1 = reverse_ ? f.rcIndex(fp) : f.fcIndex(fp);
160  label nbr = getNeighbour(facei, fp, f[fp], f[fp1]);
161 
162  if
163  (
164  nbr != -1
165  && !visited_[nbr]
166  && faceZone_[nbr] == faceZone_[facei]
167  )
168  {
169  nbrFaces[changedI] = nbr;
170  nbrEnterVerts[changedI] = f[fp];
171  changedI++;
172  }
173 
174  fp = fp1;
175  }
176  }
177  }
178 
179  nbrFaces.setSize(changedI);
180  nbrEnterVerts.setSize(changedI);
181 }
182 
183 
184 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
185 
187 (
188  const primitivePatch& pp,
189  const labelList& faceZone,
190  const bool reverse,
191  const label facei,
192  const label enterVertI,
193  boolList& visited
194 )
195 :
196  pp_(pp),
197  faceZone_(faceZone),
198  reverse_(reverse),
199  visited_(visited),
200  visitOrder_(pp.size()),
201  indexInFace_(pp.size())
202 {
203  // List of faces that have been visited in the current iteration.
204  labelList changedFaces(1, facei);
205  // Corresponding list of entry vertices
206  labelList enterVerts(1, enterVertI);
207 
208  while (true)
209  {
210  labelList nbrFaces;
211  labelList nbrEnterVerts;
212 
213  faceToFace
214  (
215  changedFaces,
216  enterVerts,
217 
218  nbrFaces,
219  nbrEnterVerts
220  );
221 
222 
223  if (nbrFaces.empty())
224  {
225  break;
226  }
227 
228  changedFaces = nbrFaces;
229  enterVerts = nbrEnterVerts;
230  }
231 
232  visitOrder_.shrink();
233  indexInFace_.shrink();
234 }
235 
236 
237 // ************************************************************************* //
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:252
void setSize(const label)
Reset size of List.
Definition: List.C:281
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
const labelListList & edgeFaces() const
Return edge-face addressing.
const labelListList & faceEdges() const
Return face-edge addressing.
label rcIndex(const label i) const
Return the reverse circular index, i.e. the previous index.
Definition: UListI.H:65
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Definition: UListI.H:58
bool empty() const
Return true if the UList is empty (ie, size() is zero)
Definition: UListI.H:325
A topoSetSource to select faces based on usage in another faceSet.
Definition: faceToFace.H:51
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:59
Collection of static functions to do various simple patch related things.
Definition: walkPatch.H:50
walkPatch(const primitivePatch &pp, const labelList &faceZone, const bool reverse, const label facei, const label enterVertI, boolList &visited)
Construct from components.
Definition: walkPatch.C:187
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
Namespace for OpenFOAM.
const doubleScalar e
Definition: doubleScalar.H:106
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void reverse(UList< T > &, const label n)
Definition: UListI.H:334
defineTypeNameAndDebug(combustionModel, 0)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
error FatalError
List< edge > edgeList
Definition: edgeList.H:38
labelList f(nPoints)