73 const face& bf = bFaces[bfI];
86 std::map<label, LongList<labelPair> > exchangeData;
95 const label bpI = iter();
99 const label neiProc = bpAtProcs(bpI, i);
104 exchangeData[neiProc].append
139 const label c0 = faceCells[edgeFaces(eI, 0)];
140 const label c1 = faceCells[edgeFaces(eI, 1)];
156 # pragma omp parallel for schedule(dynamic, 100)
166 const face&
f = faces[
c[fI]];
170 const edge e =
f.faceEdge(eI);
172 const label bps = bp[
e.start()];
179 const label beI = bpEdges(bps, i);
180 const edge& be = edges[beI];
182 if( (
e == be) && !foundEdge.
contains(be) )
208 # pragma omp parallel
215 # pragma omp for schedule(dynamic, 40)
219 const face& bf = bFaces[bfI];
227 d = 2.0 * d + VSMALL;
238 nPatchesAtFace[bfI] = nearPatches.
size();
240 localData.
append(nearPatches[i]);
256 while( counter < localData.
size() )
258 const label edgeI = localData[counter++];
260 const label size = nPatchesAtFace[edgeI];
262 for(
label i=0;i<size;++i)
278 # pragma omp parallel
285 # pragma omp for schedule(dynamic, 40)
289 const edge&
e = edges[edgeI];
291 const scalar d = 1.5 *
e.mag(
points);
306 nFeatureEdgesAtEdge[edgeI] = nearEdges.
size();
308 localData.
append(nearEdges[i]);
324 while( counter < localData.
size() )
326 const label edgeI = localData[counter++];
328 const label size = nFeatureEdgesAtEdge[edgeI];
330 for(
label i=0;i<size;++i)
347 std::map<label, label> otherProcPatch;
355 std::map<label, labelLongList> exchangeData;
365 const label beI = it();
382 while( counter < receivedData.
size() )
384 const label beI = globalToLocal[receivedData[counter++]];
385 const label fPatch = receivedData[counter++];
387 otherProcPatch[beI] = fPatch;
393 # pragma omp parallel for schedule(dynamic, 40)
402 const edge&
e = edges[beI];
403 patchPoint[bp[
e.start()]] =
false;
404 patchPoint[bp[
e.end()]] =
false;
410 const label otherPatch = otherProcPatch[beI];
412 if(
facePatch_[edgeFaces(beI, 0)] != otherPatch )
414 const edge&
e = edges[beI];
415 patchPoint[bp[
e.start()]] =
false;
416 patchPoint[bp[
e.end()]] =
false;
422 const edge&
e = edges[beI];
423 patchPoint[bp[
e.start()]] =
false;
424 patchPoint[bp[
e.end()]] =
false;
439 std::map<label, labelLongList> sendData;
441 sendData.insert(std::make_pair(neiProcs[i],
labelLongList()));
447 const label neiProc = bpAtProcs(bpI, i);
450 sendData[neiProc].append(globalPointLabel[bpI]);
458 patchPoint[globalToLocal[receivedData[i]]] =
false;
467 # pragma omp critical
485 # pragma omp critical
517 faceCandidates.
clear();
519 facePatchPtr = &facePatch_;
521 const labelList& fPatches = *facePatchPtr;
523 bool deleteOtherFacePatchPtr(
false);
524 if( !otherFacePatchPtr )
528 findOtherFacePatchesParallel(*helperPtr, facePatchPtr);
530 otherFacePatchPtr = helperPtr;
531 deleteOtherFacePatchPtr =
true;
534 const Map<label>& otherFacePatch = *otherFacePatchPtr;
541 # pragma omp parallel if( faceEdges.size() > 1000 )
546 # pragma omp for schedule(dynamic, 40)
553 const label beI = faceEdges(bfI, feI);
557 label fNei = edgeFaces(beI, 0);
559 fNei = edgeFaces(beI, 1);
569 if( allNeiPatches.
size() > 1 )
573 procCandidates.
append(bfI);
575 faceCandidates.
append(bfI);
581 # pragma omp critical
584 faceCandidates.
append(procCandidates[i]);
589 if( deleteOtherFacePatchPtr )
599 otherFacePatch.clear();
602 facePatchPtr = &facePatch_;
604 const labelList& fPatches = *facePatchPtr;
615 std::map<label, labelLongList> exchangeData;
625 const label beI = it();
634 dts.
append(fPatches[edgeFaces(beI, 0)]);
642 while( counter < receivedData.
size() )
644 const label beI = globalToLocal[receivedData[counter++]];
645 const label fPatch = receivedData[counter++];
647 otherFacePatch.insert(beI, fPatch);
661 surfaceEnginePtr_(NULL),
663 surfPartitionerPtr_(NULL),
664 surfEdgeClassificationPtr_(NULL),
671 featureEdgesNearEdge_()
675 calculateSingleCellEdge();
677 findPatchesNearSurfaceFace();
679 findFeatureEdgesNearEdge();
696 Info <<
"Reducing Hausdorff distance:" <<
flush;
709 for(
label iterI=0;iterI<nIterations;++iterI)
712 # pragma omp parallel
717 # pragma omp for schedule(dynamic, 40)
725 label patchI, nearestTri;
735 faceCentreDisplacement[bfI] = newP - centre;
740 # pragma omp for schedule(dynamic, 40)
742 forAll(pointDisplacements, bpI)
752 # pragma omp for schedule(dynamic, 40)
758 pointDisplacements[bpI].coordinates() +=
759 faceCentreDisplacement[pointFaces(bpI, pfI)];
760 ++pointDisplacements[bpI].pointLabel();
772 std::map<label, LongList<refLabelledPoint> > exchangeData;
778 const label bpI = iter();
782 const label neiProc = bpAtProcs(bpI, i);
787 exchangeData[neiProc].append
799 const label globalLabel = receivedData[i].objectLabel();
802 const label bpI = globalToLocal[globalLabel];
804 pointDisplacements[bpI].coordinates() += lp.
coordinates();
805 pointDisplacements[bpI].pointLabel() += lp.
pointLabel();
810 # pragma omp parallel for schedule(dynamic, 40)
812 forAll(pointDisplacements, bpI)
855 Warning <<
"Mesh patches are already assigned!" <<
endl;
865 # pragma omp parallel for schedule(dynamic, 40)
877 if( (fPatch > -1) && (fPatch <
nPatches) )
886 "void meshSurfaceEdgeExtractorNonTopo::"
887 "distributeBoundaryFaces()"
888 ) <<
"Cannot distribute a boundary points " << bPoints[bpI]
896 # pragma omp parallel for schedule(dynamic, 40)
900 const face& bf = bFaces[bfI];
911 if( (fPatch > -1) && (fPatch <
nPatches) )
921 "void meshSurfaceEdgeExtractorNonTopo::"
922 "distributeBoundaryFaces()"
923 ) <<
"Cannot distribute a face " << bFaces[bfI] <<
" into any "
942 label nCorrected, nIterations(0);
971 # pragma omp parallel for schedule(dynamic, 40) \
972 reduction(+ : nCorrected)
976 const label bfI = candidates[i];
977 const face& bf = bFaces[bfI];
985 const label beI = faceEdges(bfI, eI);
989 label fNei = edgeFaces(beI, 0);
991 fNei = edgeFaces(faceEdges(bfI, eI), 1);
999 neiPatches[eI] = otherProcNewPatch[beI];
1006 (allNeiPatches.
size() == 1) &&
1021 label nearestTriangle;
1036 vector tn = surf[nearestTriangle].normal(sPoints);
1037 tn /= (
mag(tn) + VSMALL);
1039 fn /= (
mag(fn) + SMALL);
1042 normalAlignment[i] =
mag(tn & fn);
1043 distanceSq[i] = dSq;
1046 scalar maxAlignment(0.0);
1047 forAll(normalAlignment, i)
1051 sqrt(maxDSq / (distanceSq[i] + VSMALL)) * normalAlignment[i]
1054 if( metric > maxAlignment )
1056 maxAlignment = metric;
1057 newPatch = allNeiPatches[i];
1061 if( (newPatch >= 0) && (newPatch !=
facePatch_[bfI]) )
1063 newBoundaryPatches[bfI] = newPatch;
1077 }
while( (nCorrected != 0) && (++nIterations < 5) );
1103 # pragma omp parallel for schedule(dynamic, 40) \
1104 if( faceCandidates.size() > 100 )
1106 forAll(faceCandidates, fcI)
1108 const label bfI = faceCandidates[fcI];
1112 const label eI = faceEdges(bfI, i);
1126 # pragma omp parallel for schedule(dynamic, 40) private(containedTriangles)
1134 const label eI = pEdges(bpI, peI);
1149 const label eI = pEdges(bpI, peI);
1150 const edge&
e = edges[eI];
1165 containedTriangles.
clear();
1170 forAll(containedTriangles, ctI)
1172 const label tI = containedTriangles[ctI];
1176 const label seI = facetEdges(tI, feI);
1197 featureEdgesNearPoint[bpI];
1198 featureEdgeDistances.
setSize(featureEdgeCandidates.
size());
1199 forAll(featureEdgeCandidates, i)
1201 const label seI = featureEdgeCandidates[i];
1203 const point s = sp[edges[seI].start()];
1204 const point e = sp[edges[seI].end()];
1211 sort(featureEdgeDistances);
1221 # pragma omp parallel for schedule(dynamic, 40) \
1222 if( edges.size() > 1000 )
1228 const edge&
e = edges[edgeI];
1231 featureEdgesNearPoint[bp[
e.start()]];
1233 featureEdgesNearPoint[bp[
e.end()]];
1240 const label sPart = edgeGroup[sc[i].scalarLabel()];
1244 const label ePart = edgeGroup[ec[j].scalarLabel()];
1246 if( (sPart >= 0) && (sPart == ePart) )
1253 sc[i].value() + ec[j].value()
1261 edgeGroupAndWeights[edgeI].
setSize(weights.
size());
1262 forAll(edgeGroupAndWeights[edgeI], epI)
1263 edgeGroupAndWeights[edgeI][epI] = weights[epI];
1270 Info <<
"Edge partitions and weights " << edgeGroupAndWeights <<
endl;
1289 const label beI = faceEdges(bfI, feI);
1293 label nei = edgeFaces(beI, 0);
1295 nei = edgeFaces(beI, 1);
1297 neiPatches[feI] = facePatch_[nei];
1299 else if( edgeFaces.
sizeOfRow(beI) == 1 )
1301 neiPatches[feI] = otherProcPatch[beI];
1321 const edge&
e = surfaceEnginePtr_->edges()[beI];
1326 const scalar magE =
mag(ev) + VSMALL;
1332 meshOctree_.findNearestPointToPatches(mps, dSqS, ps,
patches);
1333 meshOctree_.findNearestPointToPatches(mpe, dSqE, pe,
patches);
1338 val = 0.5 * (1.0 + (ev &
fv));
1340 val =
min(val, 1.0);
1341 val =
max(val, 0.0);
1361 const edge&
e = surfaceEnginePtr_->edges()[beI];
1366 const scalar magE =
mag(ev) + VSMALL;
1372 meshOctree_.findNearestPointToPatches(mps, dSqS, ps,
patches);
1373 meshOctree_.findNearestPointToPatches(mpe, dSqE, pe,
patches);
1378 scalar
c =
min(
fv & ev, 1.0);
1380 const scalar angle =
acos(
c);
1382 val = 0.5 * (
sqrt(dSqS) +
sqrt(dSqE)) + magE * angle;
1391 const label facePatch
1396 const VRWGraph& faceEdges = surfaceEnginePtr_->faceEdges();
1402 "scalar edgeExtractor::calculateDeformationMetricForFace"
1403 "(const label, const DynList<label>&, const label) const"
1404 ) <<
"Number of neiPatches and faceEdge does not match for face "
1408 const label patch0 = facePatch == -1 ? facePatch_[bfI] : facePatch;
1412 const label beI = faceEdges(bfI, i);
1414 if( neiPatches[i] == patch0 )
1417 Enorm += calculateDeformationMetricForEdge(beI, patch0, neiPatches[i]);
1425 bool changed(
false);
1464 # pragma omp parallel for schedule(dynamic, 40) reduction(+ : nChanged)
1472 const label firstPatch = newBoundaryPatches[edgeFaces(beI, 0)];
1473 const label secondPatch = newBoundaryPatches[edgeFaces(beI, 1)];
1475 if( firstPatch == secondPatch )
1478 const cell&
c =
cells[faceCells[edgeFaces(beI, 0)]];
1482 point pMax(-VGREAT, -VGREAT, -VGREAT);
1485 const face&
f = faces[
c[fI]];
1502 forAll(containedEdges, ceI)
1504 const label eI = containedEdges[ceI];
1513 const label patch0 = surf[edgeFacets(eI, 0)].region();
1514 const label patch1 = surf[edgeFacets(eI, 1)].region();
1518 ((firstPatch == patch0) && (secondPatch == patch1)) ||
1519 ((firstPatch == patch1) && (secondPatch == patch0))
1531 hasPatchPoints =
false;
1535 if(
c[fI] < bndStartFace )
1538 const label bfI =
c[fI] - bndStartFace;
1539 const face& bf = bFaces[bfI];
1541 if( newBoundaryPatches[bfI] == patch1 )
1543 facesInPatch[1].
append(bfI);
1548 if( patchPoint[bp[bf[pI]]] )
1549 hasPatchPoints[1] =
true;
1552 else if( newBoundaryPatches[bfI] == patch0 )
1554 facesInPatch[0].
append(bfI);
1559 if( patchPoint[bp[bf[pI]]] )
1560 hasPatchPoints[0] =
true;
1565 if( nFacesInPatch[1] > nFacesInPatch[0] )
1569 forAll(facesInPatch[0], i)
1570 newBoundaryPatches[facesInPatch[0][i]] = patch1;
1574 else if( nFacesInPatch[0] > nFacesInPatch[1] )
1578 forAll(facesInPatch[1], i)
1579 newBoundaryPatches[facesInPatch[1][i]] = patch0;
1585 if( hasPatchPoints[0] && !hasPatchPoints[1] )
1588 forAll(facesInPatch[0], i)
1589 newBoundaryPatches[facesInPatch[0][i]] =
1594 else if( !hasPatchPoints[0] && hasPatchPoints[1] )
1597 forAll(facesInPatch[1], i)
1598 newBoundaryPatches[facesInPatch[1][i]] =
1606 forAll(facesInPatch[1], i)
1607 newBoundaryPatches[facesInPatch[1][i]] =
1624 }
while( nChanged != 0 );
1634 bool changed(
false);
1648 # ifdef DEBUGEdgeExtractor
1683 # pragma omp parallel for schedule(dynamic, 40) \
1684 reduction(+ : nCorrected)
1688 const label bfI = candidates[i];
1689 const face& bf = bFaces[bfI];
1693 bool allInSamePatch(
true);
1697 allInSamePatch =
false;
1701 if( allInSamePatch )
1710 const label beI = faceEdges(bfI, eI);
1714 label fNei = edgeFaces(beI, 0);
1716 fNei = edgeFaces(faceEdges(bfI, eI), 1);
1721 else if( edgeFaces.
sizeOfRow(beI) == 1 )
1724 neiPatches[eI] = otherProcNewPatch[beI];
1731 (allNeiPatches.
size() == 1) &&
1744 nNeiInPatch.insert(allNeiPatches[i], 0);
1746 ++nNeiInPatch[neiPatches[eI]];
1752 if( it() > nNeiEdges )
1754 newPatch = it.key();
1759 (it() == nNeiEdges) && (it.key() ==
facePatch_[bfI])
1762 newPatch = it.key();
1767 if( (newPatch < 0) || (newPatch ==
facePatch_[bfI]) )
1777 if( neiPatches[eI] == newPatch )
1784 newBoundaryPatches[bfI] = newPatch;
1797 # pragma omp parallel for schedule(dynamic, 50)
1801 const label bfI = candidates[i];
1803 const label bestPatch =
1806 newBoundaryPatches[bfI] = bestPatch;
1818 }
while( nCorrected != 0 && (nIter++ < 3) );
1825 namespace featureEdgeHelpers
1855 const edge&
e = edges[edgeI];
1867 std::map<label, DynList<labelPair> > exchangeData;
1869 exchangeData[neiProcs[i]].clear();
1874 const label bpI = it();
1878 const label neiProc = bpAtProcs(bpI, i);
1883 exchangeData[neiProc].append
1926 neighbourEdges.
clear();
1932 const edge&
e = edges[beI];
1934 const label bps = bp[
e.start()];
1935 const label bpe = bp[
e.end()];
1941 const label beJ = bpEdges(bps, peI);
1946 neighbourEdges.
append(beJ);
1954 const label beJ = bpEdges(bpe, peI);
1959 neighbourEdges.
append(beJ);
1964 template<
class labelListType>
1968 const labelListType& elementInGroup,
1978 std::map<label, DynList<labelPair> > exchangeData;
1980 exchangeData[neiProcs[i]].clear();
1984 const label bpI = it();
1991 const label beI = bpEdges(bpI, i);
1996 const label groupI = elementInGroup[beI];
2000 const label neiProc = bpAtProcs(bpI, ppI);
2005 exchangeData[neiProc].append
2007 labelPair(it.key(), localGroupLabel[groupI])
2019 const label groupI = elementInGroup[globalToLocal[lp.
first()]];
2056 bool changed(
false);
2072 activePointLabel[bpI] = bpI;
2078 # ifdef DEBUGEdgeExtractor
2114 "void edgeExtractor::extractEdges()"
2115 ) <<
"Found " << invertedPoints.
size()
2116 <<
" points with inverted surface normals. Getting rid of them..."
2120 activePointLabel.
clear();
2121 activePoints =
false;
2124 activePointLabel.
append(bp[it.key()]);
2125 activePoints[bp[it.key()]] =
true;
2151 const face& bf = bFaces[bfI];
2154 if( invertedPoints.
found(bf[pI]) )
2162 # pragma omp parallel for schedule(dynamic, 5) reduction(+ : nCorrected)
2166 const label bfI = candidates[i];
2177 scalar minE(VGREAT);
2178 label minEPatch(-1);
2190 if( Enorm[i] < minE )
2193 minEPatch = allNeiPatches[i];
2199 newBoundaryPatches[bfI] = minEPatch;
2206 if( nCorrected == 0 )
2217 forAll(newBoundaryPatches, bfI)
2219 if( newBoundaryPatches[bfI] !=
facePatch_[bfI] )
2221 const label patchI =
2223 newBoundaryPatches[bfI] = patchI;
2226 changedFaces.
append(bfI);
2230 nCorrected = changedFaces.
size();
2240 }
while( nCorrected != 0 );
2260 const face& bf = bFaces[bfI];
2263 pointPatches[bp[bf[pI]]].appendIfNotIn(
facePatch_[bfI]);
2273 std::map<label, LongList<labelPair> > exchangeData;
2283 const label bpI = it();
2289 const label neiProc = bpAtProcs(bpI, i);
2310 pointPatches[globalToLocal[lp.
first()]].appendIfNotIn(lp.
second());
2317 # pragma omp parallel for schedule(dynamic, 10)
2319 forAll(pointPatches, bpI)
2321 if( pointPatches[bpI].size() < 2 )
2331 if( pPatches.
size() == 2 )
2344 for(
label iterI=0;iterI<20;++iterI)
2366 inp /= pPatches.
size();
2367 const scalar currDSq =
magSqr(inp - pp);
2370 if( currDSq < 1
e-2 * dSqExact )
2376 if( dSqExact > 1.1 *
magSqr(pp -
p) )
2388 bool changed(
false);
2404 # ifdef DEBUGEdgeExtractor
2406 sPtr->
writeSurface(
"initialDistributionOfPatches.stl");
2410 Info <<
"Starting topological adjustment of patches" <<
endl;
2413 Info <<
"Finished topological adjustment of patches" <<
endl;
2415 # ifdef DEBUGEdgeExtractor
2416 Info <<
"Changes due to face patches" <<
endl;
2425 Info <<
"No topological adjustment was needed" <<
endl;
2428 Info <<
"Starting geometrical adjustment of patches" <<
endl;
2431 Info <<
"Finished geometrical adjustment of patches" <<
endl;
2435 Info <<
"No geometrical adjustment was needed" <<
endl;
2438 # ifdef DEBUGEdgeExtractor
2465 if( bp[pointI] < 0 )
2468 sPts[bp[pointI]] =
points[pointI];
2474 const face& bf = bFaces[bfI];
2480 for(
label i=bf.size()-2;i>0;--i)
2483 tri[2] = bp[bf[i+1]];
2514 const face& bf = bFaces[bfI];
2517 if( newPointLabel[bf[pI]] == -1 )
2518 newPointLabel[bf[pI]] =
nPoints++;
2522 tri[0] = newPointLabel[bf[0]];
2524 for(
label i=bf.size()-2;i>0;--i)
2526 tri[1] = newPointLabel[bf[i]];
2527 tri[2] = newPointLabel[bf[i+1]];
2535 forAll(newPointLabel, pointI)
2536 if( newPointLabel[pointI] != -1 )
2538 sPts[newPointLabel[pointI]] =
points[pointI];
2567 newBoundaryOwners[bfI] = faceOwner[bfI];
2584 forAll(surfPatches, patchI)
2585 boundaries[patchI].patchType() = surfPatches[patchI].geometricType();