edgeExtractorCorners.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | cfMesh: A library for mesh generation
4  \\ / O peration |
5  \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6  \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of cfMesh.
10 
11  cfMesh is free software; you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by the
13  Free Software Foundation; either version 3 of the License, or (at your
14  option) any later version.
15 
16  cfMesh 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 cfMesh. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "error.H"
29 #include "polyMeshGenModifier.H"
30 #include "edgeExtractor.H"
31 #include "meshSurfaceEngine.H"
33 #include "meshSurfaceOptimizer.H"
34 #include "meshOctree.H"
35 #include "triSurf.H"
36 #include "triSurfModifier.H"
37 #include "helperFunctions.H"
38 #include "DynList.H"
39 #include "labelPair.H"
40 #include "labelledScalar.H"
41 #include "labelledPoint.H"
42 #include "refLabelledPoint.H"
43 #include "HashSet.H"
44 #include "triSurfacePartitioner.H"
46 
47 # ifdef USE_OMP
48 #include <omp.h>
49 # endif
50 
51 //#define DEBUGEdgeExtractor
52 
53 namespace Foam
54 {
55 
56 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
57 
59 {
60  otherFacePatch_.clear();
61 
62  const labelList& fPatches = extractor_.facePatch_;
63 
64  if( Pstream::parRun() )
65  {
67  const VRWGraph& edgeFaces = mse.edgeFaces();
68  const Map<label>& otherProc = mse.otherEdgeFaceAtProc();
69  const Map<label>& globalToLocal =
71 
72  //- create communication matrix
73  std::map<label, labelLongList> exchangeData;
74  const DynList<label>& neiProcs = mse.beNeiProcs();
75  forAll(neiProcs, procI)
76  exchangeData.insert
77  (
78  std::make_pair(neiProcs[procI], labelLongList())
79  );
80 
81  forAllConstIter(Map<label>, globalToLocal, it)
82  {
83  const label beI = it();
84 
85  if( edgeFaces.sizeOfRow(beI) == 1 )
86  {
87  labelLongList& dts = exchangeData[otherProc[beI]];
88  //- send data as follows:
89  //- 1. global edge label
90  //- 2. patch of the attached boundary face
91  dts.append(it.key());
92  dts.append(fPatches[edgeFaces(beI, 0)]);
93  }
94  }
95 
96  labelLongList receivedData;
97  help::exchangeMap(exchangeData, receivedData);
98 
99  label counter(0);
100  while( counter < receivedData.size() )
101  {
102  const label beI = globalToLocal[receivedData[counter++]];
103  const label fPatch = receivedData[counter++];
104 
105  otherFacePatch_.insert(beI, fPatch);
106  }
107  }
108 }
109 
111 {
112  if( newOtherFacePatchPtr_ )
113  return;
114 
115  if( !newBoundaryPatchesPtr_ )
117  (
118  "void edgeExtractor::faceEvaluator::"
119  "calculateNeiPatchesParallelNewPatches()"
120  ) << "newBoundaryPatchesPtr_ are NULL" << exit(FatalError);
121 
122  newOtherFacePatchPtr_ = new Map<label>();
123  Map<label>& otherFacePatch = *newOtherFacePatchPtr_;
124 
125  const labelList& fPatches = *newBoundaryPatchesPtr_;
126 
127  if( Pstream::parRun() )
128  {
129  const meshSurfaceEngine& mse = extractor_.surfaceEngine();
130  const VRWGraph& edgeFaces = mse.edgeFaces();
131  const Map<label>& otherProc = mse.otherEdgeFaceAtProc();
132  const Map<label>& globalToLocal =
134 
135  //- create communication matrix
136  std::map<label, labelLongList> exchangeData;
137  const DynList<label>& neiProcs = mse.beNeiProcs();
138  forAll(neiProcs, procI)
139  exchangeData.insert
140  (
141  std::make_pair(neiProcs[procI], labelLongList())
142  );
143 
144  forAllConstIter(Map<label>, globalToLocal, it)
145  {
146  const label beI = it();
147 
148  if( edgeFaces.sizeOfRow(beI) == 1 )
149  {
150  labelLongList& dts = exchangeData[otherProc[beI]];
151  //- send data as follows:
152  //- 1. global edge label
153  //- 2. patch of the attached boundary face
154  dts.append(it.key());
155  dts.append(fPatches[edgeFaces(beI, 0)]);
156  }
157  }
158 
159  labelLongList receivedData;
160  help::exchangeMap(exchangeData, receivedData);
161 
162  label counter(0);
163  while( counter < receivedData.size() )
164  {
165  const label beI = globalToLocal[receivedData[counter++]];
166  const label fPatch = receivedData[counter++];
167 
168  otherFacePatch.insert(beI, fPatch);
169  }
170  }
171 }
172 
174 (
175  const label bfI,
176  DynList<label>& neiFaces
177 ) const
178 {
179  const meshSurfaceEngine& mse = extractor_.surfaceEngine();
180 
181  const VRWGraph& faceEdges = mse.faceEdges();
182  const VRWGraph& edgeFaces = mse.edgeFaces();
183 
184  neiFaces.setSize(faceEdges.sizeOfRow(bfI));
185 
186  forAllRow(faceEdges, bfI, feI)
187  {
188  const label beI = faceEdges(bfI, feI);
189 
190  if( edgeFaces.sizeOfRow(beI) == 2 )
191  {
192  neiFaces[feI] = edgeFaces(beI, 0);
193  if( neiFaces[feI] == bfI )
194  neiFaces[feI] = edgeFaces(beI, 1);
195  }
196  else
197  {
198  neiFaces[feI] = -1;
199  }
200  }
201 }
202 
204 (
205  const label bfI,
206  DynList<label>& neiProcs
207 ) const
208 {
209  const meshSurfaceEngine& mse = extractor_.surfaceEngine();
210 
211  const VRWGraph& faceEdges = mse.faceEdges();
212 
213  neiProcs.setSize(faceEdges.sizeOfRow(bfI));
214  neiProcs = Pstream::myProcNo();
215 
216  if( Pstream::parRun() )
217  {
218  const Map<label>& otherFaceProc = mse.otherEdgeFaceAtProc();
219 
220  forAllRow(faceEdges, bfI, feI)
221  {
222  const label beI = faceEdges(bfI, feI);
223 
224  const Map<label>::const_iterator it = otherFaceProc.find(beI);
225 
226  if( it != otherFaceProc.end() )
227  neiProcs[feI] = it();
228  }
229  }
230 }
231 
233 (
234  const label bfI,
235  const labelList& fPatches,
236  const Map<label>& otherFacePatch,
237  DynList<label> &neiPatches
238 ) const
239 {
240  const meshSurfaceEngine& mse = extractor_.surfaceEngine();
241 
242  const VRWGraph& faceEdges = mse.faceEdges();
243  const VRWGraph& edgeFaces = mse.edgeFaces();
244 
245  neiPatches.setSize(faceEdges.sizeOfRow(bfI));
246 
247  forAllRow(faceEdges, bfI, feI)
248  {
249  const label beI = faceEdges(bfI, feI);
250 
251  if( edgeFaces.sizeOfRow(beI) == 2 )
252  {
253  label nei = edgeFaces(beI, 0);
254  if( nei == bfI )
255  nei = edgeFaces(beI, 1);
256 
257  neiPatches[feI] = fPatches[nei];
258  }
259  else if( Pstream::parRun() && (edgeFaces.sizeOfRow(beI) == 1) )
260  {
261  neiPatches[feI] = otherFacePatch[beI];
262  }
263  }
264 }
265 
267 (
268  const DynList<label>& neiPatches,
269  const label currentPatch
270 )
271 {
272  //- find indices of all neighbour patches
273  DynList<label> allNeiPatches;
274  forAll(neiPatches, i)
275  allNeiPatches.appendIfNotIn(neiPatches[i]);
276 
277  if( (allNeiPatches.size() == 1) && (allNeiPatches[0] == currentPatch) )
278  return currentPatch;
279 
280  //- counter the number of neighbours in a patch
281  Map<label> nNeiInPatch(allNeiPatches.size());
282  forAll(allNeiPatches, i)
283  nNeiInPatch.insert(allNeiPatches[i], 0);
284  forAll(neiPatches, eI)
285  ++nNeiInPatch[neiPatches[eI]];
286 
287  label newPatch = -1;
288  label nNeiEdges(0);
289  forAllConstIter(Map<label>, nNeiInPatch, it)
290  {
291  if( it() > nNeiEdges )
292  {
293  newPatch = it.key();
294  nNeiEdges = it();
295  }
296  else if
297  (
298  (it() == nNeiEdges) && (it.key() == currentPatch)
299  )
300  {
301  newPatch = it.key();
302  }
303  }
304 
305  //- do not swap if the situation allows for more than one edge
306  //- shared with faces in other patches than the dominant one
307  if( nNeiEdges < (neiPatches.size() - 1) )
308  return currentPatch;
309 
310  //- do not swap if the best face is in the current patch
311  if( (newPatch < 0) || (newPatch == currentPatch) )
312  return currentPatch;
313 
314  //- check whether the edges shared ith the neighbour patch form
315  //- a singly linked chain
317  sharedEdge.setSize(neiPatches.size());
318  sharedEdge = false;
319 
320  forAll(neiPatches, eI)
321  if( neiPatches[eI] == newPatch )
322  sharedEdge[eI] = true;
323 
325  return newPatch;
326 
327  return currentPatch;
328 }
329 
330 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
331 
333 :
334  extractor_(ee),
335  otherFacePatch_(),
336  newBoundaryPatchesPtr_(NULL),
337  newOtherFacePatchPtr_(NULL)
338 {
339  if( Pstream::parRun() )
341 }
342 
343 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
344 
346 {
347  deleteDemandDrivenData(newOtherFacePatchPtr_);
348 }
349 
350 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
351 
353 (
354  const labelList& newBoudaryPatches
355 )
356 {
357  newBoundaryPatchesPtr_ = &newBoudaryPatches;
358 
359  if( Pstream::parRun() )
360  calculateNeiPatchesParallelNewPatches();
361 }
362 
364 (
365  const label bfI,
366  DynList<label>& neiPatches
367 ) const
368 {
369  neiPatchesOverEdges
370  (
371  bfI,
372  extractor_.facePatch_,
373  otherFacePatch_,
374  neiPatches
375  );
376 }
377 
379 {
380  //- get neighbour patches over edges
381  DynList<label> neiPatches;
382  neiPatchesOverEdges
383  (
384  bfI,
385  extractor_.facePatch_,
386  otherFacePatch_,
387  neiPatches
388  );
389 
390  return bestPatchTopological(neiPatches, extractor_.facePatch_[bfI]);
391 }
392 
394 (
395  const label bfI
396 ) const
397 {
398  const label patchI = newBoundaryPatchesPtr_->operator[](bfI);
399 
400  if( patchI != extractor_.facePatch_[bfI] )
401  {
402  DynList<label> newNeiPatches, oldNeiPatches;
403  neiPatchesOverEdges
404  (
405  bfI,
406  *newBoundaryPatchesPtr_,
407  *newOtherFacePatchPtr_,
408  newNeiPatches
409  );
410 
411  neiPatchesOverEdges
412  (
413  bfI,
414  extractor_.facePatch_,
415  otherFacePatch_,
416  oldNeiPatches
417  );
418 
419  DynList<label> neiFaces, neiProcs;
420  neiFacesOverEdges(bfI, neiFaces);
421  neiFacesProcs(bfI, neiProcs);
422 
423  forAll(neiFaces, eI)
424  {
425  const label origPatchI = oldNeiPatches[eI];
426  const label newPatchI = newNeiPatches[eI];
427 
428  if( neiFaces[eI] > bfI )
429  {
430  if( newPatchI != origPatchI )
431  newNeiPatches[eI] = origPatchI;
432  }
433  else if( neiFaces[eI] < 0 )
434  {
435  if( neiProcs[eI] > Pstream::myProcNo() )
436  newNeiPatches[eI] = origPatchI;
437  }
438  }
439 
440  return bestPatchTopological(newNeiPatches, patchI);
441  }
442 
443  return patchI;
444 }
445 
446 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
447 
449 {
450  const labelHashSet& corners = partitioner_.corners();
451 
452  const labelList& facePatch = extractor_.facePatch_;
453 
454  typedef Map<label> mapType;
455 
456  const meshSurfaceEngine& mse = extractor_.surfaceEngine();
457  const faceList::subList& bFaces = mse.boundaryFaces();
458  const pointFieldPMG& points = mse.points();
459  const labelList& bp = mse.bp();
460  const VRWGraph& pointFaces = mse.pointFaces();
461  const labelList& globalLabel = mse.globalBoundaryPointLabel();
462  const mapType& globalToLocal = mse.globalToLocalBndPointAddressing();
463  const VRWGraph& bpAtProcs = mse.bpAtProcs();
464  const DynList<label>& neiProcs = mse.bpNeiProcs();
465 
466  typedef std::map<label, LongList<labelledPoint> > exchangeMapType;
467  exchangeMapType exchangeData;
468  forAll(neiProcs, i)
469  exchangeData[neiProcs[i]].clear();
470 
471  faceMap_.clear();
472  faceAtProc_.clear();
473  facePatches_.clear();
474 
475  forAllConstIter(mapType, globalToLocal, it)
476  {
477  const label bpI = it();
478 
479  if( corners.found(bpI) )
480  {
481  forAllRow(bpAtProcs, bpI, i)
482  {
483  const label neiProc = bpAtProcs(bpI, i);
484 
485  if( neiProc == Pstream::myProcNo() )
486  continue;
487 
488  LongList<labelledPoint>& dts = exchangeData[neiProc];
489 
490  //- data is send in the ollowing form
491  //- 1. globsl label of the current point
492  //- 2. number of faces attached to the point
493  //- 3. for each face send its patch, number of points and point
494  dts.append(labelledPoint(it.key(), vector::zero));
495  dts.append
496  (
497  labelledPoint(pointFaces.sizeOfRow(bpI), vector::zero)
498  );
499  forAllRow(pointFaces, bpI, i)
500  {
501  const face& bf = bFaces[pointFaces(bpI, i)];
502  dts.append
503  (
505  (
506  facePatch[pointFaces(bpI, i)],
508  )
509  );
511 
513  forAll(bf, pI)
514  {
515  const labelledPoint lp
516  (
517  globalLabel[bp[bf[bpI]]],
518  points[bf[pI]]
519  );
520 
521  dts.append(lp);
522  lpf.append(lp);
523  }
524 
525  faceMap_[bpI].append(lpf);
526  faceAtProc_[bpI].append(Pstream::myProcNo());
527  facePatches_[bpI].append(facePatch[pointFaces(bpI, i)]);
528  }
529  }
530  }
531  }
532 
533  std::map<label, List<labelledPoint> > receivedDataMap;
534  help::exchangeMap(exchangeData, receivedDataMap);
535 
536  for
537  (
538  std::map<label, List<labelledPoint> >::const_iterator it=receivedDataMap.begin();
539  it!=receivedDataMap.end();
540  ++it
541  )
542  {
543  const label procI = it->first;
544  const List<labelledPoint>& receivedData = it->second;
545 
546  for(label i=0;i<receivedData.size();)
547  {
548  const label bpI = globalToLocal[receivedData[i++].pointLabel()];
549 
550  const label nFaces = receivedData[i++].pointLabel();
551 
552  for(label fI=0;fI<nFaces;++fI)
553  {
554  const label patchI = receivedData[i++].pointLabel();
555  const label size = receivedData[i++].pointLabel();
556 
557  DynList<labelledPoint> lpf(size);
558  forAll(lpf, pI)
559  lpf[pI] = receivedData[i++];
560 
561  faceMap_[bpI].append(lpf);
562  faceAtProc_[bpI].append(procI);
563  facePatches_[bpI].append(patchI);
564  }
565  }
566  }
567 
568  //- srot the faces in the counter-clockwise order
569  for
570  (
571  std::map<label, DynList<label> >::iterator it=faceAtProc_.begin();
572  it!=faceAtProc_.end();
573  ++it
574  )
575  {
576  const label bpI = it->first;
577 
578  DynList<label>& faceProc = it->second;
579  DynList<label>& fPatches = facePatches_[bpI];
580  DynList<DynList<labelledPoint, 6> >& pFaces = faceMap_[bpI];
581 
582  forAll(pFaces, i)
583  {
584  const DynList<labelledPoint, 6>& lpf = pFaces[i];
585 
586  label pos(-1);
587  forAll(lpf, pI)
588  if( lpf[i].pointLabel() == globalLabel[bpI] )
589  {
590  pos = pI;
591  break;
592  }
593 
594  for(label j=i+2;j<pFaces.size();++j)
595  {
596  const DynList<labelledPoint, 6>& olpf = pFaces[j];
597 
598  if( olpf.contains(lpf[lpf.rcIndex(pos)]) )
599  {
600  label helper = faceProc[j];
601  faceProc[j] = faceProc[i+1];
602  faceProc[i+1] = helper;
603 
604  helper = fPatches[j];
605  fPatches[j] = fPatches[i+1];
606  fPatches[i+1] = helper;
607 
608  DynList<labelledPoint, 6> lpfHelper;
609  lpfHelper = pFaces[j];
610  pFaces[j] = pFaces[i+1];
611  pFaces[i+1] = lpfHelper;
612  }
613  }
614  }
615  }
616 }
617 
619 (
620  const label bpI,
622 ) const
623 {
624  const meshSurfaceEngine& mse = extractor_.surfaceEngine();
625  const faceList::subList& bFaces = mse.boundaryFaces();
626  const VRWGraph& pointFaces = mse.pointFaces();
627  const VRWGraph& pointInFace = mse.pointInFaces();
628 
629  pFaces = pointFaces[bpI];
630 
631  forAll(pFaces, i)
632  {
633  const face& bf = bFaces[pFaces[i]];
634  const label pos = pointFaces.containsAtPosition(bpI, pFaces[i]);
635 
636  const edge e = bf.faceEdge(bf.rcIndex(pointInFace(bpI, pos)));
637 
638  for(label j=i+2;j<pFaces.size();++j)
639  {
640  if( bFaces[pFaces[j]].which(e.start()) >= 0 )
641  {
642  label bfJ = pFaces[i+1];
643  pFaces[i+1] = pFaces[j];
644  pFaces[j] = bfJ;
645  }
646  }
647  }
648 }
649 
650 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
651 
653 (
654  const edgeExtractor& ee,
655  const meshSurfacePartitioner& mPart
656 )
657 :
658  extractor_(ee),
659  partitioner_(mPart),
660  faceMap_(),
661  facePatches_(),
662  faceAtProc_()
663 {
664  if( Pstream::parRun() )
665  createParallelAddressing();
666 }
667 
668 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
669 
671 {}
672 
673 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
674 
676 (
677  labelList& newBoundaryPatches
678 )
679 {
680  const meshOctree& mo = extractor_.meshOctree_;
681 
682  const labelHashSet& corners = partitioner_.corners();
683 
684  const meshSurfaceEngine& mse = extractor_.surfaceEngine();
685  const labelList& bPoints = mse.boundaryPoints();
686  const pointFieldPMG& points = mse.points();
687  const faceList::subList& bFaces = mse.boundaryFaces();
688 
689  forAllConstIter(labelHashSet, corners, it)
690  {
691  const point& p = points[bPoints[it.key()]];
692 
693  if( faceMap_.find(it.key()) == faceMap_.end() )
694  {
695  const labelList& facePatch = extractor_.facePatch_;
696  Info << "Checking corner " << it.key() << endl;
697 
698  //- get faces attached to this point
699  //- sorted in the counter-clocwise order
701  sortedFacesAtPoint(it.key(), pFaces);
702 
703  Info << "Faces at corner " << pFaces << endl;
704 
705  //- find feature edges attached to the point
706  DynList<labelPair> edgePatches;
707  DynList<label> edgeIndex;
708  forAll(pFaces, i)
709  {
710  const label patch0 = facePatch[pFaces[i]];
711  const label patch1 = facePatch[pFaces[pFaces.fcIndex(i)]];
712 
713  if( patch0 != patch1 )
714  {
715  edgeIndex.append(i);
716  edgePatches.append(labelPair(patch0, patch1));
717  }
718  }
719 
720  Info << "Edge patches " << edgePatches << endl;
721  Info << "Edge indices " << edgeIndex << endl;
722 
723  //- find the best aligned feature edge to the feature edge
724  DynList<label> bestEdgeIndices(edgePatches.size());
725  forAll(edgePatches, i)
726  {
727  const label patch0 = edgePatches[i].first();
728  const label patch1 = edgePatches[i].second();
730  patches[0] = patch0;
731  patches[1] = patch1;
732 
733  //- find the proection of the first point onto the feature edge
734  point mps;
735  scalar dSqS;
736  mo.findNearestPointToPatches(mps, dSqS, p, patches);
737 
738  scalar bestAlignment(0.0);
739  label bestEdgeIndex(-1);
740 
741  forAll(pFaces, pfI)
742  {
743  const face& bf = bFaces[pFaces[pfI]];
744 
745  const label pos = bf.which(bPoints[it.key()]);
746 
747  const point& pe = points[bf[bf.rcIndex(pos)]];
748 
749  //- calculate the vector of current edge
750  vector ev = pe - p;
751  ev /= (mag(ev) + VSMALL);
752 
753  //- project the endpoint onto the feature edge
754  point mpe;
755  scalar dSqE;
756  mo.findNearestPointToPatches(mpe, dSqE, pe, patches);
757 
758  vector fv = mpe - mps;
759  fv /= (mag(fv) + VSMALL);
760 
761  //- calculate alignment metrix between the current edge
762  //- and the feature edge
763  const scalar align = 0.5 * (1.0 + (ev & fv));
764 
765  if( align > bestAlignment )
766  {
767  bestAlignment = align;
768  bestEdgeIndex = pfI;
769  }
770  }
771 
772  bestEdgeIndices[i] = bestEdgeIndex;
773  }
774 
775  Info << "\nPatches of edges at corner " << it.key()
776  << " are " << edgePatches << endl;
777  Info << "Orig edge indices " << edgeIndex << endl;
778  Info << "New edge indices " << bestEdgeIndices << endl;
779 
780  DynList<label> newFacePatches(pFaces.size());
781  forAll(bestEdgeIndices, i)
782  {
783  const label patch = edgePatches[i].first();
784  label index = bestEdgeIndices[i];
785 
786  while( index != bestEdgeIndices[bestEdgeIndices.fcIndex(i)] )
787  {
788  newFacePatches[index] = patch;
789  index = (index + 1) % pFaces.size();
790  }
791  }
792 
793  bool allPatchesRemain(true);
794  forAll(edgePatches, i)
795  if( !newFacePatches.contains(edgePatches[i].first()) )
796  {
797  allPatchesRemain = false;
798  break;
799  }
800 
801  Info << "New patches at point" << newFacePatches << endl;
802  if( allPatchesRemain )
803  {
804  forAll(pFaces, i)
805  newBoundaryPatches[pFaces[i]] = newFacePatches[i];
806  }
807  }
808  else
809  {
810 
811  }
812  }
813 }
814 
815 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
816 
818 {
819  bool changed(false);
820 
821  const triSurf& surf = meshOctree_.surface();
822  const pointField& sp = surf.points();
823 
824  //- create the surface partitioner and find the corners on the surface mesh
825  triSurfacePartitioner surfPartitioner(surf);
826 
827  const labelList& corners = surfPartitioner.corners();
828 
829  Map<label> surfacePointToCorner;
830  forAll(corners, cornerI)
831  surfacePointToCorner.insert(corners[cornerI], cornerI);
832 
833  List<labelledScalar> nearestPoint
834  (
835  corners.size(),
836  labelledScalar(0, VGREAT)
837  );
838 
839  //- calculate the search range
840  const meshSurfaceEngine& mse = this->surfaceEngine();
841  const pointFieldPMG& points = mesh_.points();
842  const labelList& bPoints = mse.boundaryPoints();
843  const labelList& bp = mse.bp();
844  const faceList::subList& bFaces = mse.boundaryFaces();
845 
846  scalarList searchRange(bPoints.size(), 0.0);
847  forAll(bFaces, bfI)
848  {
849  const face& bf = bFaces[bfI];
850  const point c = bf.centre(points);
851 
852  forAll(bf, pI)
853  {
854  const scalar d = 2.0 * Foam::mag(c - points[bf[pI]]);
855  const label bpI = bp[bf[pI]];
856 
857  searchRange[bpI] = Foam::max(d, searchRange[bpI]);
858  }
859  }
860 
861  if( Pstream::parRun() )
862  {
863  const VRWGraph& bpAtProcs = mse.beAtProcs();
864  const DynList<label>& bpNeiProcs = mse.bpNeiProcs();
865  const Map<label>& globalToLocal =
867 
868  std::map<label, LongList<labelledScalar> > exchangeData;
869  forAll(bpNeiProcs, i)
870  exchangeData.insert
871  (
872  std::make_pair(bpNeiProcs[i], LongList<labelledScalar>())
873  );
874 
875  forAllConstIter(Map<label>, globalToLocal, iter)
876  {
877  const label bpI = iter();
878 
879  forAllRow(bpAtProcs, bpI, i)
880  {
881  const label neiProc = bpAtProcs(bpI, i);
882 
883  if( neiProc == Pstream::myProcNo() )
884  continue;
885 
886  exchangeData[neiProc].append
887  (
888  labelledScalar(iter.key(), searchRange[bpI])
889  );
890  }
891  }
892 
893  LongList<labelledScalar> receivedData;
894  help::exchangeMap(exchangeData, receivedData);
895 
896  forAll(receivedData, i)
897  {
898  const label bpI = globalToLocal[receivedData[i].scalarLabel()];
899 
900  searchRange[bpI] =
901  Foam::max(searchRange[bpI], receivedData[i].value());
902  }
903  }
904 
905  DynList<label> containedTriangles;
906  # ifdef USE_OMP
907  # pragma omp parallel for schedule(dynamic, 40) private(containedTriangles)
908  # endif
909  forAll(bPoints, bpI)
910  {
911  const point& p = points[bPoints[bpI]];
912  const scalar s = searchRange[bpI];
913 
914  boundBox bb(p-vector(s, s, s), p+vector(s, s, s));
915  meshOctree_.findTrianglesInBox(bb, containedTriangles);
916 
917  //- find the nearest corner on the surface mesh
918  forAll(containedTriangles, i)
919  {
920  const labelledTri& tri = surf[containedTriangles[i]];
921 
922  forAll(tri, pI)
923  {
924  const label spI = tri[pI];
925  if( !surfacePointToCorner.found(spI) )
926  continue;
927 
928  const label cornerI = surfacePointToCorner[spI];
929 
930  const scalar d = Foam::magSqr(sp[spI] - points[bPoints[bpI]]);
931 
932  if( nearestPoint[cornerI].value() > d )
933  {
934  //- update the nearest point to the found corner
935  # ifdef USE_OMP
936  # pragma omp critical
937  # endif
938  {
939  nearestPoint[cornerI] = labelledScalar(bpI, d);
940  }
941  }
942  }
943  }
944  }
945 
946  # ifdef DEBUGEdgeExtractor
947  Info << "Nearest points to corners " << nearestPoint << endl;
948  # endif
949 
950  return changed;
951 }
952 
954 {
955  bool changed(false);
956 
957  # ifdef DEBUGEdgeExtractor
958  const triSurf* surfPtr = surfaceWithPatches();
959  surfPtr->writeSurface("checkCornersBefore.fms");
960  deleteDemandDrivenData(surfPtr);
961  # endif
962 
963  const pointFieldPMG& points = mesh_.points();
964  const meshSurfaceEngine& mse = this->surfaceEngine();
965  const labelList& bPoints = mse.boundaryPoints();
966  const faceList::subList& bFaces = mse.boundaryFaces();
967  const labelList& bp = mse.bp();
968  const edgeList& edges = mse.edges();
969  const VRWGraph& pointFaces = mse.pointFaces();
970  const VRWGraph& faceEdges = mse.faceEdges();
971  const VRWGraph& edgeFaces = mse.edgeFaces();
972 
973  const triSurfacePartitioner& sPartitioner = this->partitioner();
974  const List<labelHashSet>& patchPatches = sPartitioner.patchPatches();
975 
976  //- allocate a copy of boundary patches
977  labelList newBoundaryPatches(facePatch_.size());
978 
979  label nCorrected;
980  Map<label> otherProcNewPatch;
981 
982  label nIteration(0);
983 
984  do
985  {
986  nCorrected = 0;
987  newBoundaryPatches = facePatch_;
988 
989  //- check whether there exist situations where a boundary face
990  //- is surrounded by more faces in different patches than the
991  //- faces in the current patch
992  if( Pstream::parRun() )
993  {
995  (
996  otherProcNewPatch,
997  &newBoundaryPatches
998  );
999  }
1000 
1001  //- update the information which edges are assigned as feature edges
1002  meshSurfacePartitioner mPart(mse, newBoundaryPatches);
1003 
1004  //- find corners in the current constelation
1005  const labelHashSet& corners = mPart.corners();
1006  const VRWGraph& pPatches = mPart.pointPatches();
1007 
1008  typedef std::map<label, label> mapType;
1009  typedef std::map<label, std::pair<point, scalar> > distMapType;
1010 
1011  mapType cornerIndex;
1012  distMapType nearestToCorner;
1013 
1014  # ifdef DEBUGEdgeExtractor
1015  Info << "Finding corners " << endl;
1016  # endif
1017 
1018  //- find nearest corners in the surface mesh
1019  forAllConstIter(labelHashSet, corners, it)
1020  {
1021  const label bpI = it.key();
1022  const DynList<label> neiPatches = pPatches[bpI];
1023 
1024  const point& p = points[bPoints[bpI]];
1025  point pMap;
1026  scalar dSq;
1027  label nsp;
1028 
1029  if( !meshOctree_.findNearestCorner(pMap, dSq, nsp, p, neiPatches) )
1030  {
1031  nsp = -1;
1032  meshOctree_.findNearestPointToPatches(pMap, dSq, p, neiPatches);
1033  }
1034 
1035  nearestToCorner[bpI] = std::make_pair(pMap, dSq);
1036  cornerIndex[bpI] = nsp;
1037  }
1038 
1039  std::map<label, DynList<label> > bpMappedAtSurfaceCorner;
1040  forAllConstIter(mapType, cornerIndex, mIt)
1041  {
1042  if( mIt->second < 0 )
1043  {
1044  //- the corner does not exist in the surface mesh
1045  //- this may be a situation where parts of the surface are in
1046  //- close proximity and are not topologically connected
1047  Warning << "Should not get in here. Not implemented" << endl;
1048  }
1049  else
1050  {
1051  bpMappedAtSurfaceCorner[mIt->second].append(mIt->first);
1052  }
1053  }
1054 
1055  # ifdef DEBUGEdgeExtractor
1056  for
1057  (
1058  mapType::const_iterator mIt=bpMappedAtSurfaceCorner.begin();
1059  mIt!=bpMappedAtSurfaceCorner.end();
1060  ++mIt
1061  )
1062  if( mIt->second.size() > 1 )
1063  Info << "Surface corner " << mIt->first
1064  << " mapped mesh points " << mIt->second << endl;
1065  # endif
1066 
1067  //- for all edge nodes find their nearest counterparts in the surface
1068  # ifdef DEBUGEdgeExtractor
1069  Info << "Finding nearest edges" << endl;
1070  # endif
1071 
1072  const labelHashSet& featureEdge = mPart.featureEdges();
1073 
1074  distMapType nearestToEdgePoint;
1075  mapType edgePointIndex;
1076  std::map<std::pair<label, label>, labelLongList> edgesSharedByPatches;
1077 
1078  forAllConstIter(labelHashSet, featureEdge, it)
1079  {
1080  const label beI = it.key();
1081 
1082  //- get the patches bounded by this feature edge
1084 
1085  if( edgeFaces.sizeOfRow(beI) == 2 )
1086  {
1087  patches[0] = newBoundaryPatches[edgeFaces(beI, 0)];
1088  patches[1] = newBoundaryPatches[edgeFaces(beI, 1)];
1089  }
1090  else if( edgeFaces.sizeOfRow(beI) == 1 )
1091  {
1092  patches[0] = newBoundaryPatches[edgeFaces(beI, 0)];
1093  patches[1] = otherProcNewPatch[beI];
1094  }
1095 
1096  //- store the edge into the right group
1097  std::pair<label, label> patchPair
1098  (
1099  Foam::min(patches[0], patches[1]),
1100  Foam::max(patches[0], patches[1])
1101  );
1102  edgesSharedByPatches[patchPair].append(beI);
1103 
1104  //- check if some points have already been checked
1105  const edge& e = edges[beI];
1106  const label bps = bp[e.start()];
1107  const label bpe = bp[e.end()];
1108 
1110  if
1111  (
1112  corners.found(bps) &&
1113  (nearestToEdgePoint.find(bps) == nearestToEdgePoint.end())
1114  )
1115  checkPoints.append(bps);
1116 
1117  if
1118  (
1119  corners.found(bpe) &&
1120  (nearestToEdgePoint.find(bpe) == nearestToEdgePoint.end())
1121  )
1122  checkPoints.append(bpe);
1123 
1124  forAll(checkPoints, i)
1125  {
1126  const point& p = points[bPoints[checkPoints[i]]];
1127  point pMap;
1128  scalar dSq;
1129  label nse;
1130 
1131  if( !meshOctree_.findNearestEdgePoint(pMap, dSq, nse, p, patches) )
1132  {
1133  nse = -1;
1135  }
1136 
1137  nearestToEdgePoint[checkPoints[i]] = std::make_pair(pMap, dSq);
1138  edgePointIndex[checkPoints[i]] = nse;
1139  }
1140  }
1141 
1142  labelHashSet invalidFeatureEdges;
1143  for
1144  (
1145  std::map<std::pair<label, label>, labelLongList>::const_iterator mIt=edgesSharedByPatches.begin();
1146  mIt!=edgesSharedByPatches.end();
1147  ++mIt
1148  )
1149  {
1150  const bool validConnection =
1151  patchPatches[mIt->first.first].found(mIt->first.second);
1152 
1153  # ifdef DEBUGEdgeExtractor
1154  Info << "Patches " << mIt->first.first
1155  << " and " << mIt->first.second
1156  << " share " << mIt->second
1157  << " edges " << validConnection << endl;
1158  # endif
1159 
1160  if( !validConnection )
1161  {
1162  //- find surface facets in the vicinity of the edge
1163  //- and check whether there exist various disconnected surface
1164  //- parts in the vicinity of this group of edge
1165 
1166  const DynList<label>& invalidEdges = mIt->second;
1167 
1168  forAll(invalidEdges, i)
1169  invalidFeatureEdges.insert(invalidEdges[i]);
1170  }
1171  }
1172 
1173  # ifdef DEBUGEdgeExtractor
1174  Info << "Invalid feature edges " << invalidFeatureEdges << endl;
1175  ::exit(0);
1176  # endif
1177 
1178  //- check the vicinity of the corner point and check whether
1179  //- it shall be replaced by some other point in the vicinity
1180  std::map<label, DynList<labelPair> > facesAtCornerNewPatches;
1181  forAllConstIter(distMapType, nearestToCorner, it)
1182  {
1183  const label bpI = it->first;
1184 
1185  //- find all points connected to the corner point via a face
1186  labelHashSet nearPoints;
1187  std::map<label, DynList<label> > facesContainingPoint;
1188  forAllRow(pointFaces, bpI, pfI)
1189  {
1190  const label bfI = pointFaces(bpI, pfI);
1191  const face& bf = bFaces[bfI];
1192 
1193  forAll(bf, pI)
1194  {
1195  nearPoints.insert(bf[pI]);
1196  facesContainingPoint[bf[pI]].append(bfI);
1197  }
1198  }
1199 
1200  # ifdef DEBUGEdgeExtractor
1201  forAllConstIter(labelHashSet, nearPoints, iterN)
1202  {
1203  Info << "Near point " << iterN.key() << endl;
1204  Info << "Faces containing near point are "
1205  << facesContainingPoint[iterN.key()] << endl;
1206  }
1207  # endif
1208 
1209  //- find the nearest point to the location where the corner
1210  //- shall be mapped onto the surface mesh
1211  label bestPoint(-1);
1212  scalar minDistSq(VGREAT);
1213  forAllConstIter(labelHashSet, nearPoints, iter)
1214  {
1215  const point& p = points[iter.key()];
1216 
1217  const scalar dSq = magSqr(p - nearestToCorner[bpI].first);
1218 
1219  if( dSq < minDistSq )
1220  {
1221  minDistSq = dSq;
1222  bestPoint = iter.key();
1223  }
1224  }
1225 
1226  if( bestPoint == bPoints[bpI] )
1227  {
1228  # ifdef DEBUGEdgeExtractor
1229  Info << "Current corner is nearest" << endl;
1230  # endif
1231 
1232  continue;
1233  }
1234 
1235  # ifdef DEBUGEdgeExtractor
1236  surfPtr = surfaceWithPatches(bpI);
1237  surfPtr->writeSurface
1238  (
1239  "corner_"+help::scalarToText(bpI)+
1240  "_iter_"+help::scalarToText(nIteration)+".fms"
1241  );
1242  deleteDemandDrivenData(surfPtr);
1243  Info << "Best candidate " << bestPoint << endl;
1244  # endif
1245 
1246  //- sort faces and edges at the corner in counter-clockwise order
1247  DynList<label> pFaces, pEdges;
1248 
1249  DynList<label> front;
1250  front.append(0);
1251 
1252  while( front.size() )
1253  {
1254  const label fI = front.removeLastElement();
1255  const label bfI = pointFaces(bpI, fI);
1256 
1257  pFaces.append(bfI);
1258 
1259  const face& bf = bFaces[bfI];
1260  const label pos = bf.which(bPoints[bpI]);
1261 
1262  const label beI = faceEdges(bfI, bf.rcIndex(pos));
1263 
1264  pEdges.append(beI);
1265 
1266  label nei = edgeFaces(beI, 0);
1267  if( nei == bfI )
1268  nei = edgeFaces(beI, 1);
1269 
1270  if( pFaces.contains(nei) || (nei < 0) )
1271  continue;
1272 
1273  front.append(pointFaces.containsAtPosition(bpI, nei));
1274  }
1275 
1276  # ifdef DEBUGEdgeExtractor
1277  Info << "Boundary point " << bpI
1278  << " pFaces " << pFaces
1279  << " pEdges " << pEdges << endl;
1280  forAll(pFaces, i)
1281  {
1282  Info << "Face " << pFaces[i] << " has nodes " << bFaces[pFaces[i]] << endl;
1283  Info << "Face " << pFaces[i] << " is in patch " << facePatch_[pFaces[i]] << endl;
1284  Info << "Edge " << pEdges[i] << " has nodes " << edges[pEdges[i]] << endl;
1285  }
1286  # endif
1287 
1288  //- find the best fitting edge to move towards the corner
1289  label bestEdge(-1);
1290  scalar bestAlignment(0.0);
1291 
1292  vector dv = it->second.first - points[bPoints[bpI]];
1293  dv /= (mag(dv) + VSMALL);
1294 
1295  if( facesContainingPoint[bestPoint].size() == 1 )
1296  {
1297  const label bfI = facesContainingPoint[bestPoint][0];
1298 
1299  //- only the edges of this face can be candidates
1300  forAll(pEdges, i)
1301  {
1302  const label beI = pEdges[i];
1303  const edge& e = edges[pEdges[i]];
1304 
1305  if( !(edgeFaces(beI, 0) == bfI || edgeFaces(beI, 1) == bfI) )
1306  continue;
1307 
1308  vector ev
1309  (
1310  points[e.otherVertex(bPoints[bpI])] - points[bPoints[bpI]]
1311  );
1312  ev /= (mag(ev) + VSMALL);
1313 
1314  const scalar metric = 0.5 * (1.0 + (dv & ev));
1315 
1316  if( metric > bestAlignment )
1317  {
1318  bestAlignment = metric;
1319  bestEdge = pEdges[i];
1320  }
1321  }
1322  }
1323  else
1324  {
1325  //- the edge containing the best point is the candidate
1326  forAll(pEdges, i)
1327  {
1328  const edge& e = edges[pEdges[i]];
1329 
1330  if( e.otherVertex(bestPoint) != -1 )
1331  {
1332  //- select the edge which contains best fitting point
1333  bestEdge = pEdges[i];
1334  break;
1335  }
1336  }
1337  }
1338 
1339  # ifdef DEBUGEdgeExtractor
1340  Info << "Best edge " << bestEdge
1341  << " has alignment " << bestAlignment << endl;
1342  # endif
1343 
1344  //- find groups of sorted faces at this corner which are bounded by
1345  //- existing feature edges and the new candidate
1346  DynList<label> faceInGroup(pFaces.size(), -1);
1347  label groupI(0);
1348  forAll(pFaces, i)
1349  {
1350  if( faceInGroup[i] != -1 )
1351  continue;
1352 
1353  DynList<label> front;
1354  front.append(i);
1355  faceInGroup[i] = groupI;
1356 
1357  while( front.size() != 0 )
1358  {
1359  const label currIndex = front.removeLastElement();
1360 
1361  const label nbeI = pEdges[currIndex];
1362  const label pbeI = pEdges[pFaces.rcIndex(currIndex)];
1363  if( (nbeI != bestEdge) && !featureEdge.found(nbeI) )
1364  {
1365  const label nfI = pFaces.fcIndex(currIndex);
1366 
1367  if( faceInGroup[nfI] == -1 )
1368  {
1369  faceInGroup[nfI] = groupI;
1370  front.append(nfI);
1371  }
1372  }
1373  else if( (pbeI != bestEdge) && !featureEdge.found(pbeI) )
1374  {
1375  const label pfI = pFaces.rcIndex(currIndex);
1376 
1377  if( faceInGroup[pfI] == -1 )
1378  {
1379  faceInGroup[pfI] = groupI;
1380  front.append(pfI);
1381  }
1382  }
1383  }
1384 
1385  ++groupI;
1386  }
1387 
1388  # ifdef DEBUGEdgeExtractor
1389  Info << "faceInGroup " << faceInGroup << endl;
1390  # endif
1391 
1392  //- check which group of faces shall change patch in order to make
1393  //- the best fitting edge a feature edge
1394  DynList<labelPair> groupPairs, groupPatches;
1395  labelPair groupsForChanging(-1, -1);
1396  forAll(pEdges, i)
1397  {
1398  const label beI = pEdges[i];
1399 
1400  if( beI == bestEdge )
1401  {
1402  label pos = pFaces.containsAtPosition(edgeFaces(beI, 0));
1403  groupsForChanging.first() = faceInGroup[pos];
1404  pos = pFaces.containsAtPosition(edgeFaces(beI, 1));
1405  groupsForChanging.second() = faceInGroup[pos];
1406  }
1407  else if( featureEdge.found(beI) )
1408  {
1409  labelPair lp, lpp;
1410  label pos = pFaces.containsAtPosition(edgeFaces(beI, 0));
1411  lpp.first() = facePatch_[pFaces[pos]];
1412  lp.first() = faceInGroup[pos];
1413  pos = pFaces.containsAtPosition(edgeFaces(beI, 1));
1414  lpp.second() = facePatch_[pFaces[pos]];
1415  lp.second() = faceInGroup[pos];
1416 
1417  groupPairs.append(lp);
1418  groupPatches.append(lpp);
1419  }
1420  }
1421 
1422  # ifdef DEBUGEdgeExtractor
1423  Info << "group pairs " << groupPairs << endl;
1424  Info << "Group patches " << groupPatches << endl;
1425  Info << "Groups for changing " << groupsForChanging << endl;
1426  # endif
1427 
1428  //- check which groups shall change their patch
1429  //- desired patches at the best edge are determined by finding
1430  //- the best alignment between the bestEdge and the feature edges
1431  scalar maxAlignment(0.0);
1432  label bestGroupsOfPatches(-1);
1433  forAll(groupPatches, i)
1434  {
1435  const labelPair& pp = groupPatches[i];
1436 
1437  const point& bes = points[edges[bestEdge].start()];
1438  const point& bee = points[edges[bestEdge].end()];
1439 
1441  patches[0] = pp.first();
1442  patches[1] = pp.second();
1443 
1444  point mps, mpe;
1445  scalar dSqS, dSqE;
1446  label nse;
1447 
1448  meshOctree_.findNearestEdgePoint(mps, dSqS, nse, bes, patches);
1449  meshOctree_.findNearestEdgePoint(mpe, dSqE, nse, bee, patches);
1450 
1451  const scalar align = 0.5 * (1.0 + ((bee - bes) & (mpe - mps)));
1452 
1453  if( align > maxAlignment )
1454  {
1455  maxAlignment = align;
1456  bestGroupsOfPatches = i;
1457  }
1458  }
1459 
1460  # ifdef DEBUGEdgeExtractor
1461  Info << "Best groups of patches " << bestGroupsOfPatches << endl;
1462  # endif
1463 
1464  //- assign new patches
1465  FixedList<label, 2> newPatchForGroup(-1);
1466  DynList<labelPair>& newPatchForFace = facesAtCornerNewPatches[bpI];
1467  forAll(groupPatches, i)
1468  {
1469  if( i == bestGroupsOfPatches )
1470  continue;
1471 
1472  const labelPair& gp = groupPairs[i];
1473  const labelPair& gpp = groupPatches[i];
1474 
1475  if
1476  (
1477  gp.first() == groupsForChanging.first() ||
1478  gp.first() == groupsForChanging.second()
1479  )
1480  {
1481  const label otherPatch = gpp.second();
1482 
1483  scalar Eold(0.0), Enew(0.0);
1484  forAll(faceInGroup, j)
1485  {
1486  if( faceInGroup[j] != gp.first() )
1487  continue;
1488 
1489  const label bfI = pFaces[j];
1490 
1491  forAllRow(faceEdges, bfI, feI)
1492  {
1493  const label beI = faceEdges(bfI, feI);
1494 
1495  # ifdef DEBUGEdgeExtractor
1496  Info << "2. beI " << beI << endl;
1497  # endif
1498 
1499  const point& ps = points[edges[beI].start()];
1500  const point& pe = points[edges[beI].end()];
1501  const scalar magE = edges[beI].mag(points) + VSMALL;
1502 
1503  vector ev = pe - ps;
1504  ev /= magE;
1505 
1506  label nei = edgeFaces(beI, 0);
1507  if( nei == bfI )
1508  nei = edgeFaces(beI, 1);
1509 
1510  const label posNei = pFaces.containsAtPosition(nei);
1511  if
1512  (
1513  (posNei < 0) ||
1514  (faceInGroup[posNei] != faceInGroup[j])
1515  )
1516  {
1517  if( facePatch_[bfI] != facePatch_[nei] )
1518  {
1520  patches[0] = facePatch_[bfI];
1521  patches[1] = facePatch_[nei];
1522  //- calculate deformation energy
1523  //- of the old state
1524  point mps, mpe;
1525  scalar dSqS, dSqE;
1526 
1528  (
1529  mps,
1530  dSqS,
1531  ps,
1532  patches
1533  );
1535  (
1536  mpe,
1537  dSqE,
1538  pe,
1539  patches
1540  );
1541 
1542  vector fv = mpe - mps;
1543  fv /= (mag(fv) + VSMALL);
1544 
1545  scalar c = min(fv & ev, 1.0);
1546  c = max(-1.0, c);
1547  const scalar angle = acos(c);
1548 
1549  Eold +=
1550  1.0/magE * (dSqS + dSqE) + magE * angle;
1551  }
1552  if( otherPatch != facePatch_[nei] )
1553  {
1554  //- calculate deformation energy
1555  //- of the new state
1557  patches[0] = otherPatch;
1558  patches[1] = facePatch_[nei];
1559 
1560  point mps, mpe;
1561  scalar dSqS, dSqE;
1562 
1564  (
1565  mps,
1566  dSqS,
1567  ps,
1568  patches
1569  );
1571  (
1572  mpe,
1573  dSqE,
1574  pe,
1575  patches
1576  );
1577 
1578  vector fv = mpe - mps;
1579  fv /= (mag(fv) + VSMALL);
1580 
1581  scalar c = min(fv & ev, 1.0);
1582  c = max(-1.0, c);
1583  const scalar angle = acos(c);
1584 
1585  Enew +=
1586  1.0/magE * (dSqS + dSqE) + magE * angle;
1587  }
1588  }
1589  }
1590  }
1591 
1592  # ifdef DEBUGEdgeExtractor
1593  Info << "1. Eold " << Eold << " Enew " << Enew << endl;
1594  # endif
1595 
1596  if( Enew <= Eold )
1597  {
1598  newPatchForGroup[0] = otherPatch;
1599 
1600  forAll(faceInGroup, j)
1601  {
1602  if( faceInGroup[j] != gp.first() )
1603  continue;
1604 
1605  newPatchForFace.append
1606  (
1607  labelPair(pFaces[j], otherPatch)
1608  );
1609  }
1610  }
1611  }
1612  else if
1613  (
1614  gp.second() == groupsForChanging.first() ||
1615  gp.second() == groupsForChanging.second()
1616  )
1617  {
1618  const label otherPatch = gpp.first();
1619 
1620  scalar Eold(0.0), Enew(0.0);
1621  forAll(faceInGroup, j)
1622  {
1623  if( faceInGroup[j] != gp.second() )
1624  continue;
1625 
1626  const label bfI = pFaces[j];
1627 
1628  forAllRow(faceEdges, bfI, feI)
1629  {
1630  const label beI = faceEdges(bfI, feI);
1631 
1632  # ifdef DEBUGEdgeExtractor
1633  Info << "2. beI " << beI << endl;
1634  # endif
1635 
1636  const point& ps = points[edges[beI].start()];
1637  const point& pe = points[edges[beI].end()];
1638  const scalar magE = edges[beI].mag(points) + VSMALL;
1639 
1640  vector ev = pe - ps;
1641  ev /= magE;
1642 
1643  label nei = edgeFaces(beI, 0);
1644  if( nei == bfI )
1645  nei = edgeFaces(beI, 1);
1646 
1647  const label posNei = pFaces.containsAtPosition(nei);
1648  if
1649  (
1650  (posNei < 0) ||
1651  (faceInGroup[posNei] != faceInGroup[j])
1652  )
1653  {
1654  if( facePatch_[bfI] != facePatch_[nei] )
1655  {
1657  patches[0] = facePatch_[bfI];
1658  patches[1] = facePatch_[nei];
1659 
1660  //- calculate deformation energy
1661  //- of the old state
1662  point mps, mpe;
1663  scalar dSqS, dSqE;
1664 
1666  (
1667  mps,
1668  dSqS,
1669  ps,
1670  patches
1671  );
1673  (
1674  mpe,
1675  dSqE,
1676  pe,
1677  patches
1678  );
1679 
1680  vector fv = mpe - mps;
1681  fv /= (mag(fv) + VSMALL);
1682 
1683  scalar c = min(fv & ev, 1.0);
1684  c = max(-1.0, c);
1685  const scalar angle = acos(c);
1686 
1687  Eold +=
1688  1.0/magE * (dSqS + dSqE) + magE * angle;
1689  }
1690  if( otherPatch != facePatch_[nei] )
1691  {
1692  //- calculate deformation energy
1693  //- of the new state
1695  patches[0] = otherPatch;
1696  patches[1] = facePatch_[nei];
1697 
1698  point mps, mpe;
1699  scalar dSqS, dSqE;
1700 
1702  (
1703  mps,
1704  dSqS,
1705  ps,
1706  patches
1707  );
1709  (
1710  mpe,
1711  dSqE,
1712  pe,
1713  patches
1714  );
1715 
1716  vector fv = mpe - mps;
1717  fv /= (mag(fv) + VSMALL);
1718 
1719  scalar c = min(fv & ev, 1.0);
1720  c = max(-1.0, c);
1721  const scalar angle = acos(c);
1722 
1723  Enew +=
1724  1.0/magE * (dSqS + dSqE) + magE * angle;
1725  }
1726  }
1727  }
1728  }
1729 
1730  # ifdef DEBUGEdgeExtractor
1731  Info << "2. Eold " << Eold << " Enew " << Enew << endl;
1732  # endif
1733 
1734  if( Enew <= Eold )
1735  {
1736  newPatchForGroup[1] = otherPatch;
1737 
1738  forAll(faceInGroup, j)
1739  {
1740  if( faceInGroup[j] != gp.second() )
1741  continue;
1742 
1743  newPatchForFace.append
1744  (
1745  labelPair(pFaces[j], otherPatch)
1746  );
1747  }
1748  }
1749  }
1750  }
1751 
1752  # ifdef DEBUGEdgeExtractor
1753  Info << "New patches for boundary faces "
1754  << newPatchForFace << endl;
1755  # endif
1756  }
1757 
1758  labelHashSet changedPatch;
1759  typedef std::map<label, DynList<labelPair> > labelToPairMap;
1760  forAllConstIter(labelToPairMap, facesAtCornerNewPatches, it)
1761  {
1762  const DynList<labelPair>& lp = it->second;
1763  forAll(lp, i)
1764  {
1765  if( changedPatch.found(lp[i].first()) )
1766  FatalError << "Face " << lp[i].first()
1767  << " is already modified" << abort(FatalError);
1768 
1769  changedPatch.insert(lp[i].first());
1770 
1771  newBoundaryPatches[lp[i].first()] = lp[i].second();
1772  ++nCorrected;
1773  }
1774  }
1775 
1776  reduce(nCorrected, sumOp<label>());
1777 
1778  if( nCorrected )
1779  {
1780  changed = true;
1781  facePatch_ = newBoundaryPatches;
1782  }
1783 
1784  if( nIteration++ > 5 )
1785  {
1786  Info << "Too many iterations" << endl;
1787  break;
1788  }
1789 
1790  # ifdef DEBUGEdgeExtractor
1791  surfPtr = surfaceWithPatches();
1792  surfPtr->writeSurface
1793  (
1794  "checkCornersAfterIteration_"+help::scalarToText(nIteration)+".fms"
1795  );
1796  deleteDemandDrivenData(surfPtr);
1797  # endif
1798 
1799  } while( nCorrected != 0 );
1800 
1801  return changed;
1802 }
1803 
1804 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1805 
1806 } // End namespace Foam
1807 
1808 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::meshSurfaceEngine::bpAtProcs
const VRWGraph & bpAtProcs() const
processors which contain the vertex
Definition: meshSurfaceEngineI.H:451
Foam::meshSurfaceEngine::beAtProcs
const VRWGraph & beAtProcs() const
processors which contain the edges
Definition: meshSurfaceEngineI.H:530
Foam::meshSurfaceEngine::pointInFaces
const VRWGraph & pointInFaces() const
Definition: meshSurfaceEngineI.H:181
Foam::help::sharedEdge
edge sharedEdge(const faceType1 &f1, const faceType2 &f2)
return the edge shared by the faces
Definition: helperFunctionsTopologyManipulationI.H:343
Foam::meshSurfaceEngine::bp
const labelList & bp() const
Definition: meshSurfaceEngineI.H:64
Foam::triSurfacePartitioner
Definition: triSurfacePartitioner.H:53
Foam::edgeExtractor::checkCorners
bool checkCorners()
Definition: edgeExtractorCorners.C:953
Foam::LongList::append
void append(const T &e)
Append an element at the end of the list.
Definition: LongListI.H:265
triSurf.H
Foam::edgeExtractor::partitioner
const triSurfacePartitioner & partitioner() const
get the surface partitioner
Definition: edgeExtractor.C:480
Foam::Vector< scalar >::zero
static const Vector zero
Definition: Vector.H:80
Foam::edgeExtractor::faceEvaluator::faceEvaluator
faceEvaluator(const edgeExtractor &)
Construct from edgeExtractor.
Definition: edgeExtractorCorners.C:332
p
p
Definition: pEqn.H:62
Foam::edgeExtractor::surfaceWithPatches
const triSurf * surfaceWithPatches() const
Definition: edgeExtractor.C:2445
Foam::meshSurfaceEngine::globalToLocalBndEdgeAddressing
const Map< label > & globalToLocalBndEdgeAddressing() const
global boundary edge label to local label. Only for processor edges
Definition: meshSurfaceEngineI.H:510
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
triSurfacePartitioner.H
Foam::meshSurfaceEngine::globalBoundaryPointLabel
const labelList & globalBoundaryPointLabel() const
global boundary point label
Definition: meshSurfaceEngineI.H:410
Foam::triSurfPoints::points
const pointField & points() const
access to points
Definition: triSurfPointsI.H:44
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
Foam::face::faceEdge
edge faceEdge(const label n) const
Return n-th face edge.
Definition: faceI.H:110
Foam::Warning
messageStream Warning
Foam::help::scalarToText
word scalarToText(const scalar s)
convert the scalar value into text
Definition: helperFunctionsStringConversion.C:61
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::meshSurfaceEngine::bpNeiProcs
const DynList< label > & bpNeiProcs() const
communication matrix for sending point data
Definition: meshSurfaceEngineI.H:470
Foam::face::centre
point centre(const pointField &) const
Centre point of face.
Definition: face.C:488
Foam::meshSurfaceEngine::pointFaces
const VRWGraph & pointFaces() const
Definition: meshSurfaceEngineI.H:162
polyMeshGenModifier.H
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Foam::DynList::fcIndex
label fcIndex(const label index, const label offset=1) const
return forward and reverse circular indices
Definition: DynListI.H:486
Foam::Pair::first
const Type & first() const
Return first.
Definition: Pair.H:87
Foam::meshSurfaceEngine::faceEdges
const VRWGraph & faceEdges() const
Definition: meshSurfaceEngineI.H:353
Foam::Map< label >
triSurfModifier.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::polyMeshGenPoints::points
const pointFieldPMG & points() const
access to points
Definition: polyMeshGenPointsI.H:44
Foam::edgeExtractor::cornerEvaluator::improveCorners
void improveCorners(labelList &newBoundaryPatches)
Definition: edgeExtractorCorners.C:676
Foam::LongList::size
label size() const
Size of the active part of the list.
Definition: LongListI.H:203
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::HashSet< label, Hash< label > >
Foam::DynList::removeLastElement
T removeLastElement()
Return and remove the last element.
Definition: DynListI.H:384
Foam::DynList::contains
bool contains(const T &e) const
check if the element is in the list (takes linear time)
Definition: DynListI.H:339
Foam::meshSurfacePartitioner::pointPatches
const VRWGraph & pointPatches() const
Definition: meshSurfacePartitioner.H:123
meshOctree.H
Foam::edgeExtractor::surfaceEngine
const meshSurfaceEngine & surfaceEngine() const
get the surface engine
Definition: edgeExtractor.C:462
Foam::face::which
label which(const label globalIndex) const
Navigation through face vertices.
Definition: face.C:630
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
pFaces
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=*(cellModeller::lookup("hex"));labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells]=cellShape(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
Definition: readKivaGrid.H:235
Foam::LongList< label >
Foam::deleteDemandDrivenData
void deleteDemandDrivenData(DataPtr &dataPtr)
Definition: demandDrivenData.H:40
Foam::edgeExtractor::faceEvaluator::extractor_
const edgeExtractor & extractor_
const reference to the parent class
Definition: edgeExtractor.H:209
Foam::edgeExtractor::mesh_
polyMeshGen & mesh_
reference to the mesh
Definition: edgeExtractor.H:69
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::meshSurfaceEngine::boundaryFaces
const faceList::subList & boundaryFaces() const
Definition: meshSurfaceEngineI.H:103
refLabelledPoint.H
triSurfaceClassifyEdges.H
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:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
error.H
Foam::Info
messageStream Info
Foam::meshOctree::findNearestEdgePoint
bool findNearestEdgePoint(point &edgePoint, scalar &distSq, label &nearestEdge, const point &p, const DynList< label > &regions) const
find nearest feature-edges vertex to a given vertex
Definition: meshOctreeFindNearestSurfacePoint.C:215
Foam::meshSurfaceEngine::otherEdgeFaceAtProc
const Map< label > & otherEdgeFaceAtProc() const
Definition: meshSurfaceEngineI.H:568
Foam::meshSurfaceEngine::beNeiProcs
const DynList< label > & beNeiProcs() const
communication matrix for sending edge data
Definition: meshSurfaceEngineI.H:549
Foam::meshOctree::findNearestPointToPatches
bool findNearestPointToPatches(point &nearest, scalar &distSq, const point &p, const DynList< label > &patches, const scalar tol=1e-4) const
find the nearest vertex to the given patches
Definition: meshOctreeFindNearestSurfacePoint.C:535
Foam::DynList::appendIfNotIn
void appendIfNotIn(const T &e)
Definition: DynListI.H:324
Foam::Pair::second
const Type & second() const
Return second.
Definition: Pair.H:99
forAllRow
#define forAllRow(graph, rowI, index)
Definition: VRWGraph.H:277
Foam::polyMeshGenChecks::checkPoints
bool checkPoints(const polyMeshGen &, const bool report=false, labelHashSet *setPtr=NULL)
Check for unused points.
Definition: polyMeshGenChecksTopology.C:46
Foam::meshSurfaceEngine::points
const pointFieldPMG & points() const
Definition: meshSurfaceEngineI.H:49
Foam::triSurfacePartitioner::patchPatches
const List< labelHashSet > & patchPatches() const
return patch-patches addressing
Definition: triSurfacePartitioner.C:74
Foam::edgeExtractor::faceEvaluator::bestPatchTopological
static label bestPatchTopological(const DynList< label > &neiPatches, const label currentPatch)
Definition: edgeExtractorCorners.C:267
HashSet.H
Foam::VRWGraph::sizeOfRow
label sizeOfRow(const label rowI) const
Returns the number of elements in the given row.
Definition: VRWGraphI.H:127
Foam::FatalError
error FatalError
Foam::FixedList::setSize
void setSize(const label)
Dummy setSize function.
Definition: FixedListI.H:177
labelledPoint.H
labelledScalar.H
Foam::HashTable::found
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
Foam::help::areElementsInChain
bool areElementsInChain(const boolListType &sel)
check if selected elements are in one singly-connected chain
Definition: helperFunctionsTopologyManipulationI.H:426
Foam::meshSurfaceEngine::edgeFaces
const VRWGraph & edgeFaces() const
Definition: meshSurfaceEngineI.H:334
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
meshSurfaceEngine.H
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::edgeExtractor::cornerEvaluator::cornerEvaluator
cornerEvaluator(const edgeExtractor &, const meshSurfacePartitioner &)
construct from edgeExtractor and meshSurfacePartitioner
Definition: edgeExtractorCorners.C:653
Foam::meshOctree::findTrianglesInBox
void findTrianglesInBox(const boundBox &, DynList< label > &) const
Definition: meshOctreeInsideCalculations.C:98
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
s
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Foam::DynList< label >
Foam::meshSurfacePartitioner
Definition: meshSurfacePartitioner.H:52
Foam::edgeExtractor::faceEvaluator::~faceEvaluator
~faceEvaluator()
Definition: edgeExtractorCorners.C:345
Foam::meshSurfaceEngine::edges
const edgeList & edges() const
Definition: meshSurfaceEngineI.H:296
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::labelledScalar
Definition: labelledScalar.H:50
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
Foam::edgeExtractor::faceEvaluator::neiPatchesOverEdges
void neiPatchesOverEdges(const label bfI, const labelList &fPatches, const Map< label > &otherFacePatch, DynList< label > &neiPatches) const
calculate neighbour patches over edges of a boundary face
Definition: edgeExtractorCorners.C:233
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::DynList::rcIndex
label rcIndex(const label index, const label offset=1) const
Definition: DynListI.H:496
fv
labelList fv(nPoints)
Foam::edgeExtractor::meshOctree_
const meshOctree & meshOctree_
reference to the octree
Definition: edgeExtractor.H:75
Foam::edgeExtractor::cornerEvaluator::sortedFacesAtPoint
void sortedFacesAtPoint(const label, DynList< label > &) const
sort faces attached to a boundary point
Definition: edgeExtractorCorners.C:619
Foam::VRWGraph::containsAtPosition
label containsAtPosition(const label rowI, const label e) const
Definition: VRWGraphI.H:529
Foam::sumOp
Definition: ops.H:162
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: contiguous.H:49
helperFunctions.H
edgeExtractor.H
Foam::labelledPoint
Definition: labelledPoint.H:50
Foam::edgeExtractor::faceEvaluator::neiFacesProcs
void neiFacesProcs(const label, DynList< label > &) const
find processors of faces over edges
Definition: edgeExtractorCorners.C:204
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::DynList::setSize
void setSize(const label)
Reset size of List.
Definition: DynListI.H:263
Foam::acos
dimensionedScalar acos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:259
Foam::meshOctree
Definition: meshOctree.H:55
Foam::edgeExtractor::cornerEvaluator::createParallelAddressing
void createParallelAddressing()
create addressing at inter-processor boundaries
Definition: edgeExtractorCorners.C:448
Foam::FixedList< label, 2 >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::edgeExtractor::cornerEvaluator::~cornerEvaluator
~cornerEvaluator()
Definition: edgeExtractorCorners.C:670
Foam::help::exchangeMap
void exchangeMap(const std::map< label, ListType > &m, LongList< T > &data, const Pstream::commsTypes commsType)
Definition: helperFunctionsPar.C:129
edgeExtractor
A class with a functions used to detect feature edges in the surface of the volume mesh and to detect...
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116
Foam::edgeExtractor::facePatch_
labelList facePatch_
boundary face patch
Definition: edgeExtractor.H:90
Foam::edgeExtractor::faceEvaluator::calculateNeiPatchesParallel
void calculateNeiPatchesParallel()
calculate patches of faces over inter-processor boundaries
Definition: edgeExtractorCorners.C:58
Foam::triSurfacePartitioner::corners
const labelList & corners() const
return corner nodes
Definition: triSurfacePartitioner.C:64
Foam::labelledTri
Triangle with additional region number.
Definition: labelledTri.H:49
Foam::triSurf::writeSurface
void writeSurface(const fileName &) const
Definition: triSurf.C:430
meshSurfaceEngineModifier.H
Foam::boundBox
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:55
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::meshSurfaceEngine::boundaryPoints
const labelList & boundaryPoints() const
Definition: meshSurfaceEngineI.H:84
Foam::edgeExtractor::faceEvaluator::otherFacePatch_
Map< label > otherFacePatch_
calculated patches of faces over inter-processor boundaries
Definition: edgeExtractor.H:212
patches
patches[0]
Definition: createSingleCellMesh.H:36
FatalErrorIn
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:313
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::edgeExtractor::faceEvaluator::calculateNeiPatchesParallelNewPatches
void calculateNeiPatchesParallelNewPatches()
Definition: edgeExtractorCorners.C:110
Foam::DynList::size
label size() const
Definition: DynListI.H:235
Foam::meshSurfaceEngine::globalToLocalBndPointAddressing
const Map< label > & globalToLocalBndPointAddressing() const
global point label to local label. Only for processors points
Definition: meshSurfaceEngineI.H:431
Foam::edgeExtractor::findOtherFacePatchesParallel
void findOtherFacePatchesParallel(Map< label > &otherFacePatch, const labelList *facePatchPtr=NULL) const
find patches over edges
Definition: edgeExtractor.C:594
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::meshOctree::findNearestCorner
bool findNearestCorner(point &nearest, scalar &distSq, label &nearestPoint, const point &p, const DynList< label > &patches) const
find nearest corner point
Definition: meshOctreeFindNearestSurfacePoint.C:405
Foam::meshOctree::surface
const triSurf & surface() const
return a reference to the surface
Definition: meshOctreeI.H:130
Foam::edgeExtractor::faceEvaluator::bestPatchAfterModification
label bestPatchAfterModification(const label bfI) const
Definition: edgeExtractorCorners.C:394
Foam::meshSurfacePartitioner::corners
const labelHashSet & corners() const
return labels of corner points (from the list of boundary points)
Definition: meshSurfacePartitioner.H:129
Foam::edgeExtractor::faceEvaluator::setNewBoundaryPatches
void setNewBoundaryPatches(const labelList &newBoudaryPatches)
set the values for new boundary patches
Definition: edgeExtractorCorners.C:353
Foam::edgeExtractor::faceEvaluator::neiFacesOverEdges
void neiFacesOverEdges(const label, DynList< label > &) const
find neighbour faces over edges
Definition: edgeExtractorCorners.C:174
Foam::pointFieldPMG
Definition: pointFieldPMG.H:50
Foam::VRWGraph
Definition: VRWGraph.H:101
Foam::triSurf
Definition: triSurf.H:59
Foam::labelLongList
LongList< label > labelLongList
Definition: labelLongList.H:46
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
meshSurfaceOptimizer.H
Foam::labelPair
Pair< label > labelPair
Label pair.
Definition: labelPair.H:48
Foam::magSqr
dimensioned< scalar > magSqr(const dimensioned< Type > &)
Foam::meshSurfaceEngine
Definition: meshSurfaceEngine.H:54
Foam::meshSurfacePartitioner::featureEdges
const labelHashSet & featureEdges() const
return labels of boundary edges which are feature edges
Definition: meshSurfacePartitioner.H:153
DynList.H
labelPair.H
Foam::DynList::append
void append(const T &e)
Append an element at the end of the list.
Definition: DynListI.H:304
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:190
Foam::edgeExtractor::findCornerCandidates
bool findCornerCandidates()
Definition: edgeExtractorCorners.C:817