ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / edgeMesh / edgeMesh.C
blob4e5d50ed45d50b77a9e46eb2e3392acc925ca0b7
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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
19     for more details.
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "edgeMesh.H"
27 #include "mergePoints.H"
28 #include "addToRunTimeSelectionTable.H"
29 #include "addToMemberFunctionSelectionTable.H"
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 namespace Foam
35     defineTypeNameAndDebug(edgeMesh, 0);
36     defineRunTimeSelectionTable(edgeMesh, fileExtension);
37     defineMemberFunctionSelectionTable(edgeMesh,write,fileExtension);
41 Foam::wordHashSet Foam::edgeMesh::readTypes()
43     return wordHashSet(*fileExtensionConstructorTablePtr_);
47 Foam::wordHashSet Foam::edgeMesh::writeTypes()
49     return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
53 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
55 bool Foam::edgeMesh::canReadType
57     const word& ext,
58     const bool verbose
61     return checkSupport
62     (
63         readTypes(),
64         ext,
65         verbose,
66         "reading"
67    );
71 bool Foam::edgeMesh::canWriteType
73     const word& ext,
74     const bool verbose
77     return checkSupport
78     (
79         writeTypes(),
80         ext,
81         verbose,
82         "writing"
83     );
87 bool Foam::edgeMesh::canRead
89     const fileName& name,
90     const bool verbose
93     word ext = name.ext();
94     if (ext == "gz")
95     {
96         ext = name.lessExt().ext();
97     }
98     return canReadType(ext, verbose);
102 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
104 void Foam::edgeMesh::calcPointEdges() const
106     if (pointEdgesPtr_.valid())
107     {
108         FatalErrorIn("edgeMesh::calcPointEdges() const")
109             << "pointEdges already calculated." << abort(FatalError);
110     }
112     pointEdgesPtr_.reset(new labelListList(points_.size()));
113     labelListList& pointEdges = pointEdgesPtr_();
115     // Count
116     labelList nEdgesPerPoint(points_.size(), 0);
118     forAll(edges_, edgeI)
119     {
120         const edge& e = edges_[edgeI];
122         nEdgesPerPoint[e[0]]++;
123         nEdgesPerPoint[e[1]]++;
124     }
126     // Size
127     forAll(pointEdges, pointI)
128     {
129         pointEdges[pointI].setSize(nEdgesPerPoint[pointI]);
130     }
132     // Fill
133     nEdgesPerPoint = 0;
135     forAll(edges_, edgeI)
136     {
137         const edge& e = edges_[edgeI];
138         const label p0 = e[0];
139         const label p1 = e[1];
141         pointEdges[p0][nEdgesPerPoint[p0]++] = edgeI;
142         pointEdges[p1][nEdgesPerPoint[p1]++] = edgeI;
143     }
147 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
149 Foam::edgeMesh::edgeMesh()
151     fileFormats::edgeFormatsCore(),
152     points_(0),
153     edges_(0),
154     pointEdgesPtr_(NULL)
158 Foam::edgeMesh::edgeMesh
160     const pointField& points,
161     const edgeList& edges
164     fileFormats::edgeFormatsCore(),
165     points_(points),
166     edges_(edges),
167     pointEdgesPtr_(NULL)
171 Foam::edgeMesh::edgeMesh
173     const Xfer<pointField>& pointLst,
174     const Xfer<edgeList>& edgeLst
177     fileFormats::edgeFormatsCore(),
178     points_(0),
179     edges_(0),
180     pointEdgesPtr_(NULL)
182     points_.transfer(pointLst());
183     edges_.transfer(edgeLst());
187 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
189 Foam::edgeMesh::~edgeMesh()
193 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
195 void Foam::edgeMesh::clear()
197     points_.clear();
198     edges_.clear();
199     pointEdgesPtr_.clear();
203 void Foam::edgeMesh::reset
205     const Xfer<pointField>& pointLst,
206     const Xfer<edgeList>& edgeLst
209     // Take over new primitive data.
210     // Optimized to avoid overwriting data at all
211     if (&pointLst)
212     {
213         points_.transfer(pointLst());
214     }
216     if (&edgeLst)
217     {
218         edges_.transfer(edgeLst());
220         // connectivity likely changed
221         pointEdgesPtr_.clear();
222     }
226 void Foam::edgeMesh::transfer(edgeMesh& mesh)
228     points_.transfer(mesh.points_);
229     edges_.transfer(mesh.edges_);
230     pointEdgesPtr_ = mesh.pointEdgesPtr_;
234 Foam::Xfer<Foam::edgeMesh> Foam::edgeMesh::xfer()
236     return xferMove(*this);
240 Foam::label Foam::edgeMesh::regions(labelList& edgeRegion) const
242     edgeRegion.setSize(edges_.size());
243     edgeRegion = -1;
245     label startEdgeI = 0;
246     label currentRegion = 0;
248     while (true)
249     {
250         while (startEdgeI < edges_.size() && edgeRegion[startEdgeI] != -1)
251         {
252             startEdgeI++;
253         }
255         if (startEdgeI == edges_.size())
256         {
257             break;
258         }
260         // Found edge that has not yet been assigned a region.
261         // Mark connected region with currentRegion starting at startEdgeI.
263         edgeRegion[startEdgeI] = currentRegion;
264         labelList edgesToVisit(1, startEdgeI);
266         while (edgesToVisit.size())
267         {
268             // neighbours of current edgesToVisit
269             DynamicList<label> newEdgesToVisit(edgesToVisit.size());
271             // Mark all point connected edges with current region.
272             forAll(edgesToVisit, i)
273             {
274                 label edgeI = edgesToVisit[i];
276                 // Mark connected edges
277                 const edge& e = edges_[edgeI];
279                 forAll(e, fp)
280                 {
281                     const labelList& pEdges = pointEdges()[e[fp]];
283                     forAll(pEdges, pEdgeI)
284                     {
285                         label nbrEdgeI = pEdges[pEdgeI];
287                         if (edgeRegion[nbrEdgeI] == -1)
288                         {
289                             edgeRegion[nbrEdgeI] = currentRegion;
290                             newEdgesToVisit.append(nbrEdgeI);
291                         }
292                     }
293                 }
294             }
296             edgesToVisit.transfer(newEdgesToVisit);
297         }
299         currentRegion++;
300     }
301     return currentRegion;
305 void Foam::edgeMesh::scalePoints(const scalar scaleFactor)
307     // avoid bad scaling
308     if (scaleFactor > 0 && scaleFactor != 1.0)
309     {
310         points_ *= scaleFactor;
311     }
315 void Foam::edgeMesh::mergePoints(const scalar mergeDist)
317     pointField newPoints;
318     labelList pointMap;
320     bool hasMerged = Foam::mergePoints
321     (
322         points_,
323         mergeDist,
324         false,
325         pointMap,
326         newPoints,
327         vector::zero
328     );
330     if (hasMerged)
331     {
332         pointEdgesPtr_.clear();
334         points_.transfer(newPoints);
336         // Renumber and make sure e[0] < e[1] (not really necessary)
337         forAll(edges_, edgeI)
338         {
339             edge& e = edges_[edgeI];
341             label p0 = pointMap[e[0]];
342             label p1 = pointMap[e[1]];
344             if (p0 < p1)
345             {
346                 e[0] = p0;
347                 e[1] = p1;
348             }
349             else
350             {
351                 e[0] = p1;
352                 e[1] = p0;
353             }
354         }
356         // Compact using a hashtable and commutative hash of edge.
357         HashTable<label, edge, Hash<edge> > edgeToLabel
358         (
359             2*edges_.size()
360         );
362         label newEdgeI = 0;
364         forAll(edges_, edgeI)
365         {
366             const edge& e = edges_[edgeI];
368             if (e[0] != e[1])
369             {
370                 if (edgeToLabel.insert(e, newEdgeI))
371                 {
372                     newEdgeI++;
373                 }
374             }
375         }
377         edges_.setSize(newEdgeI);
379         for
380         (
381             HashTable<label, edge, Hash<edge> >::const_iterator iter =
382                 edgeToLabel.begin();
383             iter != edgeToLabel.end();
384             ++iter
385         )
386         {
387             edges_[iter()] = iter.key();
388         }
389     }
393 // ************************************************************************* //