adding scalarIOList
[OpenFOAM-1.5.x.git] / src / edgeMesh / edgeMesh.C
blob27cb417b3ed4be7e3bbbef4df2dc27b519edf3b7
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 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 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
19     for more details.
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 "edgeMesh.H"
28 #include "mergePoints.H"
29 #include "StaticHashTable.H"
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 namespace Foam
36 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
38 void edgeMesh::calcPointEdges() const
40     if (pointEdgesPtr_.valid())
41     {
42         FatalErrorIn("edgeMesh::calcPointEdges() const")
43             << "pointEdges already calculated." << abort(FatalError);
44     }
46     pointEdgesPtr_.reset(new labelListList(points_.size()));
47     labelListList& pointEdges = pointEdgesPtr_();
49     // Count
50     labelList nEdgesPerPoint(points_.size(), 0);
52     forAll(edges_, edgeI)
53     {
54         const edge& e = edges_[edgeI];
56         nEdgesPerPoint[e[0]]++;
57         nEdgesPerPoint[e[1]]++;
58     }
60     // Size
61     forAll(pointEdges, pointI)
62     {
63         pointEdges[pointI].setSize(nEdgesPerPoint[pointI]);
64     }
66     // Fill
67     nEdgesPerPoint = 0;
69     forAll(edges_, edgeI)
70     {
71         const edge& e = edges_[edgeI];
73         label p0 = e[0];
74         pointEdges[p0][nEdgesPerPoint[p0]++] = edgeI;
75         label p1 = e[1];
76         pointEdges[p1][nEdgesPerPoint[p1]++] = edgeI;
77     }
81 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
83 // construct from components
84 edgeMesh::edgeMesh(const pointField& points, const edgeList& edges)
86     points_(points),
87     edges_(edges)
91 // construct as copy
92 edgeMesh::edgeMesh(const edgeMesh& em)
94     points_(em.points_),
95     edges_(em.edges_),
96     pointEdgesPtr_(NULL)
100 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
102 label edgeMesh::regions(labelList& edgeRegion) const
104     edgeRegion.setSize(edges_.size());
105     edgeRegion = -1;
107     label startEdgeI = 0;
109     label currentRegion = 0;
111     while (true)
112     {
113         while (startEdgeI < edges_.size() && edgeRegion[startEdgeI] != -1)
114         {
115             startEdgeI++;
116         }
118         if (startEdgeI == edges_.size())
119         {
120             break;
121         }
123         // Found edge that has not yet been assigned a region.
124         // Mark connected region with currentRegion starting at startEdgeI.
126         edgeRegion[startEdgeI] = currentRegion;
127         labelList edgesToVisit(1, startEdgeI);
129         while (edgesToVisit.size() > 0)
130         {
131             // neighbours of current edgesToVisit
132             DynamicList<label> newEdgesToVisit(edgesToVisit.size());
134             // Mark all point connected edges with current region.
135             forAll(edgesToVisit, i)
136             {
137                 label edgeI = edgesToVisit[i];
139                 // Mark connected edges
140                 const edge& e = edges_[edgeI];
142                 forAll(e, fp)
143                 {
144                     const labelList& pEdges = pointEdges()[e[fp]];
146                     forAll(pEdges, pEdgeI)
147                     {
148                         label nbrEdgeI = pEdges[pEdgeI];
150                         if (edgeRegion[nbrEdgeI] == -1)
151                         {
152                             edgeRegion[nbrEdgeI] = currentRegion;
153                             newEdgesToVisit.append(nbrEdgeI);
154                         }
155                     }
156                 }
157             }
159             edgesToVisit.transfer(newEdgesToVisit.shrink());
160         }
162         currentRegion++;
163     }
164     return currentRegion;
168 void edgeMesh::mergePoints(const scalar mergeDist)
170     pointField newPoints;
171     labelList pointMap;
173     bool hasMerged = Foam::mergePoints
174     (
175         points_,
176         mergeDist,
177         false,
178         pointMap,
179         newPoints,
180         vector::zero
181     );
183     if (hasMerged)
184     {
185         pointEdgesPtr_.clear();
187         points_.transfer(newPoints);
189         // Renumber and make sure e[0] < e[1] (not really nessecary)
190         forAll(edges_, edgeI)
191         {
192             edge& e = edges_[edgeI];
194             label p0 = pointMap[e[0]];
195             label p1 = pointMap[e[1]];
197             if (p0 < p1)
198             {
199                 e[0] = p0;
200                 e[1] = p1;
201             }
202             else
203             {
204                 e[0] = p1;
205                 e[1] = p0;
206             }
207         }
209         // Compact using a hashtable and commutative hash of edge.
210         StaticHashTable<label, edge, Hash<edge> > edgeToLabel
211         (
212             2*edges_.size()
213         );
215         label newEdgeI = 0;
217         forAll(edges_, edgeI)
218         {
219             const edge& e = edges_[edgeI];
221             if (e[0] != e[1])
222             {
223                 if (edgeToLabel.insert(e, newEdgeI))
224                 {
225                     newEdgeI++;
226                 }
227             }
228         }
230         edges_.setSize(newEdgeI);
232         for
233         (
234             StaticHashTable<label, edge, Hash<edge> >::const_iterator iter =
235                 edgeToLabel.begin();
236             iter != edgeToLabel.end();
237             ++iter
238         )
239         {
240             edges_[iter()] = iter.key();
241         }
242     }
246 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
248 void edgeMesh::operator=(const edgeMesh& rhs)
250     points_ = rhs.points_;
251     edges_ = rhs.edges_;
252     pointEdgesPtr_.reset(NULL);
256 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
258 } // End namespace Foam
260 // ************************************************************************* //