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-2015 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
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 
107 {
108  if (pointEdgesPtr_.valid())
109  {
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 
290 (
291  const scalar mergeDist,
292  labelList& reversePointMap
293 )
294 {
295  pointField newPoints;
296  labelList pointMap;
297 
298  bool hasMerged = Foam::mergePoints
299  (
300  points_,
301  mergeDist,
302  false,
303  pointMap,
304  newPoints,
306  );
307 
308  if (hasMerged)
309  {
310  pointEdgesPtr_.clear();
311 
312  points_.transfer(newPoints);
313 
314  // connectivity changed
315  pointEdgesPtr_.clear();
316 
317  // Renumber and make sure e[0] < e[1] (not really necessary)
318  forAll(edges_, edgeI)
319  {
320  edge& e = edges_[edgeI];
321 
322  label p0 = pointMap[e[0]];
323  label p1 = pointMap[e[1]];
324 
325  if (p0 < p1)
326  {
327  e[0] = p0;
328  e[1] = p1;
329  }
330  else
331  {
332  e[0] = p1;
333  e[1] = p0;
334  }
335  }
336 
337  // Compact using a hashtable and commutative hash of edge.
338  EdgeMap<label> edgeToLabel(2*edges_.size());
339 
340  label newEdgeI = 0;
341 
342  forAll(edges_, edgeI)
343  {
344  const edge& e = edges_[edgeI];
345 
346  if (e[0] != e[1])
347  {
348  if (edgeToLabel.insert(e, newEdgeI))
349  {
350  newEdgeI++;
351  }
352  }
353  }
354 
355  edges_.setSize(newEdgeI);
356 
357  forAllConstIter(EdgeMap<label>, edgeToLabel, iter)
358  {
359  edges_[iter()] = iter.key();
360  }
361  }
362 }
363 
364 
366 {
367  EdgeMap<label> existingEdges(2*edges_.size());
368 
369  label curEdgeI = 0;
370  forAll(edges_, edgeI)
371  {
372  const edge& e = edges_[edgeI];
373 
374  if (existingEdges.insert(e, curEdgeI))
375  {
376  curEdgeI++;
377  }
378  }
379 
380  if (debug)
381  {
382  Info<< "Merging duplicate edges: "
383  << edges_.size() - existingEdges.size()
384  << " edges will be deleted." << endl;
385  }
386 
387  edges_.setSize(existingEdges.size());
388 
389  forAllConstIter(EdgeMap<label>, existingEdges, iter)
390  {
391  edges_[iter()] = iter.key();
392  }
393 
394  // connectivity changed
395  pointEdgesPtr_.clear();
396 }
397 
398 
399 // ************************************************************************* //
Foam::edgeMesh::~edgeMesh
virtual ~edgeMesh()
Destructor.
Definition: edgeMesh.C:163
Foam::edgeMesh::regions
label regions(labelList &edgeRegion) const
Find connected regions. Set region number per edge.
Definition: edgeMesh.C:214
Foam::Vector< scalar >::zero
static const Vector zero
Definition: Vector.H:80
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::edgeMesh::canWriteType
static bool canWriteType(const word &ext, const bool verbose=false)
Can we write this file format type?
Definition: edgeMesh.C:74
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::edgeMesh::canReadType
static bool canReadType(const word &ext, const bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:58
Foam::DynamicList< label >
Foam::notNull
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:46
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
Foam::edgeMesh::scalePoints
virtual void scalePoints(const scalar)
Scale points. A non-positive factor is ignored.
Definition: edgeMesh.C:279
Foam::edgeMesh::edgeMesh
edgeMesh()
Construct null.
Definition: edgeMesh.C:123
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Foam::List::transfer
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Foam::edgeMesh::xfer
Xfer< edgeMesh > xfer()
Transfer contents to the Xfer container.
Definition: edgeMesh.C:208
Foam::edgeMesh::mergePoints
virtual void mergePoints(const scalar mergeDist, labelList &)
Merge common points (points within mergeDist). Return map from.
Definition: edgeMesh.C:290
Foam::HashTable::insert
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::invertManyToMany
void invertManyToMany(const label len, const UList< InList > &, List< OutList > &)
Invert many-to-many.
Definition: ListOpsTemplates.C:418
Foam::HashSet
A HashTable with keys but without contents.
Definition: HashSet.H:59
Foam::Xfer
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
Foam::edgeMesh::canRead
static bool canRead(const fileName &, const bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:90
Foam::label
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
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::edgeMesh::writeTypes
static wordHashSet writeTypes()
Definition: edgeMesh.C:49
edgeMesh.H
Foam::Info
messageStream Info
Foam::edgeMesh::readTypes
static wordHashSet readTypes()
Definition: edgeMesh.C:43
addToMemberFunctionSelectionTable.H
Macros for easy insertion into member function selection tables.
Foam::defineMemberFunctionSelectionTable
defineMemberFunctionSelectionTable(edgeMesh, write, fileExtension)
Foam::FatalError
error FatalError
Foam::HashTable::size
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
Foam::polyMesh::points_
pointIOField points_
Points.
Definition: polyMesh.H:118
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::edgeMesh::mergeEdges
virtual void mergeEdges()
Merge duplicate edges.
Definition: edgeMesh.C:365
Foam::edgeMesh::clear
virtual void clear()
Clear all storage.
Definition: edgeMesh.C:169
Foam::DynamicList::append
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
Foam::EdgeMap< label >
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::edgeMesh::reset
virtual void reset(const Xfer< pointField > &points, const Xfer< edgeList > &edges)
Reset primitive data (points, edges)
Definition: edgeMesh.C:178
Foam::xferMove
Xfer< T > xferMove(T &)
Construct by transferring the contents of the arg.
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
points
const pointField & points
Definition: gmvOutputHeader.H:1
EdgeMap.H
mergePoints.H
Merge points. See below.
Foam::wordHashSet
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:207
ListOps.H
Various functions to operate on Lists.
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::edgeMesh::transfer
void transfer(edgeMesh &)
Transfer the contents of the argument and annul the argument.
Definition: edgeMesh.C:200
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::edgeMesh
Points connected by edges.
Definition: edgeMesh.H:69
Foam::edgeMesh::calcPointEdges
void calcPointEdges() const
Calculate point-edge addressing (inverse of edges)
Definition: edgeMesh.C:106
Foam::mergePoints
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.
Foam::fileFormats::edgeMeshFormatsCore
A collection of helper functions for reading/writing edge formats.
Definition: edgeMeshFormatsCore.H:58
write
Tcoeff write()
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47