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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2017 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "edgeMesh.H"
30 #include "bitSet.H"
31 #include "edgeHashes.H"
32 #include "mergePoints.H"
33 #include "ListOps.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41  defineTypeNameAndDebug(edgeMesh, 0);
44 }
45 
46 
48 {
49  return wordHashSet(*fileExtensionConstructorTablePtr_);
50 }
51 
52 
54 {
55  return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
56 }
57 
58 
59 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
60 
61 bool Foam::edgeMesh::canReadType(const word& ext, bool verbose)
62 {
63  return checkSupport
64  (
65  readTypes(),
66  ext,
67  verbose,
68  "reading"
69  );
70 }
71 
72 
73 bool Foam::edgeMesh::canWriteType(const word& ext, bool verbose)
74 {
75  return checkSupport
76  (
77  writeTypes(),
78  ext,
79  verbose,
80  "writing"
81  );
82 }
83 
84 
85 bool Foam::edgeMesh::canRead(const fileName& name, bool verbose)
86 {
87  word ext = name.ext();
88  if (ext == "gz")
89  {
90  ext = name.lessExt().ext();
91  }
92  return canReadType(ext, verbose);
93 }
94 
95 
96 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
97 
98 void Foam::edgeMesh::calcPointEdges() const
99 {
100  if (pointEdgesPtr_.valid())
101  {
103  << "pointEdges already calculated." << abort(FatalError);
104  }
105 
106  pointEdgesPtr_.reset(new labelListList(points_.size()));
107  labelListList& pointEdges = pointEdgesPtr_();
108 
109  invertManyToMany(pointEdges.size(), edges_, pointEdges);
110 }
111 
112 
113 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
114 
116 {
117  points_.clear();
118  edges_.clear();
119  pointEdgesPtr_.clear();
120 }
121 
122 
124 {
125  points_.transfer(mesh.points_);
126  edges_.transfer(mesh.edges_);
127  pointEdgesPtr_ = std::move(mesh.pointEdgesPtr_);
128 }
129 
130 
132 {
133  edgeRegion.setSize(edges_.size());
134  edgeRegion = -1;
135 
136  label startEdgeI = 0;
137  label currentRegion = 0;
138 
139  while (true)
140  {
141  while (startEdgeI < edges_.size() && edgeRegion[startEdgeI] != -1)
142  {
143  startEdgeI++;
144  }
145 
146  if (startEdgeI == edges_.size())
147  {
148  break;
149  }
150 
151  // Found edge that has not yet been assigned a region.
152  // Mark connected region with currentRegion starting at startEdgeI.
153 
154  edgeRegion[startEdgeI] = currentRegion;
155  labelList edgesToVisit(1, startEdgeI);
156 
157  while (edgesToVisit.size())
158  {
159  // neighbours of current edgesToVisit
160  DynamicList<label> newEdgesToVisit(edgesToVisit.size());
161 
162  // Mark all point connected edges with current region.
163  forAll(edgesToVisit, i)
164  {
165  label edgeI = edgesToVisit[i];
166 
167  // Mark connected edges
168  const edge& e = edges_[edgeI];
169 
170  forAll(e, fp)
171  {
172  const labelList& pEdges = pointEdges()[e[fp]];
173 
174  forAll(pEdges, pEdgeI)
175  {
176  label nbrEdgeI = pEdges[pEdgeI];
177 
178  if (edgeRegion[nbrEdgeI] == -1)
179  {
180  edgeRegion[nbrEdgeI] = currentRegion;
181  newEdgesToVisit.append(nbrEdgeI);
182  }
183  }
184  }
185  }
186 
187  edgesToVisit.transfer(newEdgesToVisit);
188  }
189 
190  currentRegion++;
191  }
192  return currentRegion;
193 }
194 
195 
196 void Foam::edgeMesh::scalePoints(const scalar scaleFactor)
197 {
198  // avoid bad scaling
199  if (scaleFactor > 0 && scaleFactor != 1.0)
200  {
201  points_ *= scaleFactor;
202  }
203 }
204 
205 
206 void Foam::edgeMesh::mergePoints(const scalar mergeDist)
207 {
208  pointField newPoints;
209  labelList pointMap;
210 
211  const bool hasMerged = Foam::mergePoints
212  (
213  points_,
214  mergeDist,
215  false,
216  pointMap,
217  newPoints,
219  );
220 
221  if (hasMerged)
222  {
223  pointEdgesPtr_.clear(); // connectivity change
224 
225  points_.transfer(newPoints);
226 
227  forAll(edges_, edgeI)
228  {
229  edge& e = edges_[edgeI];
230 
231  e[0] = pointMap[e[0]];
232  e[1] = pointMap[e[1]];
233  }
234  }
235 
236  this->mergeEdges();
237 }
238 
239 
241 {
242  edgeHashSet uniqEdges(2*edges_.size());
243  bitSet pointIsUsed(points_.size());
244 
245  label nUniqEdges = 0;
246  label nUniqPoints = 0;
247  forAll(edges_, edgeI)
248  {
249  const edge& e = edges_[edgeI];
250 
251  // Remove degenerate and repeated edges
252  // - reordering (e[0] < e[1]) is not really necessary
253  if (e[0] != e[1] && uniqEdges.insert(e))
254  {
255  if (nUniqEdges != edgeI)
256  {
257  edges_[nUniqEdges] = e;
258  }
259  edges_[nUniqEdges].sort();
260  ++nUniqEdges;
261 
262  if (pointIsUsed.set(e[0]))
263  {
264  ++nUniqPoints;
265  }
266  if (pointIsUsed.set(e[1]))
267  {
268  ++nUniqPoints;
269  }
270  }
271  }
272 
273  if (debug)
274  {
275  Info<< "Merging duplicate edges: "
276  << (edges_.size() - nUniqEdges)
277  << " edges will be deleted, "
278  << (points_.size() - nUniqPoints)
279  << " unused points will be removed." << endl;
280  }
281 
282  if (nUniqEdges < edges_.size())
283  {
284  pointEdgesPtr_.clear(); // connectivity change
285  edges_.setSize(nUniqEdges); // truncate
286  }
287 
288  if (nUniqPoints < points_.size())
289  {
290  pointEdgesPtr_.clear(); // connectivity change
291 
292  // build a oldToNew point-map and rewrite the points.
293  // We can do this simultaneously since the point order is unchanged
294  // and we are only effectively eliminating some entries.
295  labelList pointMap(points_.size(), -1);
296 
297  label newId = 0;
298  forAll(pointMap, pointi)
299  {
300  if (pointIsUsed.test(pointi))
301  {
302  pointMap[pointi] = newId;
303 
304  if (newId < pointi)
305  {
306  // copy down
307  points_[newId] = points_[pointi];
308  }
309  ++newId;
310  }
311  }
312  points_.setSize(newId);
313 
314  // Renumber edges - already sorted (above)
315  forAll(edges_, edgeI)
316  {
317  edge& e = edges_[edgeI];
318 
319  e[0] = pointMap[e[0]];
320  e[1] = pointMap[e[1]];
321  }
322  }
323 
324 }
325 
326 
327 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::word::lessExt
word lessExt() const
Return word without extension (part before last .)
Definition: word.C:113
Foam::edgeMesh::scalePoints
virtual void scalePoints(const scalar scaleFactor)
Scale points. A non-positive factor is ignored.
Definition: edgeMesh.C:196
Foam::edgeMesh::regions
label regions(labelList &edgeRegion) const
Find connected regions. Set region number per edge.
Definition: edgeMesh.C:131
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:64
Foam::DynamicList< label >
Foam::vtk::fileExtension
const Foam::Enum< fileTag > fileExtension
File extension (without ".") for some vtk XML file content types.
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
Foam::edgeMesh::canReadType
static bool canReadType(const word &ext, bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:61
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:63
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:182
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::word::ext
word ext() const
Return file name extension (part after last .)
Definition: word.C:126
Foam::HashSet< word >
bitSet.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::invertManyToMany
void invertManyToMany(const label len, const UList< InputIntListType > &input, List< OutputIntListType > &output)
Invert many-to-many.
Definition: ListOpsTemplates.C:727
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:62
Foam::Field< vector >
Foam::edgeMesh::writeTypes
static wordHashSet writeTypes()
Definition: edgeMesh.C:53
edgeMesh.H
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::edgeMesh::readTypes
static wordHashSet readTypes()
Definition: edgeMesh.C:47
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:436
addToMemberFunctionSelectionTable.H
Macros for easy insertion into member function selection tables.
Foam::defineMemberFunctionSelectionTable
defineMemberFunctionSelectionTable(edgeMesh, write, fileExtension)
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
Foam::mergePoints
label mergePoints(const PointList &points, const scalar mergeTol, const bool verbose, labelList &pointMap, typename PointList::const_reference origin=PointList::value_type::zero)
Sorts and merges points. All points closer than/equal mergeTol get merged.
Foam::edgeMesh::mergeEdges
virtual void mergeEdges()
Merge duplicate edges and eliminate unused points.
Definition: edgeMesh.C:240
Foam::edgeMesh::canRead
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:85
Foam::edgeMesh::clear
virtual void clear()
Clear all storage.
Definition: edgeMesh.C:115
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
Foam::edgeMesh::mergePoints
virtual void mergePoints(const scalar mergeDist)
Geometric merge points (points within mergeDist) prior to.
Definition: edgeMesh.C:206
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
edgeHashes.H
Foam::List< label >
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:35
mergePoints.H
Merge points. See below.
Foam::wordHashSet
HashSet< word > wordHashSet
A HashSet with word keys.
Definition: HashSet.H:412
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::zero
static const Vector< scalar > zero
Definition: VectorSpace.H:115
Foam::edgeMesh::canWriteType
static bool canWriteType(const word &ext, bool verbose=false)
Can we write this file format type?
Definition: edgeMesh.C:73
ListOps.H
Various functions to operate on Lists.
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::edgeMesh
Mesh data needed to do the Finite Area discretisation.
Definition: edgeFaMesh.H:52
Foam::edgeMesh::transfer
void transfer(edgeMesh &mesh)
Transfer the contents of the argument and annul the argument.
Definition: edgeMesh.C:123