edgeMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2018 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  {
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_(nullptr)
129 {}
130 
131 
133 (
134  const pointField& points,
135  const edgeList& edges
136 )
137 :
139  points_(points),
140  edges_(edges),
141  pointEdgesPtr_(nullptr)
142 {}
143 
144 
146 (
147  const Xfer<pointField>& pointLst,
148  const Xfer<edgeList>& edgeLst
149 )
150 :
152  points_(0),
153  edges_(0),
154  pointEdgesPtr_(nullptr)
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  // labelList& edgeMap
294 )
295 {
296  pointField newPoints;
297  labelList pointMap;
298 
299  bool hasMerged = Foam::mergePoints
300  (
301  points_,
302  mergeDist,
303  false,
304  pointMap,
305  newPoints,
307  );
308 
309  if (hasMerged)
310  {
311  pointEdgesPtr_.clear();
312 
313  points_.transfer(newPoints);
314 
315  // connectivity changed
316  pointEdgesPtr_.clear();
317 
318  // Renumber and make sure e[0] < e[1] (not really necessary)
319  forAll(edges_, edgeI)
320  {
321  edge& e = edges_[edgeI];
322 
323  label p0 = pointMap[e[0]];
324  label p1 = pointMap[e[1]];
325 
326  if (p0 < p1)
327  {
328  e[0] = p0;
329  e[1] = p1;
330  }
331  else
332  {
333  e[0] = p1;
334  e[1] = p0;
335  }
336  }
337 
338  // Compact using a hashtable and commutative hash of edge.
339  EdgeMap<label> edgeToLabel(2*edges_.size());
340 
341  label newEdgeI = 0;
342 
343  forAll(edges_, edgeI)
344  {
345  const edge& e = edges_[edgeI];
346 
347  if (e[0] != e[1])
348  {
349  if (edgeToLabel.insert(e, newEdgeI))
350  {
351  newEdgeI++;
352  }
353  }
354  }
355 
356  edges_.setSize(newEdgeI);
357 
358  forAllConstIter(EdgeMap<label>, edgeToLabel, iter)
359  {
360  edges_[iter()] = iter.key();
361  }
362  }
363 }
364 
365 
367 {
368  EdgeMap<label> existingEdges(2*edges_.size());
369 
370  label curEdgeI = 0;
371  forAll(edges_, edgeI)
372  {
373  const edge& e = edges_[edgeI];
374 
375  if (existingEdges.insert(e, curEdgeI))
376  {
377  curEdgeI++;
378  }
379  }
380 
381  if (debug)
382  {
383  Info<< "Merging duplicate edges: "
384  << edges_.size() - existingEdges.size()
385  << " edges will be deleted." << endl;
386  }
387 
388  edges_.setSize(existingEdges.size());
389 
390  forAllConstIter(EdgeMap<label>, existingEdges, iter)
391  {
392  edges_[iter()] = iter.key();
393  }
394 
395  // connectivity changed
396  pointEdgesPtr_.clear();
397 }
398 
399 
400 // ************************************************************************* //
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
void transfer(edgeMesh &)
Transfer the contents of the argument and annul the argument.
Definition: edgeMesh.C:200
A HashTable with keys but without contents.
Definition: HashSet.H:59
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
A class for handling file names.
Definition: fileName.H:69
static bool canReadType(const word &ext, const bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:58
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
virtual void mergePoints(const scalar mergeDist, labelList &)
Merge common points (points within mergeDist). Return map from.
Definition: edgeMesh.C:290
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
virtual void scalePoints(const scalar)
Scale points. A non-positive factor is ignored.
Definition: edgeMesh.C:279
static bool canRead(const fileName &, const bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:90
Xfer< edgeMesh > xfer()
Transfer contents to the Xfer container.
Definition: edgeMesh.C:208
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:283
Macros for easy insertion into run-time selection tables.
edgeMesh()
Construct null.
Definition: edgeMesh.C:123
Various functions to operate on Lists.
static wordHashSet writeTypes()
Definition: edgeMesh.C:49
void write(Ostream &, const label, const dictionary &)
Write with dictionary lookup.
const labelListList & pointEdges() const
Return edges.
Definition: edgeMeshI.H:65
dynamicFvMesh & mesh
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Xfer< T > xferMove(T &)
Construct by transferring the contents of the arg.
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:124
A class for handling words, derived from string.
Definition: word.H:59
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:184
static wordHashSet readTypes()
Definition: edgeMesh.C:43
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:207
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
errorManip< error > abort(error &err)
Definition: errorManip.H:131
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
defineTypeNameAndDebug(combustionModel, 0)
Points connected by edges.
Definition: edgeMesh.H:69
Merge points. See below.
virtual void reset(const Xfer< pointField > &points, const Xfer< edgeList > &edges)
Reset primitive data (points, edges)
Definition: edgeMesh.C:178
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:46
virtual void clear()
Clear all storage.
Definition: edgeMesh.C:169
void setSize(const label)
Reset size of List.
Definition: List.C:281
virtual void mergeEdges()
Merge duplicate edges.
Definition: edgeMesh.C:366
A collection of helper functions for reading/writing edge formats.
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.
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:268
Macros for easy insertion into member function selection tables.
void invertManyToMany(const label len, const UList< InList > &, List< OutList > &)
Invert many-to-many.
messageStream Info
const doubleScalar e
Elementary charge.
Definition: doubleScalar.H:98
label regions(labelList &edgeRegion) const
Find connected regions. Set region number per edge.
Definition: edgeMesh.C:214
defineMemberFunctionSelectionTable(edgeMesh, write, fileExtension)
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
virtual ~edgeMesh()
Destructor.
Definition: edgeMesh.C:163
static bool canWriteType(const word &ext, const bool verbose=false)
Can we write this file format type?
Definition: edgeMesh.C:74
Namespace for OpenFOAM.