edgeMesh.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 | Copyright (C) 2011-2014 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "edgeMesh.H"
27 #include "mergePoints.H"
30 #include "ListOps.H"
31 #include "EdgeMap.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(edgeMesh, 0);
38  defineRunTimeSelectionTable(edgeMesh, fileExtension);
39  defineMemberFunctionSelectionTable(edgeMesh,write,fileExtension);
40 }
41 
42 
44 {
45  return wordHashSet(*fileExtensionConstructorTablePtr_);
46 }
47 
48 
50 {
51  return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
52 }
53 
54 
55 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
56 
58 (
59  const word& ext,
60  const bool verbose
61 )
62 {
63  return checkSupport
64  (
65  readTypes(),
66  ext,
67  verbose,
68  "reading"
69  );
70 }
71 
72 
74 (
75  const word& ext,
76  const bool verbose
77 )
78 {
79  return checkSupport
80  (
81  writeTypes(),
82  ext,
83  verbose,
84  "writing"
85  );
86 }
87 
88 
90 (
91  const fileName& name,
92  const bool verbose
93 )
94 {
95  word ext = name.ext();
96  if (ext == "gz")
97  {
98  ext = name.lessExt().ext();
99  }
100  return canReadType(ext, verbose);
101 }
102 
103 
104 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
105 
106 void Foam::edgeMesh::calcPointEdges() const
107 {
108  if (pointEdgesPtr_.valid())
109  {
110  FatalErrorIn("edgeMesh::calcPointEdges() const")
111  << "pointEdges already calculated." << abort(FatalError);
112  }
113 
114  pointEdgesPtr_.reset(new labelListList(points_.size()));
115  labelListList& pointEdges = pointEdgesPtr_();
116 
117  invertManyToMany(pointEdges.size(), edges_, pointEdges);
118 }
119 
120 
121 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
122 
124 :
125  fileFormats::edgeMeshFormatsCore(),
126  points_(0),
127  edges_(0),
128  pointEdgesPtr_(NULL)
129 {}
130 
131 
133 (
134  const pointField& points,
135  const edgeList& edges
136 )
137 :
139  points_(points),
140  edges_(edges),
141  pointEdgesPtr_(NULL)
142 {}
143 
144 
146 (
147  const Xfer<pointField>& pointLst,
148  const Xfer<edgeList>& edgeLst
149 )
150 :
152  points_(0),
153  edges_(0),
154  pointEdgesPtr_(NULL)
155 {
156  points_.transfer(pointLst());
157  edges_.transfer(edgeLst());
158 }
159 
160 
161 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
162 
164 {}
165 
166 
167 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
168 
170 {
171  points_.clear();
172  edges_.clear();
173  pointEdgesPtr_.clear();
174 }
175 
176 
178 (
179  const Xfer<pointField>& pointLst,
180  const Xfer<edgeList>& edgeLst
181 )
182 {
183  // Take over new primitive data.
184  // Optimized to avoid overwriting data at all
185  if (notNull(pointLst))
186  {
187  points_.transfer(pointLst());
188  }
189 
190  if (notNull(edgeLst))
191  {
192  edges_.transfer(edgeLst());
193 
194  // connectivity likely changed
195  pointEdgesPtr_.clear();
196  }
197 }
198 
199 
201 {
202  points_.transfer(mesh.points_);
203  edges_.transfer(mesh.edges_);
204  pointEdgesPtr_ = mesh.pointEdgesPtr_;
205 }
206 
207 
209 {
210  return xferMove(*this);
211 }
212 
213 
215 {
216  edgeRegion.setSize(edges_.size());
217  edgeRegion = -1;
218 
219  label startEdgeI = 0;
220  label currentRegion = 0;
221 
222  while (true)
223  {
224  while (startEdgeI < edges_.size() && edgeRegion[startEdgeI] != -1)
225  {
226  startEdgeI++;
227  }
228 
229  if (startEdgeI == edges_.size())
230  {
231  break;
232  }
233 
234  // Found edge that has not yet been assigned a region.
235  // Mark connected region with currentRegion starting at startEdgeI.
236 
237  edgeRegion[startEdgeI] = currentRegion;
238  labelList edgesToVisit(1, startEdgeI);
239 
240  while (edgesToVisit.size())
241  {
242  // neighbours of current edgesToVisit
243  DynamicList<label> newEdgesToVisit(edgesToVisit.size());
244 
245  // Mark all point connected edges with current region.
246  forAll(edgesToVisit, i)
247  {
248  label edgeI = edgesToVisit[i];
249 
250  // Mark connected edges
251  const edge& e = edges_[edgeI];
252 
253  forAll(e, fp)
254  {
255  const labelList& pEdges = pointEdges()[e[fp]];
256 
257  forAll(pEdges, pEdgeI)
258  {
259  label nbrEdgeI = pEdges[pEdgeI];
260 
261  if (edgeRegion[nbrEdgeI] == -1)
262  {
263  edgeRegion[nbrEdgeI] = currentRegion;
264  newEdgesToVisit.append(nbrEdgeI);
265  }
266  }
267  }
268  }
269 
270  edgesToVisit.transfer(newEdgesToVisit);
271  }
272 
273  currentRegion++;
274  }
275  return currentRegion;
276 }
277 
278 
279 void Foam::edgeMesh::scalePoints(const scalar scaleFactor)
280 {
281  // avoid bad scaling
282  if (scaleFactor > 0 && scaleFactor != 1.0)
283  {
284  points_ *= scaleFactor;
285  }
286 }
287 
288 
289 void Foam::edgeMesh::mergePoints(const scalar mergeDist)
290 {
291  pointField newPoints;
292  labelList pointMap;
293 
294  bool hasMerged = Foam::mergePoints
295  (
296  points_,
297  mergeDist,
298  false,
299  pointMap,
300  newPoints,
302  );
303 
304  if (hasMerged)
305  {
306  pointEdgesPtr_.clear();
307 
308  points_.transfer(newPoints);
309 
310  // Renumber and make sure e[0] < e[1] (not really necessary)
311  forAll(edges_, edgeI)
312  {
313  edge& e = edges_[edgeI];
314 
315  label p0 = pointMap[e[0]];
316  label p1 = pointMap[e[1]];
317 
318  if (p0 < p1)
319  {
320  e[0] = p0;
321  e[1] = p1;
322  }
323  else
324  {
325  e[0] = p1;
326  e[1] = p0;
327  }
328  }
329 
330  // Compact using a hashtable and commutative hash of edge.
331  EdgeMap<label> edgeToLabel(2*edges_.size());
332 
333  label newEdgeI = 0;
334 
335  forAll(edges_, edgeI)
336  {
337  const edge& e = edges_[edgeI];
338 
339  if (e[0] != e[1])
340  {
341  if (edgeToLabel.insert(e, newEdgeI))
342  {
343  newEdgeI++;
344  }
345  }
346  }
347 
348  edges_.setSize(newEdgeI);
349 
350  forAllConstIter(EdgeMap<label>, edgeToLabel, iter)
351  {
352  edges_[iter()] = iter.key();
353  }
354  }
355 }
356 
357 
359 {
360  EdgeMap<label> existingEdges(2*edges_.size());
361 
362  label curEdgeI = 0;
363  forAll(edges_, edgeI)
364  {
365  const edge& e = edges_[edgeI];
366 
367  if (existingEdges.insert(e, curEdgeI))
368  {
369  curEdgeI++;
370  }
371  }
372 
373  if (debug)
374  {
375  Info<< "Merging duplicate edges: "
376  << edges_.size() - existingEdges.size()
377  << " edges will be deleted." << endl;
378  }
379 
380  edges_.setSize(existingEdges.size());
381 
382  forAllConstIter(EdgeMap<label>, existingEdges, iter)
383  {
384  edges_[iter()] = iter.key();
385  }
386 }
387 
388 
389 // ************************************************************************* //
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:323
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:207
void invertManyToMany(const label len, const UList< InList > &, List< OutList > &)
Invert many-to-many.
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:390
Merge points. See below.
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
A class for handling words, derived from string.
Definition: word.H:59
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
void mergePoints(const scalar mergeDist)
Merge common points (points within mergeDist)
Definition: edgeMesh.C:289
void mergeEdges()
Merge similar edges.
Definition: edgeMesh.C:358
Various functions to operate on Lists.
Xfer< edgeMesh > xfer()
Transfer contents to the Xfer container.
Definition: edgeMesh.C:208
virtual ~edgeMesh()
Destructor.
Definition: edgeMesh.C:163
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:46
messageStream Info
dynamicFvMesh & mesh
Xfer< T > xferMove(T &)
edgeMesh()
Construct null.
Definition: edgeMesh.C:123
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Namespace for OpenFOAM.
runTime write()
defineMemberFunctionSelectionTable(edgeMesh, write, fileExtension)
label regions(labelList &edgeRegion) const
Find connected regions. Set region number per edge.
Definition: edgeMesh.C:214
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
virtual void clear()
Clear all storage.
Definition: edgeMesh.C:169
void clear()
Clear the list, i.e. set size to zero.
Definition: List.C:379
const double e
Elementary charge.
Definition: doubleFloat.H:78
void setSize(const label)
Reset size of List.
Definition: List.C:318
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
#define forAll(list, i)
Definition: UList.H:421
Macros for easy insertion into run-time selection tables.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
label mergePoints(const UList< Type > &points, const scalar mergeTol, const bool verbose, labelList &pointMap, const Type &origin=Type::zero)
Sorts and merges points. All points closer than/equal mergeTol get merged.
A collection of helper functions for reading/writing edge formats.
static wordHashSet writeTypes()
Definition: edgeMesh.C:49
Points connected by edges.
Definition: edgeMesh.H:69
error FatalError
A class for handling file names.
Definition: fileName.H:69
static const Vector zero
Definition: Vector.H:80
A HashTable with keys but without contents.
Definition: HashSet.H:59
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:307
static bool canReadType(const word &ext, const bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:58
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
static wordHashSet readTypes()
Definition: edgeMesh.C:43
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:97
Macros for easy insertion into member function selection tables.
static bool canRead(const fileName &, const bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:90
const labelListList & pointEdges() const
Return edges.
Definition: edgeMeshI.H:51
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
static bool canWriteType(const word &ext, const bool verbose=false)
Can we write this file format type?
Definition: edgeMesh.C:74
void transfer(edgeMesh &)
Transfer the contents of the argument and annul the argument.
Definition: edgeMesh.C:200
virtual void scalePoints(const scalar)
Scale points. A non-positive factor is ignored.
Definition: edgeMesh.C:279
virtual void reset(const Xfer< pointField > &points, const Xfer< edgeList > &edges)
Reset primitive data (points, edges)
Definition: edgeMesh.C:178
defineTypeNameAndDebug(combustionModel, 0)