Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / edgeMesh / edgeMesh.C
blob04f3d15da62c6a6f2b041bb754430972b8e72363
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2010 OpenCFD Ltd.
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     points_(0),
152     edges_(0),
153     pointEdgesPtr_(NULL)
157 Foam::edgeMesh::edgeMesh
159     const pointField& points,
160     const edgeList& edges
163     points_(points),
164     edges_(edges),
165     pointEdgesPtr_(NULL)
169 Foam::edgeMesh::edgeMesh
171     const Xfer<pointField>& pointLst,
172     const Xfer<edgeList>& edgeLst
175     points_(0),
176     edges_(0),
177     pointEdgesPtr_(NULL)
179     points_.transfer(pointLst());
180     edges_.transfer(edgeLst());
184 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
186 Foam::edgeMesh::~edgeMesh()
190 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
192 void Foam::edgeMesh::clear()
194     points_.clear();
195     edges_.clear();
196     pointEdgesPtr_.clear();
200 void Foam::edgeMesh::reset
202     const Xfer<pointField>& pointLst,
203     const Xfer<edgeList>& edgeLst
206     // Take over new primitive data.
207     // Optimized to avoid overwriting data at all
208     if (&pointLst)
209     {
210         points_.transfer(pointLst());
211     }
213     if (&edgeLst)
214     {
215         edges_.transfer(edgeLst());
217         // connectivity likely changed
218         pointEdgesPtr_.clear();
219     }
223 void Foam::edgeMesh::transfer(edgeMesh& mesh)
225     points_.transfer(mesh.points_);
226     edges_.transfer(mesh.edges_);
227     pointEdgesPtr_ = mesh.pointEdgesPtr_;
231 Foam::Xfer<Foam::edgeMesh> Foam::edgeMesh::xfer()
233     return xferMove(*this);
237 Foam::label Foam::edgeMesh::regions(labelList& edgeRegion) const
239     edgeRegion.setSize(edges_.size());
240     edgeRegion = -1;
242     label startEdgeI = 0;
243     label currentRegion = 0;
245     while (true)
246     {
247         while (startEdgeI < edges_.size() && edgeRegion[startEdgeI] != -1)
248         {
249             startEdgeI++;
250         }
252         if (startEdgeI == edges_.size())
253         {
254             break;
255         }
257         // Found edge that has not yet been assigned a region.
258         // Mark connected region with currentRegion starting at startEdgeI.
260         edgeRegion[startEdgeI] = currentRegion;
261         labelList edgesToVisit(1, startEdgeI);
263         while (edgesToVisit.size())
264         {
265             // neighbours of current edgesToVisit
266             DynamicList<label> newEdgesToVisit(edgesToVisit.size());
268             // Mark all point connected edges with current region.
269             forAll(edgesToVisit, i)
270             {
271                 label edgeI = edgesToVisit[i];
273                 // Mark connected edges
274                 const edge& e = edges_[edgeI];
276                 forAll(e, fp)
277                 {
278                     const labelList& pEdges = pointEdges()[e[fp]];
280                     forAll(pEdges, pEdgeI)
281                     {
282                         label nbrEdgeI = pEdges[pEdgeI];
284                         if (edgeRegion[nbrEdgeI] == -1)
285                         {
286                             edgeRegion[nbrEdgeI] = currentRegion;
287                             newEdgesToVisit.append(nbrEdgeI);
288                         }
289                     }
290                 }
291             }
293             edgesToVisit.transfer(newEdgesToVisit);
294         }
296         currentRegion++;
297     }
298     return currentRegion;
302 void Foam::edgeMesh::scalePoints(const scalar scaleFactor)
304     // avoid bad scaling
305     if (scaleFactor > 0 && scaleFactor != 1.0)
306     {
307         points_ *= scaleFactor;
308     }
312 void Foam::edgeMesh::mergePoints(const scalar mergeDist)
314     pointField newPoints;
315     labelList pointMap;
317     bool hasMerged = Foam::mergePoints
318     (
319         points_,
320         mergeDist,
321         false,
322         pointMap,
323         newPoints,
324         vector::zero
325     );
327     if (hasMerged)
328     {
329         pointEdgesPtr_.clear();
331         points_.transfer(newPoints);
333         // Renumber and make sure e[0] < e[1] (not really necessary)
334         forAll(edges_, edgeI)
335         {
336             edge& e = edges_[edgeI];
338             label p0 = pointMap[e[0]];
339             label p1 = pointMap[e[1]];
341             if (p0 < p1)
342             {
343                 e[0] = p0;
344                 e[1] = p1;
345             }
346             else
347             {
348                 e[0] = p1;
349                 e[1] = p0;
350             }
351         }
353         // Compact using a hashtable and commutative hash of edge.
354         HashTable<label, edge, Hash<edge> > edgeToLabel
355         (
356             2*edges_.size()
357         );
359         label newEdgeI = 0;
361         forAll(edges_, edgeI)
362         {
363             const edge& e = edges_[edgeI];
365             if (e[0] != e[1])
366             {
367                 if (edgeToLabel.insert(e, newEdgeI))
368                 {
369                     newEdgeI++;
370                 }
371             }
372         }
374         edges_.setSize(newEdgeI);
376         for
377         (
378             HashTable<label, edge, Hash<edge> >::const_iterator iter =
379                 edgeToLabel.begin();
380             iter != edgeToLabel.end();
381             ++iter
382         )
383         {
384             edges_[iter()] = iter.key();
385         }
386     }
390 // ************************************************************************* //