62 const label nAdditionalLayers
65 const labelList& bPoints = surfaceEngine_.boundaryPoints();
66 const VRWGraph& pPoints = surfaceEngine_.pointPoints();
68 if( smoothVertex.
size() != bPoints.
size() )
74 label nInvertedTria(0);
84 if( inverted.
found(bPoints[bpI]) )
87 smoothVertex[bpI] =
true;
93 Info <<
"Number of inverted boundary faces is " << nInvertedTria <<
endl;
95 if( nInvertedTria == 0 )
99 for(
label i=0;i<nAdditionalLayers;++i)
101 boolList originallySelected = smoothVertex;
103 if( originallySelected[bpI] )
105 smoothVertex[pPoints(bpI, ppI)] =
true;
111 surfaceEngine_.globalBoundaryPointLabel();
113 surfaceEngine_.globalToLocalBndPointAddressing();
114 const VRWGraph& bpAtProcs = surfaceEngine_.bpAtProcs();
117 std::map<label, labelLongList> shareData;
126 const label bpI = iter();
128 if( !smoothVertex[bpI] )
133 const label neiProc = bpAtProcs(bpI, procI);
138 shareData[neiProc].append(globalPointLabel[bpI]);
148 const label bpI = globalToLocal[receivedData[j]];
150 smoothVertex[bpI] =
true;
155 return nInvertedTria;
166 newPositions.
setSize(omp_get_num_procs());
171 # pragma omp parallel num_threads(newPositions.size())
176 newPositions[omp_get_thread_num()];
182 # pragma omp for schedule(dynamic, 40)
186 const label bpI = edgePoints[i];
188 if( vertexType_[bpI] & (PROCBND | LOCKED) )
196 edgeNodeDisplacementParallel(procEdgePoints);
199 forAll(newPositions, threadI)
206 newPos[i].pointLabel(),
223 newPositions.
setSize(omp_get_num_procs());
227 # pragma omp parallel num_threads(newPositions.size())
232 newPositions[omp_get_thread_num()];
238 # pragma omp for schedule(dynamic, 40)
242 const label bpI = selectedPoints[i];
244 if( vertexType_[bpI] & (PROCBND | LOCKED) )
255 nodeDisplacementLaplacianFCParallel(selectedProcPoints,
transform);
260 # pragma omp parallel num_threads(newPositions.size())
264 const label threadI = omp_get_thread_num();
266 const label threadI = 0;
274 newPos[i].pointLabel(),
292 updateTriMesh(selectedPoints);
297 # pragma omp parallel for schedule(dynamic, 20)
301 const label bpI = selectedPoints[i];
303 newPositions[i] = newPositionSurfaceOptimizer(bpI);
309 # pragma omp parallel for schedule(dynamic, 100)
313 const label bpI = selectedPoints[i];
329 const label nAdditionalLayers
332 Info <<
"Starting untangling the surface of the volume mesh" <<
endl;
336 const labelList& bPoints = surfaceEngine_.boundaryPoints();
338 surfaceEngine_.pointFaces();
339 surfaceEngine_.faceCentres();
340 surfaceEngine_.pointPoints();
341 surfaceEngine_.boundaryFacePatches();
342 surfaceEngine_.pointNormals();
343 surfaceEngine_.boundaryPointEdges();
347 surfaceEngine_.bpAtProcs();
348 surfaceEngine_.globalToLocalBndPointAddressing();
349 surfaceEngine_.globalBoundaryPointLabel();
350 surfaceEngine_.bpNeiProcs();
355 # pragma omp parallel for schedule(dynamic, 50)
357 forAll(selectedBoundaryPoints, i)
359 if( vertexType_[selectedBoundaryPoints[i]] & LOCKED )
362 smoothVertex[selectedBoundaryPoints[i]] =
true;
371 bool remapVertex(
true);
373 label nGlobalIter(0);
384 label nIter(0), nAfterRefresh(0);
389 findInvertedVertices(smoothVertex, nAdditionalLayers);
391 if( nInvertedTria == 0 )
395 else if( enforceConstraints_ && !remapVertex )
400 const label subsetId =
401 mesh.addPointSubset(badPointsSubsetName_);
404 if( smoothVertex[bpI] )
405 mesh.addPointToSubset(subsetId, bPoints[bpI]);
409 "bool meshSurfaceOptimizer::untangleSurface"
410 "(const labelLongList&, const label)"
411 ) <<
"Writing mesh with " << badPointsSubsetName_
412 <<
" subset. These points cannot be untangled"
413 <<
" without sacrificing geometry constraints. Exitting.."
418 throw std::logic_error
420 "bool meshSurfaceOptimizer::untangleSurface"
421 "(const labelLongList&, const label)"
422 "Cannot untangle mesh!!"
428 if( nInvertedTria < minNumInverted )
430 minNumInverted = nInvertedTria;
434 # pragma omp parallel for schedule(dynamic, 100)
437 minInvertedPoints[bpI] =
points[bPoints[bpI]];
444 nInvertedHistory.
push(nInvertedTria);
445 if( nInvertedHistory.size() > 2 )
446 nInvertedHistory.
pop();
449 bool minimumInStack(
false);
451 if( it() == minNumInverted )
452 minimumInStack =
true;
456 if( !minimumInStack || (nAfterRefresh > 2) )
462 procBndPoints.
clear();
464 procEdgePoints.
clear();
465 movedEdgePoints.
clear();
469 if( !smoothVertex[bpI] )
472 if( vertexType_[bpI] & PARTITION )
476 if( vertexType_[bpI] & PROCBND )
477 procBndPoints.
append(bpI);
479 else if( vertexType_[bpI] & EDGE )
481 movedEdgePoints.
append(bpI);
483 if( vertexType_[bpI] & PROCBND )
484 procEdgePoints.
append(bpI);
489 smoothEdgePoints(movedEdgePoints, procEdgePoints);
490 if( remapVertex && mapperPtr )
495 smoothLaplacianFC(movedPoints, procBndPoints);
499 smoothSurfaceOptimizer(movedPoints, procBndPoints);
501 if( remapVertex && mapperPtr )
507 }
while( nInvertedTria && (++nIter < 20) );
509 if( nInvertedTria > 0 )
513 forAll(minInvertedPoints, bpI)
521 Info <<
"Smoothing remaining inverted vertices " <<
endl;
524 procBndPoints.
clear();
526 if( smoothVertex[bpI] )
530 if( vertexType_[bpI] & PROCBND )
531 procBndPoints.
append(bpI);
534 smoothLaplacianFC(movedPoints, procBndPoints,
false);
536 if( remapVertex && mapperPtr )
542 if( nGlobalIter > 5 )
546 }
while( nInvertedTria && (++nGlobalIter < 10) );
550 if( nInvertedTria != 0 )
557 label subsetId =
mesh.pointSubsetIndex(badPointsSubsetName_);
559 mesh.removePointSubset(subsetId);
560 subsetId =
mesh.addPointSubset(badPointsSubsetName_);
563 if( smoothVertex[bpI] )
564 mesh.addPointToSubset(subsetId, bPoints[bpI]);
567 Info <<
"Finished untangling the surface of the volume mesh" <<
endl;
598 labelLongList procBndPoints, edgePoints, partitionPoints, procPoints;
609 procBndPoints.
append(bpI);
613 partitionPoints.
append(bpI);
621 Info <<
"Optimizing edges. Iteration:" <<
flush;
622 for(
label i=0;i<nIterations;++i)
643 Info <<
"Optimizing surface vertices. Iteration:";
644 for(
label i=0;i<nIterations;++i)
678 labelLongList procBndPoints, movedPoints, activeEdges, updatePoints;
681 const edge&
e = edges[beI];
683 if( zMinPoint[
e.start()] ^ zMinPoint[
e.end()] )
685 label bpI = bp[
e.start()];
686 if( !zMinPoint[
e.start()] )
693 updatePoints.
append(bp[
e.start()]);
694 updatePoints.
append(bp[
e.end()]);
699 procBndPoints.
append(bpI);
711 Info <<
"Optimizing edges. Iteration:" <<
flush;
712 for(
label i=0;i<nIterations;++i)
730 procBndPoints.
clear();
738 procBndPoints.
append(bpI);
740 Info <<
"Optimizing surface vertices. Iteration:";
741 for(
label i=0;i<nIterations;++i)
763 const VRWGraph& pointFaces =
mesh.addressingData().pointFaces();
787 const label nBadFaces =
796 Info <<
"Iteration " << iterationI
797 <<
". Number of bad faces " << nBadFaces <<
endl;
804 activeBoundaryPoint =
false;
808 const face&
f = faces[it.key()];
812 if( zMinPoint[
f[pI]] )
814 activeBoundaryPoint[bp[
f[pI]]] =
true;
817 changedFace[pointFaces(
f[pI], pfI)] =
true;
836 const label bpI = it();
838 if( activeBoundaryPoint[bpI] )
842 const label neiProc = bpNeiProcs(bpI, i);
859 const label bpI = globalToLocal[receivedData[i]];
862 activeBoundaryPoint[bpI] =
true;
866 changedFace[pointFaces(bPoints[bpI], pfI)] =
true;
876 if( !activeBoundaryPoint[bpI] )
895 for(
label i=0;i<5;++i)
915 mesh.addressingData()
916 ).updateGeometry(changedFace);
918 }
while( ++iterationI < 20 );
921 mesh.clearAddressingData();