cellPointConnectivity.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) 2024-2025 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
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 
28 #include "cellPointConnectivity.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34  defineTypeNameAndDebug(cellPointConnectivity, 0);
35 }
36 
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 void Foam::cellPointConnectivity::generateCellPointConnectivity(label cellI)
41 {
42  const cell& cFaceLabels(mesh_.cells()[cellI]);
43  const labelList cPointLabels(cFaceLabels.labels(mesh_.faces()));
44  const edgeList cEdges(cFaceLabels.edges(mesh_.faces()));
45 
46  // Generate a sorted list of points and corresponding point indices
47  labelPairList pointLabelPointIndices(cPointLabels.size());
48  forAll(cPointLabels, pointI)
49  {
50  pointLabelPointIndices[pointI] =
51  labelPair(cPointLabels[pointI], pointI);
52  }
53  sort(pointLabelPointIndices);
54 
55  // Generate a sorted list of edge labels and corresponding edge indices
56  // Negative values indicate an edge which runs in an opposite direction to
57  // the face node listing
58  labelListList edgeLabelsEdgeIndices
59  (
60  2*cEdges.size(),
61  labelList(3, label(-1))
62  );
63  forAll(cEdges, cEdgeI)
64  {
65  edgeLabelsEdgeIndices[2*cEdgeI][0] = cEdges[cEdgeI][0];
66  edgeLabelsEdgeIndices[2*cEdgeI][1] = cEdges[cEdgeI][1];
67  edgeLabelsEdgeIndices[2*cEdgeI][2] = cEdgeI;
68 
69  edgeLabelsEdgeIndices[2*cEdgeI+1][0] = cEdges[cEdgeI][1];
70  edgeLabelsEdgeIndices[2*cEdgeI+1][1] = cEdges[cEdgeI][0];
71  edgeLabelsEdgeIndices[2*cEdgeI+1][2] = - cEdgeI - 1;
72  }
73  sort(edgeLabelsEdgeIndices);
74 
75  // Generate a sorted list of edge labels and correspoinding face indices
76  labelListList edgeLabelsFaceIndices;
77  forAll(cFaceLabels, cFaceI)
78  {
79  const face& cFace(mesh_.faces()[cFaceLabels[cFaceI]]);
80 
81  const bool owner(mesh_.faceOwner()[cFaceLabels[cFaceI]] == cellI);
82 
83  const label cFaceNEdges(cFace.size());
84  forAll(cFace, cFaceEdgeI)
85  {
86  edgeLabelsFaceIndices.append(labelList(3, label(-1)));
87  edgeLabelsFaceIndices.last()[0] =
88  cFace[(cFaceEdgeI + owner) % cFaceNEdges];
89  edgeLabelsFaceIndices.last()[1] =
90  cFace[(cFaceEdgeI + !owner) % cFaceNEdges];
91  edgeLabelsFaceIndices.last()[2] = cFaceI;
92  }
93  }
94  sort(edgeLabelsFaceIndices);
95 
96  // Assemble lists of edge-face and cell-face connectivities
97  // Negative values indicate an edge which runs in an opposite direction to
98  // the face node listing
99  labelListList edgeFaceIndices(cEdges.size());
100  labelListList faceEdgeIndices(cFaceLabels.size());
101  forAll(edgeLabelsFaceIndices, I)
102  {
103  const label edgeLabelsEdgeIndex(edgeLabelsEdgeIndices[I][2]);
104  const label absCellEdgeEdgeIndex
105  (
106  edgeLabelsEdgeIndex >= 0
107  ? edgeLabelsEdgeIndex
108  : - edgeLabelsEdgeIndex - 1
109  );
110  const label absCellEdgeFaceIndex(edgeLabelsFaceIndices[I][2]);
111  const label edgeLabelsFaceIndex
112  (
113  edgeLabelsEdgeIndex >= 0
114  ? absCellEdgeFaceIndex
115  : - absCellEdgeFaceIndex - 1
116  );
117 
118  edgeFaceIndices[absCellEdgeEdgeIndex].append(edgeLabelsFaceIndex);
119  faceEdgeIndices[absCellEdgeFaceIndex].append(edgeLabelsEdgeIndex);
120  }
121 
122  // Generate a list of point labels and face index pairs
123  labelListList pointLabelEdgeIndexFaceIndexPairs;
124  forAll(cEdges, edgeI)
125  {
126  const labelPair pointIndices(cEdges[edgeI]);
127 
128  const labelPair faceIndices
129  (
130  edgeFaceIndices[edgeI][0],
131  edgeFaceIndices[edgeI][1]
132  );
133  const labelPair absFaceIndices
134  (
135  faceIndices[0] >= 0 ? faceIndices[0] : - faceIndices[0] - 1,
136  faceIndices[1] >= 0 ? faceIndices[1] : - faceIndices[1] - 1
137  );
138 
139  const bool order(faceIndices[0] > faceIndices[1]);
140 
141  pointLabelEdgeIndexFaceIndexPairs.append(labelList(4, label(-1)));
142  pointLabelEdgeIndexFaceIndexPairs.last()[0] = pointIndices[0];
143  pointLabelEdgeIndexFaceIndexPairs.last()[1] = edgeI;
144  pointLabelEdgeIndexFaceIndexPairs.last()[2] = absFaceIndices[order];
145  pointLabelEdgeIndexFaceIndexPairs.last()[3] = absFaceIndices[!order];
146 
147  pointLabelEdgeIndexFaceIndexPairs.append(labelList(4, label(-1)));
148  pointLabelEdgeIndexFaceIndexPairs.last()[0] = pointIndices[1];
149  pointLabelEdgeIndexFaceIndexPairs.last()[1] = edgeI;
150  pointLabelEdgeIndexFaceIndexPairs.last()[2] = absFaceIndices[!order];
151  pointLabelEdgeIndexFaceIndexPairs.last()[3] = absFaceIndices[order];
152  }
153  sort(pointLabelEdgeIndexFaceIndexPairs);
154 
155  // Assemble a list of point face pairs from the sorted lists
156  labelListList pointEdgeIndices(cPointLabels.size());
157  List<List<Pair<label> > > pointFaceIndexPairs(cPointLabels.size());
158  {
159  label I(0);
160  label pointLabelOld(pointLabelEdgeIndexFaceIndexPairs[0][0]);
161  forAll
162  (
163  pointLabelEdgeIndexFaceIndexPairs,
164  pointLabelEdgeIndexFaceIndexPairI
165  )
166  {
167  const labelList& pointLabelEdgeIndexFaceIndexPair
168  (
169  pointLabelEdgeIndexFaceIndexPairs
170  [
171  pointLabelEdgeIndexFaceIndexPairI
172  ]
173  );
174 
175  if (pointLabelOld != pointLabelEdgeIndexFaceIndexPair[0])
176  {
177  I ++;
178  pointLabelOld = pointLabelEdgeIndexFaceIndexPair[0];
179  }
180 
181  const label pointI(pointLabelPointIndices[I][1]);
182 
183  pointEdgeIndices[pointI].append
184  (
185  pointLabelEdgeIndexFaceIndexPair[1]
186  );
187 
188  pointFaceIndexPairs[pointI].append
189  (
190  labelPair
191  (
192  pointLabelEdgeIndexFaceIndexPair[2],
193  pointLabelEdgeIndexFaceIndexPair[3]
194  )
195  );
196  }
197  }
198 
199  // Order the point face pairs and assemble a list of point face indices
200  labelListList pointFaceIndices(cPointLabels.size());
201  forAll(pointFaceIndexPairs, pointI)
202  {
203  labelPairList& faceIndexPairs(pointFaceIndexPairs[pointI]);
204 
205  pointFaceIndices[pointI].append(faceIndexPairs[0][0]);
206 
207  for (label pairI = 1; pairI < faceIndexPairs.size(); pairI ++)
208  {
209  for (label pairJ = pairI; pairJ < faceIndexPairs.size(); ++ pairJ)
210  {
211  if (faceIndexPairs[pairI-1][1] == faceIndexPairs[pairJ][0])
212  {
213  Swap
214  (
215  pointEdgeIndices[pointI][pairI],
216  pointEdgeIndices[pointI][pairJ]
217  );
218 
219  Swap
220  (
221  faceIndexPairs[pairI],
222  faceIndexPairs[pairJ]
223  );
224 
225  break;
226  }
227  }
228  pointFaceIndices[pointI].append(faceIndexPairs[pairI][0]);
229  }
230  }
231 
232  // convert to global indices
233  forAll(cPointLabels, pointI)
234  {
235  labelList& edgeIndices(pointEdgeIndices[pointI]);
236  labelList& faceIndices(pointFaceIndices[pointI]);
237 
238  const label nPointFaces(faceIndices.size());
239 
240  cellPointPoints_[cellI][pointI].resize(nPointFaces);
241 
242  forAll(edgeIndices, edgeI)
243  {
244  cellPointPoints_[cellI][pointI][edgeI] =
245  cEdges[edgeIndices[edgeI]]
246  [
247  cEdges[edgeIndices[edgeI]][0] == cPointLabels[pointI]
248  ];
249  }
250 
251  cellPointFaces_[cellI][pointI].resize(nPointFaces);
252 
253  forAll(faceIndices, faceI)
254  {
255  cellPointFaces_[cellI][pointI][faceI] =
256  cFaceLabels
257  [
258  faceIndices[faceI]
259  ];
260  }
261  }
262 }
263 
264 
265 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
266 
267 Foam::cellPointConnectivity::cellPointConnectivity(const polyMesh& mesh)
268 :
269  MoveableMeshObject<polyMesh>(typeName, mesh),
270  mesh_(mesh),
271  cellPointPoints_(mesh.nCells()),
272  cellPointFaces_(mesh.nCells())
273 {
274  forAll(mesh.cells(), cellI)
275  {
276  const label nPoints(mesh.cellPoints()[cellI].size());
277 
278  cellPointPoints_[cellI].resize(nPoints);
279  cellPointFaces_[cellI].resize(nPoints);
280 
281  generateCellPointConnectivity(cellI);
282  }
283 }
284 
285 
286 // ************************************************************************* //
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:150
List< edge > edgeList
List of edge.
Definition: edgeList.H:32
List< labelPair > labelPairList
List of labelPair.
Definition: labelPair.H:33
const cellList & cells() const
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
dynamicFvMesh & mesh
static const Identity< scalar > I
Definition: Identity.H:100
label nPoints
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:295
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1101
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1088
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:51
defineTypeNameAndDebug(combustionModel, 0)
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
Exchange contents of lists - see DynamicList::swap().
Definition: DynamicList.H:717
List< label > labelList
A List of labels.
Definition: List.H:61
Namespace for OpenFOAM.