cellEdgeAddressing.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) 2022-2023 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 "cellEdgeAddressing.H"
27 #include "polyDistributionMap.H"
28 #include "polyTopoChangeMap.H"
29 #include "polyMeshMap.H"
30 #include "HashList.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 
37 // An edge hash functor that is much faster than Hash<edge>, but is also more
38 // prone to collisions
40 {
41  unsigned operator()(const edge& e)
42  {
43  return e[0]*e[1];
44  }
45 };
46 
47 // An invalid null edge for unset entries in the edge map
48 template<>
50 
51 // Workspace for addressing calculations
53 {
55 
57 
59  :
60  edgeToCei(0),
61  cfei0()
62  {
63  resizeAndClear(6, 12);
64  }
65 
66  void resizeAndClear(const label nCellFaces, const label nCellEdges)
67  {
68  if (edgeToCei.capacity() < nCellEdges)
69  {
70  edgeToCei.resizeAndClear(nCellEdges*6);
71  }
72  else
73  {
74  edgeToCei.clear();
75  }
76 
77  cfei0.resize(nCellFaces);
78  cfei0 = -1;
79  }
80 }
82 
83 }
84 
85 
86 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
87 
89 (
90  const cell& c,
91  const faceList& fs,
92  const bool cOwnsFirst
93 )
94 {
95  // Allocate and initialise the addressing
96  cfiAndFeiToCei_.resize(UIndirectList<face>(fs, c));
97  ceiToCfiAndFei_ =
99  (
100  cfiAndFeiToCei_.m().size()/2,
101  Pair<labelPair>(labelPair(-1, -1), labelPair(-1, -1))
102  );
103 
104  // Resize and reset the workspace
105  workspace_.resizeAndClear(c.size(), ceiToCfiAndFei_.size());
106 
107  // Construct a map to enumerate the cell edges
108  {
109  label cellEdgei = 0;
110 
111  forAll(c, cfi)
112  {
113  const face& f = fs[c[cfi]];
114 
115  forAll(f, fei)
116  {
117  cellEdgei +=
118  workspace_.edgeToCei.insert(f.faceEdge(fei), cellEdgei);
119  }
120  }
121  }
122 
123  // Copy data out of the map into the addressing
124  forAll(c, cfi)
125  {
126  const face& f = fs[c[cfi]];
127 
128  cfiAndFeiToCei_[cfi] = -1;
129 
130  forAll(f, fei)
131  {
132  const label cei = workspace_.edgeToCei[f.faceEdge(fei)];
133 
134  cfiAndFeiToCei_[cfi][fei] = cei;
135  ceiToCfiAndFei_[cei]
136  [
137  ceiToCfiAndFei_[cei][0] != labelPair(-1, -1)
138  ] = {cfi, fei};
139  }
140  }
141 
142  // Allocate and initialise the face ownership
143  cOwns_ = boolList(c.size(), false);
144  cOwns_[0] = cOwnsFirst;
145  workspace_.cfei0[0] = 0;
146 
147  // Walk around the cell, comparing edges to determine face ownership
148  {
149  label cfi = 0, fei = 0;
150 
151  do
152  {
153  // Get the adjacent face and face-edge (given subscript j)
154  const label cei = cfiAndFeiToCei_[cfi][fei];
155  const labelPair cfiAndFei(labelPair(cfi, fei));
156  const labelPair& cfjAndFej =
157  ceiToCfiAndFei_[cei][ceiToCfiAndFei_[cei][0] == cfiAndFei];
158  const label cfj = cfjAndFej[0], fej = cfjAndFej[1];
159 
160  // If the adjacent face has not been visited then set its ownership
161  // and it's starting face edge and move forwards into it
162  if (workspace_.cfei0[cfj] == -1)
163  {
164  // If the face-edges point in different directions then the
165  // faces have the same owner. If they point in the same
166  // direction then they have different owners.
167  const label sign =
169  (
170  fs[c[cfi]].faceEdge(fei),
171  fs[c[cfj]].faceEdge(fej)
172  );
173 
174  cOwns_[cfj] = sign < 0 ? cOwns_[cfi] : !cOwns_[cfi];
175 
176  workspace_.cfei0[cfj] = fej;
177  cfi = cfj;
178  fei = (fej + 1) % fs[c[cfj]].size();
179  }
180 
181  // If the adjacent face has been visited, and we are not back at
182  // the starting edge of this face, then move to the next edge of
183  // this face
184  else if (fei != workspace_.cfei0[cfi])
185  {
186  fei = (fei + 1) % fs[c[cfi]].size();
187  }
188 
189  // If we are back at the first edge then this face is complete, so
190  // move backwards into the adjacent face
191  else // if (fei == workspace_.cfei0[cfi])
192  {
193  cfi = cfj;
194  fei = fej;
195  }
196  }
197  while (cfi != 0 || fei != 0);
198  }
199 }
200 
201 
203 :
205  <
206  polyMesh,
209  >(mesh),
210  list_(mesh.nCells())
211 {}
212 
213 
214 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
215 
217 {
218  return true;
219 }
220 
221 
223 {
224  // We could be more selective here and try to keep addressing for cells
225  // that haven't changed
226 
227  list_.clear();
228  list_.resize(map.mesh().nCells());
229 }
230 
231 
233 {
234  // We could be more selective here and try to keep addressing for cells
235  // that haven't changed
236 
237  list_.clear();
238  list_.resize(map.mesh().nCells());
239 }
240 
241 
243 {
244  list_.clear();
245  list_.resize(map.mesh().nCells());
246 }
247 
248 
249 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
void resize(const label mRows)
Reset size of CompactListList.
Templated abstract base-class for demand-driven mesh objects used to automate their allocation to the...
void resize(const label)
Alter the addressed list size.
Definition: DynamicListI.H:216
HashList class. Like HashTable, but much less dynamic memory-y. Should be faster for small sets of no...
Definition: HashList.H:60
static const Key nullKey
Null key value for unset elements in the list.
Definition: HashList.H:66
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:65
const UList< T > & m() const
Return the packed matrix of data.
A List with indirect addressing.
Definition: UIndirectList.H:60
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
cellEdgeAddressingData(const cell &c, const faceList &fs, const bool cOwnsFirst)
Construct from a cell and its faces.
virtual bool movePoints()
Update following mesh motion.
cellEdgeAddressingList(const polyMesh &mesh)
Construct for a mesh.
virtual void mapMesh(const polyMeshMap &map)
Update following mapping.
virtual void distribute(const polyDistributionMap &map)
Update following mesh distribution.
virtual void topoChange(const polyTopoChangeMap &map)
Update following topology change.
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:60
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:61
static int compare(const edge &, const edge &)
Compare edges.
Definition: edgeI.H:36
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:76
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
const polyMesh & mesh() const
Return polyMesh.
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
const polyMesh & mesh() const
Return polyMesh.
Definition: polyMeshMap.H:75
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const polyMesh & mesh() const
Return polyMesh.
label nCells() const
const dimensionedScalar c
Speed of light in a vacuum.
Namespace for OpenFOAM.
Pair< label > labelPair
Label pair.
Definition: labelPair.H:48
const doubleScalar e
Definition: doubleScalar.H:105
dimensionedScalar sign(const dimensionedScalar &ds)
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
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
struct Foam::cellEdgeAddressingWorkspace workspace_
static const label labelMax
Definition: label.H:62
labelList f(nPoints)
unsigned operator()(const edge &e)
HashList< label, edge, QuickHashEdge > edgeToCei
void resizeAndClear(const label nCellFaces, const label nCellEdges)