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-2021 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 
47 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
48 
50 {
51  return wordHashSet(*fileExtensionConstructorTablePtr_);
52 }
53 
54 
56 {
57  return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
58 }
59 
60 
61 bool Foam::edgeMesh::canReadType(const word& fileType, bool verbose)
62 {
63  return checkSupport
64  (
65  readTypes(),
66  fileType,
67  verbose,
68  "reading"
69  );
70 }
71 
72 
73 bool Foam::edgeMesh::canWriteType(const word& fileType, bool verbose)
74 {
75  return checkSupport
76  (
77  writeTypes(),
78  fileType,
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_)
101  {
103  << "pointEdges already calculated."
104  << abort(FatalError);
105  }
106 
107  pointEdgesPtr_.reset(new labelListList(points_.size()));
108  auto& pointEdges = *pointEdgesPtr_;
109 
110  invertManyToMany(pointEdges.size(), edges_, pointEdges);
111 }
112 
113 
114 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
115 
117 {
118  points_.clear();
119  edges_.clear();
120  pointEdgesPtr_.reset(nullptr);
121 }
122 
123 
125 {
126  if (&mesh == this)
127  {
128  return; // Self-transfer is a no-op
129  }
130 
131  points_.transfer(mesh.points_);
132  edges_.transfer(mesh.edges_);
133  pointEdgesPtr_ = std::move(mesh.pointEdgesPtr_);
134 }
135 
136 
137 Foam::label Foam::edgeMesh::regions(labelList& edgeRegion) const
138 {
139  edgeRegion.setSize(edges_.size());
140  edgeRegion = -1;
141 
142  label startEdgeI = 0;
143  label currentRegion = 0;
144 
145  while (true)
146  {
147  while (startEdgeI < edges_.size() && edgeRegion[startEdgeI] != -1)
148  {
149  startEdgeI++;
150  }
151 
152  if (startEdgeI == edges_.size())
153  {
154  break;
155  }
156 
157  // Found edge that has not yet been assigned a region.
158  // Mark connected region with currentRegion starting at startEdgeI.
159 
160  edgeRegion[startEdgeI] = currentRegion;
161  labelList edgesToVisit(1, startEdgeI);
162 
163  while (edgesToVisit.size())
164  {
165  // neighbours of current edgesToVisit
166  DynamicList<label> newEdgesToVisit(edgesToVisit.size());
167 
168  // Mark all point connected edges with current region.
169  forAll(edgesToVisit, i)
170  {
171  label edgeI = edgesToVisit[i];
172 
173  // Mark connected edges
174  const edge& e = edges_[edgeI];
175 
176  forAll(e, fp)
177  {
178  const labelList& pEdges = pointEdges()[e[fp]];
179 
180  forAll(pEdges, pEdgeI)
181  {
182  label nbrEdgeI = pEdges[pEdgeI];
183 
184  if (edgeRegion[nbrEdgeI] == -1)
185  {
186  edgeRegion[nbrEdgeI] = currentRegion;
187  newEdgesToVisit.append(nbrEdgeI);
188  }
189  }
190  }
191  }
192 
193  edgesToVisit.transfer(newEdgesToVisit);
194  }
195 
196  currentRegion++;
197  }
198 
199  return currentRegion;
200 }
201 
202 
203 void Foam::edgeMesh::scalePoints(const scalar scaleFactor)
204 {
205  // avoid bad scaling
206  if (scaleFactor > VSMALL && !equal(scaleFactor, 1))
207  {
208  points_ *= scaleFactor;
209  }
210 }
211 
212 
213 void Foam::edgeMesh::mergePoints(const scalar mergeDist)
214 {
215  pointField newPoints;
216  labelList pointMap;
217 
218  const bool hasMerged = Foam::mergePoints
219  (
220  points_,
221  mergeDist,
222  false,
223  pointMap,
224  newPoints,
226  );
227 
228  if (hasMerged)
229  {
230  pointEdgesPtr_.reset(nullptr); // connectivity change
231 
232  points_.transfer(newPoints);
233 
234  forAll(edges_, edgeI)
235  {
236  edge& e = edges_[edgeI];
237 
238  e[0] = pointMap[e[0]];
239  e[1] = pointMap[e[1]];
240  }
241  }
242 
243  this->mergeEdges();
244 }
245 
246 
248 {
249  edgeHashSet uniqEdges(2*edges_.size());
250  bitSet pointIsUsed(points_.size());
251 
252  label nUniqEdges = 0;
253  label nUniqPoints = 0;
254  forAll(edges_, edgeI)
255  {
256  const edge& e = edges_[edgeI];
257 
258  // Remove degenerate and repeated edges
259  // - reordering (e[0] < e[1]) is not really necessary
260  if (e[0] != e[1] && uniqEdges.insert(e))
261  {
262  if (nUniqEdges != edgeI)
263  {
264  edges_[nUniqEdges] = e;
265  }
266  edges_[nUniqEdges].sort();
267  ++nUniqEdges;
268 
269  if (pointIsUsed.set(e[0]))
270  {
271  ++nUniqPoints;
272  }
273  if (pointIsUsed.set(e[1]))
274  {
275  ++nUniqPoints;
276  }
277  }
278  }
279 
280  if (debug)
281  {
282  Info<< "Merging duplicate edges: "
283  << (edges_.size() - nUniqEdges)
284  << " edges will be deleted, "
285  << (points_.size() - nUniqPoints)
286  << " unused points will be removed." << endl;
287  }
288 
289  if (nUniqEdges < edges_.size())
290  {
291  pointEdgesPtr_.reset(nullptr); // connectivity change
292  edges_.setSize(nUniqEdges); // truncate
293  }
294 
295  if (nUniqPoints < points_.size())
296  {
297  pointEdgesPtr_.reset(nullptr); // connectivity change
298 
299  // build a oldToNew point-map and rewrite the points.
300  // We can do this simultaneously since the point order is unchanged
301  // and we are only effectively eliminating some entries.
302  labelList pointMap(points_.size(), -1);
303 
304  label newId = 0;
305  forAll(pointMap, pointi)
306  {
307  if (pointIsUsed.test(pointi))
308  {
309  pointMap[pointi] = newId;
310 
311  if (newId < pointi)
312  {
313  // copy down
314  points_[newId] = points_[pointi];
315  }
316  ++newId;
317  }
318  }
319  points_.setSize(newId);
320 
321  // Renumber edges - already sorted (above)
322  forAll(edges_, edgeI)
323  {
324  edge& e = edges_[edgeI];
325 
326  e[0] = pointMap[e[0]];
327  e[1] = pointMap[e[1]];
328  }
329  }
330 }
331 
332 
333 // ************************************************************************* //
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:203
Foam::edgeMesh::regions
label regions(labelList &edgeRegion) const
Find connected regions. Set region number per edge.
Definition: edgeMesh.C:137
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::edgeMesh::canReadType
static bool canReadType(const word &fileType, bool verbose=false)
Can we read this file format?
Definition: edgeMesh.C:61
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
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::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:175
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::word::ext
word ext() const
Return file name extension (part after last .)
Definition: word.C:126
Foam::HashSet< word, Hash< word > >
bitSet.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::invertManyToMany
void invertManyToMany(const label len, const UList< InputIntListType > &input, List< OutputIntListType > &output)
Invert many-to-many.
Definition: ListOpsTemplates.C:720
Foam::Field< vector >
Foam::edgeMesh::writeTypes
static wordHashSet writeTypes()
Summary of supported write file types.
Definition: edgeMesh.C:55
edgeMesh.H
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::edgeMesh::readTypes
static wordHashSet readTypes()
Summary of supported read file types.
Definition: edgeMesh.C:49
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:456
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:144
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:247
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:116
Foam::edgeMesh::canWriteType
static bool canWriteType(const word &fileType, bool verbose=false)
Can we write this file format type?
Definition: edgeMesh.C:73
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:213
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
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:36
mergePoints.H
Merge points. See below.
Foam::wordHashSet
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
Definition: HashSet.H:77
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::zero
static const Vector< scalar > zero
Definition: VectorSpace.H:115
ListOps.H
Various functions to operate on Lists.
Foam::equal
bool equal(const T &s1, const T &s2)
Compare two values for equality.
Definition: doubleFloat.H:46
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::edgeMesh
Mesh data needed to do the Finite Area discretisation.
Definition: edgeFaMesh.H:53
Foam::edgeMesh::transfer
void transfer(edgeMesh &mesh)
Transfer the contents of the argument and annul the argument.
Definition: edgeMesh.C:124