primitiveMeshPointCells.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2023 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 
29 #include "primitiveMesh.H"
30 #include "cell.H"
31 #include "bitSet.H"
32 #include "DynamicList.H"
33 #include "ListOps.H"
34 
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
36 
37 void Foam::primitiveMesh::calcPointCells() const
38 {
39  if (debug)
40  {
41  Pout<< "primitiveMesh::calcPointCells() : "
42  << "calculating pointCells"
43  << endl;
44 
45  if (debug == -1)
46  {
47  // For checking calls:abort so we can quickly hunt down
48  // origin of call
50  << abort(FatalError);
51  }
52  }
53 
54  // It is an error to attempt to recalculate pointCells
55  // if the pointer is already set
56  if (pcPtr_)
57  {
59  << "pointCells already calculated"
60  << abort(FatalError);
61  }
62  else if (hasCellPoints())
63  {
64  // Invert cellPoints
65  pcPtr_ = new labelListList(nPoints());
66  invertManyToMany(nPoints(), cellPoints(), *pcPtr_);
67  }
68  else if (hasPointFaces())
69  {
70  // Calculate point-cell from point-face information
71 
72  const labelList& own = faceOwner();
73  const labelList& nei = faceNeighbour();
74  const labelListList& pFaces = pointFaces();
75 
76  // Tracking (only use each cell id once)
77  bitSet usedCells(nCells());
78 
79  // Cell ids for the point currently being processed
80  DynamicList<label> currCells(256);
81 
82  const label loopLen = nPoints();
83 
84  pcPtr_ = new labelListList(nPoints());
85  auto& pointCellAddr = *pcPtr_;
86 
87  for (label pointi = 0; pointi < loopLen; ++pointi)
88  {
89  // Clear any previous contents
90  usedCells.unset(currCells);
91  currCells.clear();
92 
93  for (const label facei : pFaces[pointi])
94  {
95  // Owner cell - only allow one occurance
96  if (usedCells.set(own[facei]))
97  {
98  currCells.push_back(own[facei]);
99  }
100 
101  // Neighbour cell - only allow one occurance
102  if (facei < nInternalFaces())
103  {
104  if (usedCells.set(nei[facei]))
105  {
106  currCells.push_back(nei[facei]);
107  }
108  }
109  }
110 
111  pointCellAddr[pointi] = currCells; // NB: unsorted
112  }
113  }
114  else
115  {
116  // Calculate point-cell topology
117 
118  const cellList& cellLst = cells();
119  const faceList& faceLst = faces();
120 
121  // Tracking (only use each point id once)
122  bitSet usedPoints(nPoints());
123 
124  // Which of usedPoints needs to be unset [faster]
125  DynamicList<label> currPoints(256);
126 
127  const label loopLen = nCells();
128 
129  // Step 1: count number of cells per point
130 
131  labelList pointCount(nPoints(), Zero);
132 
133  for (label celli = 0; celli < loopLen; ++celli)
134  {
135  // Clear any previous contents
136  usedPoints.unset(currPoints);
137  currPoints.clear();
138 
139  for (const label facei : cellLst[celli])
140  {
141  for (const label pointi : faceLst[facei])
142  {
143  // Only once for each point id
144  if (usedPoints.set(pointi))
145  {
146  currPoints.push_back(pointi); // Needed for cleanup
147  ++pointCount[pointi];
148  }
149  }
150  }
151  }
152 
153 
154  // Step 2: set sizing, reset counters
155 
156  pcPtr_ = new labelListList(nPoints());
157  auto& pointCellAddr = *pcPtr_;
158 
159  forAll(pointCellAddr, pointi)
160  {
161  pointCellAddr[pointi].resize_nocopy(pointCount[pointi]);
162  pointCount[pointi] = 0;
163  }
164 
165 
166  // Step 3: fill in values. Logic as per step 1
167  for (label celli = 0; celli < loopLen; ++celli)
168  {
169  // Clear any previous contents
170  usedPoints.unset(currPoints);
171  currPoints.clear();
172 
173  for (const label facei : cellLst[celli])
174  {
175  for (const label pointi : faceLst[facei])
176  {
177  // Only once for each point id
178  if (usedPoints.set(pointi))
179  {
180  currPoints.push_back(pointi); // Needed for cleanup
181  pointCellAddr[pointi][pointCount[pointi]++] = celli;
182  }
183  }
184  }
185  }
186  }
187 }
188 
189 
190 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
191 
193 {
194  if (!pcPtr_)
195  {
196  calcPointCells();
197  }
198 
199  return *pcPtr_;
200 }
201 
202 
204 (
205  const label pointi,
206  DynamicList<label>& storage
207 ) const
208 {
209  if (hasPointCells())
210  {
211  return pointCells()[pointi];
212  }
213  else
214  {
215  const labelList& own = faceOwner();
216  const labelList& nei = faceNeighbour();
217  const labelList& pFaces = pointFaces()[pointi];
218 
219  storage.clear();
220 
221  for (const label facei : pFaces)
222  {
223  // Owner cell
224  storage.push_back(own[facei]);
225 
226  // Neighbour cell
227  if (facei < nInternalFaces())
228  {
229  storage.push_back(nei[facei]);
230  }
231  }
232 
233  // Filter duplicates
234  if (storage.size() > 1)
235  {
236  std::sort(storage.begin(), storage.end());
237  auto last = std::unique(storage.begin(), storage.end());
238  storage.resize(label(last - storage.begin()));
239  }
240 
241  return storage;
242  }
243 }
244 
245 
246 const Foam::labelList& Foam::primitiveMesh::pointCells(const label pointi) const
247 {
248  return pointCells(pointi, labels_);
249 }
250 
251 
252 // ************************************************************************* //
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type unset(const label i)
Unset the bool entry at specified position, always false for out-of-range access. ...
Definition: UList.H:796
List< cell > cellList
List of cell.
Definition: cellListFwd.H:39
label nPoints() const noexcept
Number of mesh points.
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
const cellList & cells() const
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
List< face > faceList
List of faces.
Definition: faceListFwd.H:39
virtual const labelList & faceNeighbour() const =0
Face face-neighbour addressing.
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:296
label nInternalFaces() const noexcept
Number of internal faces.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
const labelListList & pointCells() const
bool hasCellPoints() const noexcept
int debug
Static debugging option.
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
Definition: readKivaGrid.H:235
bool hasPointFaces() const noexcept
label nCells() const noexcept
Number of mesh cells.
virtual const faceList & faces() const =0
Return faces.
const labelListList & pointFaces() const
virtual const labelList & faceOwner() const =0
Face face-owner addressing.
List< label > labelList
A List of labels.
Definition: List.H:62
void invertManyToMany(const label len, const UList< InputIntListType > &input, List< OutputIntListType > &output)
Invert many-to-many.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
const labelListList & cellPoints() const
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127