1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "primitiveMesh.H"
28 #include "DynamicList.H"
29 #include "demandDrivenData.H"
30 #include "SortableList.H"
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 // Returns edgeI between two points.
36 Foam::label Foam::primitiveMesh::getEdge
38 List<DynamicList<label> >& pe,
39 DynamicList<edge>& es,
42 const label nextPointI
45 // Find connection between pointI and nextPointI
46 forAll(pe[pointI], ppI)
48 label eI = pe[pointI][ppI];
50 const edge& e = es[eI];
52 if (e.start() == nextPointI || e.end() == nextPointI)
59 label edgeI = es.size();
60 pe[pointI].append(edgeI);
61 pe[nextPointI].append(edgeI);
62 if (pointI < nextPointI)
64 es.append(edge(pointI, nextPointI));
68 es.append(edge(nextPointI, pointI));
74 void Foam::primitiveMesh::calcEdges() const
78 Pout<< "primitiveMesh::calcEdges() : "
79 << "calculating edges, pointEdges and faceEdges"
83 // It is an error to attempt to recalculate edges
84 // if the pointer is already set
85 if (edgesPtr_ || fePtr_)
87 FatalErrorIn("primitiveMesh::calcEdges(const bool) const")
88 << "edges or faceEdges already calculated"
93 // Note: replaced with the original and correct algorithm
94 // which preserved correct ordering for edges list
95 // Version 1.5.x, 1.5-dev were wrong, with failures in parallel
96 // point-based data exchange. Fixed in 1.6-ext and
97 // consecutive versions
101 // Go through the pointFace list. Go through the list of faces for that
102 // point and ask for edges. If the edge has got the point in question
103 // AND the second point in the edge is larger than the first, add the
104 // edge to the list. At the same time, add the edge label to the list
105 // of edges for the current face (faceEdges) and log the other face as
106 // the neighbour of this face.
108 const faceList& f = faces();
110 const labelListList& pf = pointFaces();
112 fePtr_ = new labelListList(nFaces());
113 labelListList& fe = *fePtr_;
115 // count the maximum number of edges
118 // create a list of edges for each face and store for efficiency
119 edgeListList edgesOfFace(nFaces());
123 edgesOfFace[faceI] = f[faceI].edges();
125 maxEdges += f[faceI].nEdges();
127 labelList& curFE = fe[faceI];
129 curFE.setSize(f[faceI].nEdges());
131 forAll (curFE, curFEI)
139 edgesPtr_ = new edgeList(maxEdges);
140 edgeList& e = *edgesPtr_;
145 const labelList& curFaces = pf[pointI];
147 // create a list of labels to keep the neighbours that
148 // have already been added
149 DynamicList<label, edgesPerPoint_> addedNeighbours;
150 DynamicList<DynamicList<label, edgesPerPoint_> >
152 DynamicList<DynamicList<label, edgesPerPoint_> >
153 edgeOfFaceGivingNeighbour;
155 forAll (curFaces, faceI)
158 const edgeList& fEdges = edgesOfFace[curFaces[faceI]];
161 forAll(fEdges, edgeI)
163 const edge& ends = fEdges[edgeI];
165 // does the edge has got the point in question
167 label secondPoint = -1;
169 if (ends.start() == pointI)
172 secondPoint = ends.end();
175 if (ends.end() == pointI)
178 secondPoint = ends.start();
181 // if the edge has got the point and second label is larger
182 // than first, it is a candidate for adding
183 if (found && (secondPoint > pointI))
185 // check if the edge has already been added
188 forAll (addedNeighbours, eopI)
190 if (secondPoint == addedNeighbours[eopI])
192 // Edge is already added. New face sharing it
195 // Remember the face and edge giving neighbour
196 faceGivingNeighbour[eopI].append
199 edgeOfFaceGivingNeighbour[eopI].append(edgeI);
205 // If not added, add the edge to the list
208 addedNeighbours.append(secondPoint);
210 // Remember the face and subShape giving neighbour
211 faceGivingNeighbour(addedNeighbours.size() - 1)
212 .append(curFaces[faceI]);
213 edgeOfFaceGivingNeighbour
214 (addedNeighbours.size() - 1).append(edgeI);
220 // All edges for the current point found. Before adding them to the
221 // list, it is necessary to sort them in the increasing order of the
222 // neighbouring point.
224 // Make real list out of SLList to simplify the manipulation.
225 // Also, make another list to "remember" how the original list was
227 labelList shuffleList(addedNeighbours.size());
229 forAll (shuffleList, i)
234 // Use a simple sort to sort the addedNeighbours list.
235 // Other two lists mimic the same behaviour
238 for (j = 1; j <= addedNeighbours.size() - 1; j++)
240 a = addedNeighbours[j];
245 while (i >= 0 && addedNeighbours[i] > a)
247 addedNeighbours[i + 1] = addedNeighbours[i];
248 shuffleList[i + 1] = shuffleList[i];
252 addedNeighbours[i + 1] = a;
253 shuffleList[i + 1] = b;
256 labelList reshuffleList(shuffleList.size());
258 forAll(shuffleList, i)
260 reshuffleList[shuffleList[i]] = i;
263 // Reshuffle other lists
265 labelListList fgn(faceGivingNeighbour.size());
267 forAll (faceGivingNeighbour, i)
269 fgn[reshuffleList[i]].transfer(faceGivingNeighbour[i].shrink());
272 labelListList eofgn(edgeOfFaceGivingNeighbour.size());
274 forAll (edgeOfFaceGivingNeighbour, i)
276 eofgn[reshuffleList[i]].transfer
278 edgeOfFaceGivingNeighbour[i].shrink()
283 forAll(addedNeighbours, edgeI)
285 const labelList& curFgn = fgn[edgeI];
286 const labelList& curEofgn = eofgn[edgeI];
288 forAll (curFgn, fgnI)
290 fe[curFgn[fgnI]][curEofgn[fgnI]] = nEdges;
293 e[nEdges] = edge(pointI, addedNeighbours[edgeI]);
303 // Removed ordered edges: reverting to correct parallelisation
304 // of edge data. HJ, 17/Au/2010
305 // void primitiveMesh::calcOrderedEdges() const
308 Foam::label Foam::primitiveMesh::findFirstCommonElementFromSortedLists
310 const labelList& list1,
311 const labelList& list2
316 labelList::const_iterator iter1 = list1.begin();
317 labelList::const_iterator iter2 = list2.begin();
319 while (iter1 != list1.end() && iter2 != list2.end())
325 else if (*iter1 > *iter2)
339 "primitiveMesh::findFirstCommonElementFromSortedLists"
340 "(const labelList&, const labelList&)"
341 ) << "No common elements in lists " << list1 << " and " << list2
342 << abort(FatalError);
348 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
350 const Foam::edgeList& Foam::primitiveMesh::edges() const
354 // 1.6.x merge: reverting to correct code
363 const Foam::labelListList& Foam::primitiveMesh::faceEdges() const
367 // 1.6.x merge: reverting to correct code
376 void Foam::primitiveMesh::clearOutEdges()
378 deleteDemandDrivenData(edgesPtr_);
379 deleteDemandDrivenData(fePtr_);
385 const Foam::labelList& Foam::primitiveMesh::faceEdges
388 DynamicList<label>& storage
393 return faceEdges()[faceI];
397 const labelListList& pointEs = pointEdges();
398 const face& f = faces()[faceI];
401 if (f.size() > storage.capacity())
403 storage.setCapacity(f.size());
410 findFirstCommonElementFromSortedLists
413 pointEs[f.nextLabel(fp)]
423 const Foam::labelList& Foam::primitiveMesh::faceEdges(const label faceI) const
425 return faceEdges(faceI, labels_);
429 const Foam::labelList& Foam::primitiveMesh::cellEdges
432 DynamicList<label>& storage
437 return cellEdges()[cellI];
441 const labelList& cFaces = cells()[cellI];
447 const labelList& fe = faceEdges(cFaces[i]);
451 labelSet_.insert(fe[feI]);
457 if (labelSet_.size() > storage.capacity())
459 storage.setCapacity(labelSet_.size());
462 forAllConstIter(labelHashSet, labelSet_, iter)
464 storage.append(iter.key());
472 const Foam::labelList& Foam::primitiveMesh::cellEdges(const label cellI) const
474 return cellEdges(cellI, labels_);
478 // ************************************************************************* //