extendedFeatureEdgeMeshTemplates.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-2017 OpenFOAM Foundation
9  Copyright (C) 2018 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 
30 #include "ListListOps.H"
31 #include "unitConversion.H"
32 #include "bitSet.H"
33 #include "PatchTools.H"
34 #include "searchableBox.H"
35 
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 
38 template<class Patch>
40 (
41  const Patch& surf,
42  const labelList& featureEdges,
43  const labelList& regionFeatureEdges,// subset of featureEdges: inter-region
44  const labelList& featurePoints
45 )
46 {
47  const pointField& sFeatLocalPts(surf.localPoints());
48  const edgeList& sFeatEds(surf.edges());
49  const labelListList edgeFaces = PatchTools::sortedEdgeFaces(surf);
50  const vectorField& faceNormals = surf.faceNormals();
52 
53  // Extract and reorder the data from surfaceFeatures
54 
55  // References to the surfaceFeatures data
56 
57  // Filling the extendedFeatureEdgeMesh with the raw geometrical data.
58 
59  label nFeatEds = featureEdges.size();
60  label nFeatPts = featurePoints.size();
61 
62  DynamicList<point> tmpPts;
63  edgeList eds(nFeatEds);
64  DynamicList<vector> norms;
65  vectorField edgeDirections(nFeatEds);
66  labelListList edgeNormals(nFeatEds);
68  DynamicList<label> regionEdges;
69 
70  // Keep track of the ordered feature point feature edges
71  labelListList featurePointFeatureEdges(nFeatPts);
72  forAll(featurePointFeatureEdges, pI)
73  {
74  featurePointFeatureEdges[pI] = pointEdges[featurePoints[pI]];
75  }
76 
77  // Mapping between old and new indices, there is entry in the map for each
78  // of surf.localPoints, -1 means that this point hasn't been used (yet),
79  // >= 0 corresponds to the index
80  labelList pointMap(sFeatLocalPts.size(), -1);
81 
82  // Mapping between surface edge index and its feature edge index. -1 if it
83  // is not a feature edge
84  labelList edgeMap(sFeatEds.size(), -1);
85 
86  // Noting when the normal of a face has been used so not to duplicate
87  labelList faceMap(surf.size(), -1);
88 
89  // Collecting the status of edge for subsequent sorting
90  List<edgeStatus> edStatus(nFeatEds, NONE);
91 
92  forAll(featurePoints, i)
93  {
94  label sFPI = featurePoints[i];
95 
96  tmpPts.append(sFeatLocalPts[sFPI]);
97 
98  pointMap[sFPI] = tmpPts.size() - 1;
99  }
100 
101  // All feature points have been added
102  nonFeatureStart_ = tmpPts.size();
103 
104  bitSet isRegionFeatureEdge(regionFeatureEdges);
105 
106  forAll(featureEdges, i)
107  {
108  label sFEI = featureEdges[i];
109 
110  edgeMap[sFEI] = i;
111 
112  const edge& fE = sFeatEds[sFEI];
113 
114  edgeDirections[i] = fE.vec(sFeatLocalPts);
115 
116  // Check to see if the points have been already used
117  if (pointMap[fE.start()] == -1)
118  {
119  tmpPts.append(sFeatLocalPts[fE.start()]);
120 
121  pointMap[fE.start()] = tmpPts.size() - 1;
122  }
123 
124  eds[i].start() = pointMap[fE.start()];
125 
126  if (pointMap[fE.end()] == -1)
127  {
128  tmpPts.append(sFeatLocalPts[fE.end()]);
129 
130  pointMap[fE.end()] = tmpPts.size() - 1;
131  }
132 
133  eds[i].end() = pointMap[fE.end()];
134 
135  // Pick up the faces adjacent to the feature edge
136  const labelList& eFaces = edgeFaces[sFEI];
137 
138  edgeNormals[i].setSize(eFaces.size());
139  normalDirections[i].setSize(eFaces.size());
140 
141  forAll(eFaces, j)
142  {
143  label eFI = eFaces[j];
144 
145  // Check to see if the points have been already used
146  if (faceMap[eFI] == -1)
147  {
148  norms.append(faceNormals[eFI]);
149 
150  faceMap[eFI] = norms.size() - 1;
151  }
152 
153  edgeNormals[i][j] = faceMap[eFI];
154 
155  const vector cross = (faceNormals[eFI] ^ edgeDirections[i]);
156  const vector fC0tofE0 =
157  surf[eFI].centre(surf.points())
158  - sFeatLocalPts[fE.start()];
159 
160  normalDirections[i][j] =
161  (
162  (
163  (cross/(mag(cross) + VSMALL))
164  & (fC0tofE0/(mag(fC0tofE0)+ VSMALL))
165  )
166  > 0.0
167  ? 1
168  : -1
169  );
170  }
171 
172  vector fC0tofC1(Zero);
173 
174  if (eFaces.size() == 2)
175  {
176  fC0tofC1 =
177  surf[eFaces[1]].centre(surf.points())
178  - surf[eFaces[0]].centre(surf.points());
179  }
180 
181  edStatus[i] = classifyEdge(norms, edgeNormals[i], fC0tofC1);
182 
183  if (isRegionFeatureEdge.test(i))
184  {
185  regionEdges.append(i);
186  }
187  }
188 
189  // Populate feature point feature edges
190  DynamicList<label> newFeatureEdges;
191 
192  forAll(featurePointFeatureEdges, pI)
193  {
194  const labelList& fpfe = featurePointFeatureEdges[pI];
195 
196  newFeatureEdges.setCapacity(fpfe.size());
197 
198  forAll(fpfe, eI)
199  {
200  const label oldEdgeIndex = fpfe[eI];
201 
202  const label newFeatureEdgeIndex = edgeMap[oldEdgeIndex];
203 
204  if (newFeatureEdgeIndex != -1)
205  {
206  newFeatureEdges.append(newFeatureEdgeIndex);
207  }
208  }
209 
210  featurePointFeatureEdges[pI].transfer(newFeatureEdges);
211  }
212 
213  // Reorder the edges by classification
214  List<DynamicList<label>> allEds(nEdgeTypes);
215 
216  DynamicList<label>& externalEds(allEds[0]);
217  DynamicList<label>& internalEds(allEds[1]);
218  DynamicList<label>& flatEds(allEds[2]);
219  DynamicList<label>& openEds(allEds[3]);
220  DynamicList<label>& multipleEds(allEds[4]);
221 
222  forAll(eds, i)
223  {
224  edgeStatus eStat = edStatus[i];
225 
226  if (eStat == EXTERNAL)
227  {
228  externalEds.append(i);
229  }
230  else if (eStat == INTERNAL)
231  {
232  internalEds.append(i);
233  }
234  else if (eStat == FLAT)
235  {
236  flatEds.append(i);
237  }
238  else if (eStat == OPEN)
239  {
240  openEds.append(i);
241  }
242  else if (eStat == MULTIPLE)
243  {
244  multipleEds.append(i);
245  }
246  else if (eStat == NONE)
247  {
249  << nl << "classifyEdge returned NONE on edge "
250  << eds[i]
251  << ". There is a problem with definition of this edge."
252  << nl << abort(FatalError);
253  }
254  }
255 
256  internalStart_ = externalEds.size();
257  flatStart_ = internalStart_ + internalEds.size();
258  openStart_ = flatStart_ + flatEds.size();
259  multipleStart_ = openStart_ + openEds.size();
260 
261  labelList edMap
262  (
263  ListListOps::combine<labelList>
264  (
265  allEds,
266  accessOp<labelList>()
267  )
268  );
269 
270  edMap = invert(edMap.size(), edMap);
271 
272  inplaceReorder(edMap, eds);
273  inplaceReorder(edMap, edStatus);
275  inplaceReorder(edMap, edgeNormals);
278 
279  forAll(featurePointFeatureEdges, pI)
280  {
281  inplaceRenumber(edMap, featurePointFeatureEdges[pI]);
282  }
283 
284  pointField pts(tmpPts);
285 
286  // Initialise the edgeMesh
287  edgeMesh::operator=(edgeMesh(pts, eds));
288 
289  // Initialise sorted edge related data
294 
295  // Normals are all now found and indirectly addressed, can also be stored
296  normals_ = vectorField(norms);
297 
298 
299  // Reorder the feature points by classification
300 
301  List<DynamicList<label>> allPts(3);
302 
303  DynamicList<label>& convexPts(allPts[0]);
304  DynamicList<label>& concavePts(allPts[1]);
305  DynamicList<label>& mixedPts(allPts[2]);
306 
307  for (label i = 0; i < nonFeatureStart_; i++)
308  {
309  pointStatus ptStatus = classifyFeaturePoint(i);
310 
311  if (ptStatus == CONVEX)
312  {
313  convexPts.append(i);
314  }
315  else if (ptStatus == CONCAVE)
316  {
317  concavePts.append(i);
318  }
319  else if (ptStatus == MIXED)
320  {
321  mixedPts.append(i);
322  }
323  else if (ptStatus == NONFEATURE)
324  {
326  << nl << "classifyFeaturePoint returned NONFEATURE on point at "
327  << points()[i]
328  << ". There is a problem with definition of this feature point."
329  << nl << abort(FatalError);
330  }
331  }
332 
333  concaveStart_ = convexPts.size();
334  mixedStart_ = concaveStart_ + concavePts.size();
335 
336  labelList ftPtMap
337  (
338  ListListOps::combine<labelList>
339  (
340  allPts,
341  accessOp<labelList>()
342  )
343  );
344 
345  ftPtMap = invert(ftPtMap.size(), ftPtMap);
346 
347  // Creating the ptMap from the ftPtMap with identity values up to the size
348  // of pts to create an oldToNew map for inplaceReorder
349 
350  labelList ptMap(identity(pts.size()));
351 
352  forAll(ftPtMap, i)
353  {
354  ptMap[i] = ftPtMap[i];
355  }
356 
357  inplaceReorder(ptMap, pts);
358  inplaceReorder(ptMap, featurePointFeatureEdges);
359 
360  forAll(eds, i)
361  {
362  inplaceRenumber(ptMap, eds[i]);
363  }
364 
365  // Reinitialise the edgeMesh with sorted feature points and
366  // renumbered edges
367  {
368  edgeMesh newmesh(std::move(pts), std::move(eds));
369  edgeMesh::transfer(newmesh);
370  }
371 
372  // Generate the featurePointNormals
373 
375 
376  for (label i = 0; i < nonFeatureStart_; i++)
377  {
378  DynamicList<label> tmpFtPtNorms;
379 
380  const labelList& ptEds = edgeMesh::pointEdges()[i];
381 
382  forAll(ptEds, j)
383  {
384  const labelList& ptEdNorms(edgeNormals[ptEds[j]]);
385 
386  forAll(ptEdNorms, k)
387  {
388  if (!tmpFtPtNorms.found(ptEdNorms[k]))
389  {
390  bool addNormal = true;
391 
392  // Check that the normal direction is unique at this feature
393  forAll(tmpFtPtNorms, q)
394  {
395  if
396  (
397  (normals_[ptEdNorms[k]] & normals_[tmpFtPtNorms[q]])
399  )
400  {
401  // Parallel to an existing normal, do not add
402  addNormal = false;
403 
404  break;
405  }
406  }
407 
408  if (addNormal)
409  {
410  tmpFtPtNorms.append(ptEdNorms[k]);
411  }
412  }
413  }
414  }
415 
416  featurePointNormals[i] = tmpFtPtNorms;
417  }
418 
420  featurePointEdges_ = featurePointFeatureEdges;
421 }
422 
423 
424 // ************************************************************************* //
Foam::extendedEdgeMesh::NONE
Unclassified (consistency with surfaceFeatures)
Definition: extendedEdgeMesh.H:111
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::extendedEdgeMesh::normalDirections
const labelListList & normalDirections() const
Definition: extendedEdgeMeshI.H:111
Foam::extendedEdgeMesh::regionEdges_
labelList regionEdges_
Feature edges which are on the boundary between regions.
Definition: extendedEdgeMesh.H:192
Foam::edgeMesh::points
const pointField & points() const noexcept
Return points.
Definition: edgeMeshI.H:99
Foam::extendedEdgeMesh::edgeStatus
edgeStatus
Definition: extendedEdgeMesh.H:104
Foam::extendedEdgeMesh::featurePointNormals
const labelListList & featurePointNormals() const
Return the indices of the normals that are adjacent to the.
Definition: extendedEdgeMeshI.H:177
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::edgeMesh::operator=
void operator=(const edgeMesh &rhs)
Copy assignment.
Definition: edgeMeshI.H:123
Foam::edgeList
List< edge > edgeList
A List of edges.
Definition: edgeList.H:63
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
PatchTools.H
Foam::extendedEdgeMesh::FLAT
Neither concave or convex, on a flat surface.
Definition: extendedEdgeMesh.H:108
ListListOps.H
searchableBox.H
Foam::extendedEdgeMesh::concaveStart_
label concaveStart_
Index of the start of the concave feature points.
Definition: extendedEdgeMesh.H:145
Foam::edgeMesh::edgeMesh
edgeMesh()
Default construct.
Definition: edgeMeshI.H:45
Foam::extendedEdgeMesh::regionEdges
const labelList & regionEdges() const
Return the feature edges which are on the boundary between.
Definition: extendedEdgeMeshI.H:218
unitConversion.H
Unit conversion functions.
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:175
Foam::extendedEdgeMesh::NONFEATURE
Not a feature point.
Definition: extendedEdgeMesh.H:99
Foam::extendedEdgeMesh::mixedStart_
label mixedStart_
Index of the start of the mixed type feature points.
Definition: extendedEdgeMesh.H:148
Foam::PatchTools::sortedPointEdges
static labelListList sortedPointEdges(const PrimitivePatch< FaceList, PointField > &)
Return point-edge addressing sorted by order around the point.
bitSet.H
extendedFeatureEdgeMesh.H
Foam::invert
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:36
Foam::inplaceRenumber
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:61
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::PatchTools::sortedEdgeFaces
static labelListList sortedEdgeFaces(const PrimitivePatch< FaceList, PointField > &)
Return edge-face addressing sorted by angle around the edge.
Foam::extendedEdgeMesh::INTERNAL
"Concave" edge
Definition: extendedEdgeMesh.H:107
Foam::extendedEdgeMesh::edgeDirections
const vectorField & edgeDirections() const
Return the edgeDirection vectors.
Definition: extendedEdgeMeshI.H:103
Foam::extendedEdgeMesh::classifyEdge
static edgeStatus classifyEdge(const List< vector > &norms, const labelList &edNorms, const vector &fC0tofC1)
Classify the type of feature edge. Requires face centre 0 to face.
Definition: extendedEdgeMesh.C:2098
faceNormals
surfaceVectorField faceNormals(mesh.Sf()/mesh.magSf())
Foam::extendedEdgeMesh::nEdgeTypes
static constexpr label nEdgeTypes
Number of possible feature edge types (i.e. number of slices)
Definition: extendedEdgeMesh.H:254
Foam::extendedEdgeMesh::edgeDirections_
vectorField edgeDirections_
Flat and open edges require the direction of the edge.
Definition: extendedEdgeMesh.H:173
Foam::extendedEdgeMesh::MIXED
A point surrounded by both convex and concave edges.
Definition: extendedEdgeMesh.H:98
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::Vector::centre
const Vector< Cmpt > & centre(const Foam::List< Vector< Cmpt >> &) const
Return *this (used for point which is a typedef to Vector<scalar>.
Definition: VectorI.H:114
Foam::extendedEdgeMesh::multipleStart_
label multipleStart_
Index of the start of the multiply-connected feature edges.
Definition: extendedEdgeMesh.H:163
Foam::extendedEdgeMesh::cosNormalAngleTol_
static scalar cosNormalAngleTol_
Angular closeness tolerance for treating normals as the same.
Definition: extendedEdgeMesh.H:128
Foam::edgeMesh::pointEdges
const labelListList & pointEdges() const
Return edges.
Definition: edgeMeshI.H:111
Foam::FatalError
error FatalError
Foam::extendedEdgeMesh::edgeNormals
const labelListList & edgeNormals() const
Return the indices of the normals that are adjacent to the.
Definition: extendedEdgeMeshI.H:146
Foam::extendedEdgeMesh::MULTIPLE
Multiply connected (connected to more than two faces)
Definition: extendedEdgeMesh.H:110
Foam::extendedEdgeMesh::edgeNormals_
labelListList edgeNormals_
Indices of the normals that are adjacent to the feature edges.
Definition: extendedEdgeMesh.H:181
Foam::extendedEdgeMesh::CONVEX
Fully convex point (w.r.t normals)
Definition: extendedEdgeMesh.H:96
Foam::extendedEdgeMesh::pointStatus
pointStatus
Definition: extendedEdgeMesh.H:94
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::extendedEdgeMesh::normals_
vectorField normals_
Normals of the features, to be referred to by index by both feature.
Definition: extendedEdgeMesh.H:167
Foam::extendedEdgeMesh::internalStart_
label internalStart_
Index of the start of the internal feature edges.
Definition: extendedEdgeMesh.H:154
Foam::extendedEdgeMesh::normalDirections_
labelListList normalDirections_
Starting directions for the edges.
Definition: extendedEdgeMesh.H:178
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::extendedEdgeMesh::OPEN
Only connected to a single face.
Definition: extendedEdgeMesh.H:109
Foam::extendedEdgeMesh::EXTERNAL
"Convex" edge
Definition: extendedEdgeMesh.H:106
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::extendedEdgeMesh::classifyFeaturePoint
pointStatus classifyFeaturePoint(label ptI) const
Classify the type of feature point. Requires valid stored member.
Definition: extendedEdgeMesh.C:152
Foam::extendedEdgeMesh::featurePointEdges_
labelListList featurePointEdges_
Indices of feature edges attached to feature points. The edges are.
Definition: extendedEdgeMesh.H:189
Foam::extendedEdgeMesh::sortPointsAndEdges
void sortPointsAndEdges(const Patch &, const labelUList &featureEdges, const labelUList &regionFeatureEdges, const labelUList &feaurePoints)
Definition: extendedEdgeMeshTemplates.C:40
Foam::inplaceReorder
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
Definition: ListOpsTemplates.C:124
Foam::extendedEdgeMesh::flatStart_
label flatStart_
Index of the start of the flat feature edges.
Definition: extendedEdgeMesh.H:157
Foam::extendedEdgeMesh::nonFeatureStart_
label nonFeatureStart_
Index of the start of the non-feature points.
Definition: extendedEdgeMesh.H:151
Foam::cross
void cross(FieldField< Field1, typename crossProduct< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Definition: FieldFieldFunctions.C:943
Foam::extendedEdgeMesh::openStart_
label openStart_
Index of the start of the open feature edges.
Definition: extendedEdgeMesh.H:160
Foam::edgeMesh::transfer
void transfer(edgeMesh &mesh)
Transfer the contents of the argument and annul the argument.
Definition: edgeMesh.C:124
Foam::extendedEdgeMesh::featurePointNormals_
labelListList featurePointNormals_
Indices of the normals that are adjacent to the feature points.
Definition: extendedEdgeMesh.H:185
Foam::extendedEdgeMesh::CONCAVE
Fully concave point.
Definition: extendedEdgeMesh.H:97