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-2021 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  pointField&& pointLst,
148  edgeList&& edgeLst
149 )
150 :
152  points_(move(pointLst)),
153  edges_(move(edgeLst)),
154  pointEdgesPtr_(nullptr)
155 {}
156 
157 
158 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
159 
161 {}
162 
163 
164 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
165 
167 {
168  points_.clear();
169  edges_.clear();
170  pointEdgesPtr_.clear();
171 }
172 
173 
175 (
176  pointField&& pointLst,
177  edgeList&& edgeLst
178 )
179 {
180  // Take over new primitive data.
181  // Optimised to avoid overwriting data at all
182  if (notNull(pointLst))
183  {
184  points_.transfer(pointLst);
185  }
186 
187  if (notNull(edgeLst))
188  {
189  edges_.transfer(edgeLst);
190 
191  // connectivity likely changed
192  pointEdgesPtr_.clear();
193  }
194 }
195 
196 
198 {
199  points_.transfer(mesh.points_);
200  edges_.transfer(mesh.edges_);
201  pointEdgesPtr_ = mesh.pointEdgesPtr_;
202 }
203 
204 
206 {
207  edgeRegion.setSize(edges_.size());
208  edgeRegion = -1;
209 
210  label startEdgeI = 0;
211  label currentRegion = 0;
212 
213  while (true)
214  {
215  while (startEdgeI < edges_.size() && edgeRegion[startEdgeI] != -1)
216  {
217  startEdgeI++;
218  }
219 
220  if (startEdgeI == edges_.size())
221  {
222  break;
223  }
224 
225  // Found edge that has not yet been assigned a region.
226  // Mark connected region with currentRegion starting at startEdgeI.
227 
228  edgeRegion[startEdgeI] = currentRegion;
229  labelList edgesToVisit(1, startEdgeI);
230 
231  while (edgesToVisit.size())
232  {
233  // neighbours of current edgesToVisit
234  DynamicList<label> newEdgesToVisit(edgesToVisit.size());
235 
236  // Mark all point connected edges with current region.
237  forAll(edgesToVisit, i)
238  {
239  label edgeI = edgesToVisit[i];
240 
241  // Mark connected edges
242  const edge& e = edges_[edgeI];
243 
244  forAll(e, fp)
245  {
246  const labelList& pEdges = pointEdges()[e[fp]];
247 
248  forAll(pEdges, pEdgeI)
249  {
250  label nbrEdgeI = pEdges[pEdgeI];
251 
252  if (edgeRegion[nbrEdgeI] == -1)
253  {
254  edgeRegion[nbrEdgeI] = currentRegion;
255  newEdgesToVisit.append(nbrEdgeI);
256  }
257  }
258  }
259  }
260 
261  edgesToVisit.transfer(newEdgesToVisit);
262  }
263 
264  currentRegion++;
265  }
266  return currentRegion;
267 }
268 
269 
270 void Foam::edgeMesh::scalePoints(const scalar scaleFactor)
271 {
272  // avoid bad scaling
273  if (scaleFactor > 0 && scaleFactor != 1.0)
274  {
275  points_ *= scaleFactor;
276  }
277 }
278 
279 
281 (
282  const scalar mergeDist,
283  labelList& reversePointMap
284  // labelList& edgeMap
285 )
286 {
287  pointField newPoints;
288  labelList pointMap;
289 
290  bool hasMerged = Foam::mergePoints
291  (
292  points_,
293  mergeDist,
294  false,
295  pointMap,
296  newPoints,
298  );
299 
300  if (hasMerged)
301  {
302  pointEdgesPtr_.clear();
303 
304  points_.transfer(newPoints);
305 
306  // connectivity changed
307  pointEdgesPtr_.clear();
308 
309  // Renumber and make sure e[0] < e[1] (not really necessary)
310  forAll(edges_, edgeI)
311  {
312  edge& e = edges_[edgeI];
313 
314  label p0 = pointMap[e[0]];
315  label p1 = pointMap[e[1]];
316 
317  if (p0 < p1)
318  {
319  e[0] = p0;
320  e[1] = p1;
321  }
322  else
323  {
324  e[0] = p1;
325  e[1] = p0;
326  }
327  }
328 
329  // Compact using a hashtable and commutative hash of edge.
330  EdgeMap<label> edgeToLabel(2*edges_.size());
331 
332  label newEdgeI = 0;
333 
334  forAll(edges_, edgeI)
335  {
336  const edge& e = edges_[edgeI];
337 
338  if (e[0] != e[1])
339  {
340  if (edgeToLabel.insert(e, newEdgeI))
341  {
342  newEdgeI++;
343  }
344  }
345  }
346 
347  edges_.setSize(newEdgeI);
348 
349  forAllConstIter(EdgeMap<label>, edgeToLabel, iter)
350  {
351  edges_[iter()] = iter.key();
352  }
353  }
354 }
355 
356 
358 {
359  EdgeMap<label> existingEdges(2*edges_.size());
360 
361  label curEdgeI = 0;
362  forAll(edges_, edgeI)
363  {
364  const edge& e = edges_[edgeI];
365 
366  if (existingEdges.insert(e, curEdgeI))
367  {
368  curEdgeI++;
369  }
370  }
371 
372  if (debug)
373  {
374  Info<< "Merging duplicate edges: "
375  << edges_.size() - existingEdges.size()
376  << " edges will be deleted." << endl;
377  }
378 
379  edges_.setSize(existingEdges.size());
380 
381  forAllConstIter(EdgeMap<label>, existingEdges, iter)
382  {
383  edges_[iter()] = iter.key();
384  }
385 
386  // connectivity changed
387  pointEdgesPtr_.clear();
388 }
389 
390 
391 // ************************************************************************* //
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:197
A HashTable with keys but without contents.
Definition: HashSet.H:59
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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:79
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:323
virtual void mergePoints(const scalar mergeDist, labelList &)
Merge common points (points within mergeDist). Return map from.
Definition: edgeMesh.C:281
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
virtual void scalePoints(const scalar)
Scale points. A non-positive factor is ignored.
Definition: edgeMesh.C:270
static bool canRead(const fileName &, const bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:90
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:299
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
const labelListList & pointEdges() const
Return edges.
Definition: edgeMeshI.H:74
dynamicFvMesh & mesh
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
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:178
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
static wordHashSet readTypes()
Definition: edgeMesh.C:43
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:208
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(pointField &&points, edgeList &&edges)
Reset primitive data (points, edges)
Definition: edgeMesh.C:175
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:52
virtual void clear()
Clear all storage.
Definition: edgeMesh.C:166
void setSize(const label)
Reset size of List.
Definition: List.C:281
virtual void mergeEdges()
Merge duplicate edges.
Definition: edgeMesh.C:357
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:284
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:105
label regions(labelList &edgeRegion) const
Find connected regions. Set region number per edge.
Definition: edgeMesh.C:205
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:160
static bool canWriteType(const word &ext, const bool verbose=false)
Can we write this file format type?
Definition: edgeMesh.C:74
Namespace for OpenFOAM.