Loading...
Searching...
No Matches
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-2024 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
37void 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_ = std::make_unique<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();
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_ = std::make_unique<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_ = std::make_unique<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 }
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()));
240
241 return storage;
242 }
243}
244
245
246const Foam::labelList& Foam::primitiveMesh::pointCells(const label pointi) const
247{
248 return pointCells(pointi, labels_);
249}
250
251
252// ************************************************************************* //
Various functions to operate on Lists.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
void push_back(const T &val)
Copy append an element to the end of this list.
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content.
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition UListI.H:454
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
Smooth ATC in cells having a point to a set of patches supplied by type.
Definition pointCells.H:55
bool hasPointCells() const noexcept
virtual const labelList & faceOwner() const =0
Face face-owner addressing.
virtual const labelList & faceNeighbour() const =0
Face face-neighbour addressing.
const labelListList & pointCells() const
virtual const faceList & faces() const =0
Return faces.
label nInternalFaces() const noexcept
Number of internal faces.
bool hasPointFaces() const noexcept
label nPoints() const noexcept
Number of mesh points.
const labelListList & cellPoints() const
label nCells() const noexcept
Number of mesh cells.
const labelListList & pointFaces() const
bool hasCellPoints() const noexcept
const cellList & cells() const
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
void invertManyToMany(const label len, const UList< InputIntListType > &input, List< OutputIntListType > &output)
Invert many-to-many.
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
List< face > faceList
List of faces.
Definition faceListFwd.H:41
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
List< cell > cellList
List of cell.
Definition cellListFwd.H:41
errorManip< error > abort(error &err)
Definition errorManip.H:139
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
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];} pointMap[start]=pointMap[end]=Foam::min(start, end);} } 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};constexpr 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< DynamicList< face > > pFaces[nBCs]
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299