00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <OpenFOAM/BiIndirectList.H>
00027 #include "removePoints.H"
00028 #include <OpenFOAM/PstreamReduceOps.H>
00029 #include <OpenFOAM/polyMesh.H>
00030 #include "polyTopoChange.H"
00031 #include <dynamicMesh/polyRemovePoint.H>
00032 #include <dynamicMesh/polyAddPoint.H>
00033 #include <dynamicMesh/polyModifyFace.H>
00034 #include <OpenFOAM/syncTools.H>
00035 #include <meshTools/wallPoint.H>
00036 #include <meshTools/faceSet.H>
00037
00038
00039
00040 namespace Foam
00041 {
00042
00043 defineTypeNameAndDebug(removePoints, 0);
00044
00045 }
00046
00047
00048
00049
00050 void Foam::removePoints::modifyFace
00051 (
00052 const label faceI,
00053 const face& newFace,
00054 polyTopoChange& meshMod
00055 ) const
00056 {
00057
00058 label patchI = -1;
00059 label owner = mesh_.faceOwner()[faceI];
00060 label neighbour = -1;
00061
00062 if (mesh_.isInternalFace(faceI))
00063 {
00064 neighbour = mesh_.faceNeighbour()[faceI];
00065 }
00066 else
00067 {
00068 patchI = mesh_.boundaryMesh().whichPatch(faceI);
00069 }
00070
00071 label zoneID = mesh_.faceZones().whichZone(faceI);
00072
00073 bool zoneFlip = false;
00074
00075 if (zoneID >= 0)
00076 {
00077 const faceZone& fZone = mesh_.faceZones()[zoneID];
00078
00079 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
00080 }
00081
00082 meshMod.setAction
00083 (
00084 polyModifyFace
00085 (
00086 newFace,
00087 faceI,
00088 owner,
00089 neighbour,
00090 false,
00091 patchI,
00092 false,
00093 zoneID,
00094 zoneFlip
00095 )
00096 );
00097 }
00098
00099
00100
00101
00102
00103 Foam::removePoints::removePoints
00104 (
00105 const polyMesh& mesh,
00106 const bool undoable
00107 )
00108 :
00109 mesh_(mesh),
00110 undoable_(undoable)
00111 {}
00112
00113
00114
00115
00116 Foam::label Foam::removePoints::countPointUsage
00117 (
00118 const scalar minCos,
00119 boolList& pointCanBeDeleted
00120 ) const
00121 {
00122
00123
00124
00125
00126 labelList edge0(mesh_.nPoints(), -1);
00127 labelList edge1(mesh_.nPoints(), -1);
00128
00129 const edgeList& edges = mesh_.edges();
00130
00131 forAll(edges, edgeI)
00132 {
00133 const edge& e = edges[edgeI];
00134
00135 forAll(e, eI)
00136 {
00137 label pointI = e[eI];
00138
00139 if (edge0[pointI] == -2)
00140 {
00141
00142 }
00143 else if (edge0[pointI] == -1)
00144 {
00145
00146 edge0[pointI] = edgeI;
00147 }
00148 else
00149 {
00150
00151
00152 if (edge1[pointI] == -1)
00153 {
00154
00155 edge1[pointI] = edgeI;
00156 }
00157 else
00158 {
00159
00160 edge0[pointI] = -2;
00161 edge1[pointI] = -2;
00162 }
00163 }
00164 }
00165 }
00166
00167
00168
00169 const pointField& points = mesh_.points();
00170
00171 pointCanBeDeleted.setSize(mesh_.nPoints());
00172 pointCanBeDeleted = false;
00173 label nDeleted = 0;
00174
00175 forAll(edge0, pointI)
00176 {
00177 if (edge0[pointI] >= 0 && edge1[pointI] >= 0)
00178 {
00179
00180
00181 const edge& e0 = edges[edge0[pointI]];
00182 const edge& e1 = edges[edge1[pointI]];
00183
00184 label common = e0.commonVertex(e1);
00185 label vLeft = e0.otherVertex(common);
00186 label vRight = e1.otherVertex(common);
00187
00188 vector e0Vec = points[common] - points[vLeft];
00189 e0Vec /= mag(e0Vec) + VSMALL;
00190
00191 vector e1Vec = points[vRight] - points[common];
00192 e1Vec /= mag(e1Vec) + VSMALL;
00193
00194 if ((e0Vec & e1Vec) > minCos)
00195 {
00196 pointCanBeDeleted[pointI] = true;
00197 nDeleted++;
00198 }
00199 }
00200 else if (edge0[pointI] == -1)
00201 {
00202
00203 pointCanBeDeleted[pointI] = true;
00204 nDeleted++;
00205 }
00206 }
00207 edge0.clear();
00208 edge1.clear();
00209
00210
00211
00212
00213 forAll(mesh_.faces(), faceI)
00214 {
00215 const face& f = mesh_.faces()[faceI];
00216
00217 label nCollapse = 0;
00218 forAll(f, fp)
00219 {
00220 if (pointCanBeDeleted[f[fp]])
00221 {
00222 nCollapse++;
00223 }
00224 }
00225
00226 if ((f.size() - nCollapse) < 3)
00227 {
00228
00229 forAll(f, fp)
00230 {
00231 if (pointCanBeDeleted[f[fp]])
00232 {
00233 pointCanBeDeleted[f[fp]] = false;
00234 --nCollapse;
00235 if (nCollapse == 0)
00236 {
00237 break;
00238 }
00239 }
00240 }
00241 }
00242 }
00243
00244
00245
00246 syncTools::syncPointList
00247 (
00248 mesh_,
00249 pointCanBeDeleted,
00250 andEqOp<bool>(),
00251 true,
00252 false
00253 );
00254
00255 return returnReduce(nDeleted, sumOp<label>());
00256 }
00257
00258
00259 void Foam::removePoints::setRefinement
00260 (
00261 const boolList& pointCanBeDeleted,
00262 polyTopoChange& meshMod
00263 )
00264 {
00265
00266 label nDeleted = 0;
00267 forAll(pointCanBeDeleted, pointI)
00268 {
00269 if (pointCanBeDeleted[pointI])
00270 {
00271 nDeleted++;
00272 }
00273 }
00274
00275
00276
00277 labelHashSet facesAffected(4*nDeleted);
00278
00279
00280
00281 Map<label> pointToSaved;
00282
00283
00284 if (undoable_)
00285 {
00286 savedPoints_.setSize(nDeleted);
00287 pointToSaved.resize(2*nDeleted);
00288 }
00289
00290
00291
00292
00293
00294 nDeleted = 0;
00295
00296 forAll(pointCanBeDeleted, pointI)
00297 {
00298 if (pointCanBeDeleted[pointI])
00299 {
00300 if (undoable_)
00301 {
00302 pointToSaved.insert(pointI, nDeleted);
00303 savedPoints_[nDeleted++] = mesh_.points()[pointI];
00304 }
00305 meshMod.setAction(polyRemovePoint(pointI));
00306
00307
00308 const labelList& pFaces = mesh_.pointFaces()[pointI];
00309
00310 forAll(pFaces, i)
00311 {
00312 facesAffected.insert(pFaces[i]);
00313 }
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323 if (undoable_)
00324 {
00325 savedFaceLabels_.setSize(facesAffected.size());
00326 savedFaces_.setSize(facesAffected.size());
00327 }
00328 label nSaved = 0;
00329
00330 forAllConstIter(labelHashSet, facesAffected, iter)
00331 {
00332 label faceI = iter.key();
00333
00334 const face& f = mesh_.faces()[faceI];
00335
00336 face newFace(f.size());
00337
00338 label newI = 0;
00339
00340 forAll(f, fp)
00341 {
00342 label pointI = f[fp];
00343
00344 if (!pointCanBeDeleted[pointI])
00345 {
00346 newFace[newI++] = pointI;
00347 }
00348 }
00349 newFace.setSize(newI);
00350
00351
00352 modifyFace(faceI, newFace, meshMod);
00353
00354
00355 if (undoable_)
00356 {
00357 savedFaceLabels_[nSaved] = faceI;
00358
00359 face& savedFace = savedFaces_[nSaved++];
00360 savedFace.setSize(f.size());
00361
00362 forAll(f, fp)
00363 {
00364 label pointI = f[fp];
00365
00366 if (pointCanBeDeleted[pointI])
00367 {
00368 savedFace[fp] = -pointToSaved[pointI]-1;
00369 }
00370 else
00371 {
00372 savedFace[fp] = pointI;
00373 }
00374 }
00375 }
00376 }
00377
00378 if (undoable_)
00379 {
00380
00381 if (debug)
00382 {
00383 forAll(savedFaceLabels_, saveI)
00384 {
00385
00386 List<point> meshPoints
00387 (
00388 UIndirectList<point>
00389 (
00390 mesh_.points(),
00391 mesh_.faces()[savedFaceLabels_[saveI]]
00392 )
00393 );
00394
00395
00396 List<point> keptPoints
00397 (
00398 BiIndirectList<point>
00399 (
00400 mesh_.points(),
00401 savedPoints_,
00402 savedFaces_[saveI]
00403 )
00404 );
00405
00406 if (meshPoints != keptPoints)
00407 {
00408 FatalErrorIn("setRefinement")
00409 << "faceI:" << savedFaceLabels_[saveI] << nl
00410 << "meshPoints:" << meshPoints << nl
00411 << "keptPoints:" << keptPoints << nl
00412 << abort(FatalError);
00413 }
00414 }
00415 }
00416 }
00417 }
00418
00419
00420 void Foam::removePoints::updateMesh(const mapPolyMesh& map)
00421 {
00422 if (undoable_)
00423 {
00424 forAll(savedFaceLabels_, localI)
00425 {
00426 if (savedFaceLabels_[localI] >= 0)
00427 {
00428 label newFaceI = map.reverseFaceMap()[savedFaceLabels_[localI]];
00429
00430 if (newFaceI == -1)
00431 {
00432 FatalErrorIn
00433 (
00434 "removePoints::updateMesh(const mapPolyMesh&)"
00435 ) << "Old face " << savedFaceLabels_[localI]
00436 << " seems to have dissapeared."
00437 << abort(FatalError);
00438 }
00439 savedFaceLabels_[localI] = newFaceI;
00440 }
00441 }
00442
00443
00444
00445
00446 forAll(savedFaces_, i)
00447 {
00448 face& f = savedFaces_[i];
00449
00450 forAll(f, fp)
00451 {
00452 label pointI = f[fp];
00453
00454 if (pointI >= 0)
00455 {
00456 f[fp] = map.reversePointMap()[pointI];
00457
00458 if (f[fp] == -1)
00459 {
00460 FatalErrorIn
00461 (
00462 "removePoints::updateMesh(const mapPolyMesh&)"
00463 ) << "Old point " << pointI
00464 << " seems to have dissapeared."
00465 << abort(FatalError);
00466 }
00467 }
00468 }
00469 }
00470
00471
00472
00473 if (debug)
00474 {
00475 forAll(savedFaceLabels_, saveI)
00476 {
00477 if (savedFaceLabels_[saveI] >= 0)
00478 {
00479 const face& f = mesh_.faces()[savedFaceLabels_[saveI]];
00480
00481
00482 const face& savedFace = savedFaces_[saveI];
00483
00484 face keptFace(savedFace.size());
00485 label keptFp = 0;
00486
00487 forAll(savedFace, fp)
00488 {
00489 label pointI = savedFace[fp];
00490
00491 if (pointI >= 0)
00492 {
00493 keptFace[keptFp++] = pointI;
00494 }
00495 }
00496 keptFace.setSize(keptFp);
00497
00498
00499
00500 if (keptFace != f)
00501 {
00502 FatalErrorIn("setRefinement")
00503 << "faceI:" << savedFaceLabels_[saveI] << nl
00504 << "face:" << f << nl
00505 << "keptFace:" << keptFace << nl
00506 << "saved points:"
00507 << BiIndirectList<point>
00508 (
00509 mesh_.points(),
00510 savedPoints_,
00511 savedFace
00512 )() << nl
00513 << abort(FatalError);
00514 }
00515 }
00516 }
00517 }
00518 }
00519 }
00520
00521
00522
00523
00524
00525 void Foam::removePoints::getUnrefimentSet
00526 (
00527 const labelList& undoFaces,
00528 labelList& localFaces,
00529 labelList& localPoints
00530 ) const
00531 {
00532 if (!undoable_)
00533 {
00534 FatalErrorIn
00535 (
00536 "removePoints::getUnrefimentSet(const labelList&"
00537 ", labelList&, labelList&) const"
00538 ) << "removePoints not constructed with"
00539 << " unrefinement capability."
00540 << abort(FatalError);
00541 }
00542
00543 if (debug)
00544 {
00545
00546 faceSet undoFacesSet(mesh_, "undoFacesSet", undoFaces);
00547 label sz = undoFacesSet.size();
00548
00549 undoFacesSet.sync(mesh_);
00550 if (sz != undoFacesSet.size())
00551 {
00552 FatalErrorIn
00553 (
00554 "removePoints::getUnrefimentSet(const labelList&"
00555 ", labelList&, labelList&) const"
00556 ) << "undoFaces not synchronised across coupled faces." << endl
00557 << "Size before sync:" << sz
00558 << " after sync:" << undoFacesSet.size()
00559 << abort(FatalError);
00560 }
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 labelHashSet localPointsSet(undoFaces.size());
00577
00578 {
00579
00580 labelHashSet undoFacesSet(undoFaces);
00581
00582 forAll(savedFaceLabels_, saveI)
00583 {
00584 if (savedFaceLabels_[saveI] < 0)
00585 {
00586 FatalErrorIn
00587 (
00588 "removePoints::getUnrefimentSet(const labelList&"
00589 ", labelList&, labelList&) const"
00590 ) << "Illegal face label " << savedFaceLabels_[saveI]
00591 << " at index " << saveI
00592 << abort(FatalError);
00593 }
00594
00595 if (undoFacesSet.found(savedFaceLabels_[saveI]))
00596 {
00597 const face& savedFace = savedFaces_[saveI];
00598
00599 forAll(savedFace, fp)
00600 {
00601 if (savedFace[fp] < 0)
00602 {
00603 label savedPointI = -savedFace[fp]-1;
00604
00605 if (savedPoints_[savedPointI] == wallPoint::greatPoint)
00606 {
00607 FatalErrorIn
00608 (
00609 "removePoints::getUnrefimentSet"
00610 "(const labelList&, labelList&, labelList&)"
00611 " const"
00612 ) << "Trying to restore point " << savedPointI
00613 << " from mesh face " << savedFaceLabels_[saveI]
00614 << " saved face:" << savedFace
00615 << " which has already been undone."
00616 << abort(FatalError);
00617 }
00618
00619 localPointsSet.insert(savedPointI);
00620 }
00621 }
00622 }
00623 }
00624
00625
00626
00627
00628
00629
00630 boolListList faceVertexRestore(mesh_.nFaces()-mesh_.nInternalFaces());
00631
00632
00633 forAll(savedFaces_, saveI)
00634 {
00635 label bFaceI = savedFaceLabels_[saveI] - mesh_.nInternalFaces();
00636
00637 if (bFaceI >= 0)
00638 {
00639 const face& savedFace = savedFaces_[saveI];
00640
00641 boolList& fRestore = faceVertexRestore[bFaceI];
00642
00643 fRestore.setSize(savedFace.size());
00644 fRestore = false;
00645
00646 forAll(savedFace, fp)
00647 {
00648 if (savedFace[fp] < 0)
00649 {
00650 label savedPointI = -savedFace[fp]-1;
00651
00652 if (localPointsSet.found(savedPointI))
00653 {
00654 fRestore[fp] = true;
00655 }
00656 }
00657 }
00658 }
00659 }
00660
00661 syncTools::syncBoundaryFaceList
00662 (
00663 mesh_,
00664 faceVertexRestore,
00665 faceEqOp<bool, orEqOp>(),
00666 false
00667 );
00668
00669
00670
00671
00672
00673
00674
00675 forAll(savedFaces_, saveI)
00676 {
00677 label bFaceI = savedFaceLabels_[saveI] - mesh_.nInternalFaces();
00678
00679 if (bFaceI >= 0)
00680 {
00681 const boolList& fRestore = faceVertexRestore[bFaceI];
00682
00683 const face& savedFace = savedFaces_[saveI];
00684
00685 forAll(fRestore, fp)
00686 {
00687
00688 if (fRestore[fp])
00689 {
00690 if (savedFace[fp] >= 0)
00691 {
00692 FatalErrorIn
00693 (
00694 "removePoints::getUnrefimentSet"
00695 "(const labelList&, labelList&, labelList&)"
00696 " const"
00697 ) << "Problem: on coupled face:"
00698 << savedFaceLabels_[saveI]
00699 << " fc:"
00700 << mesh_.faceCentres()[savedFaceLabels_[saveI]]
00701 << endl
00702 << " my neighbour tries to restore the vertex"
00703 << " at index " << fp
00704 << " whereas my saved face:" << savedFace
00705 << " does not indicate a deleted vertex"
00706 << " at that position."
00707 << abort(FatalError);
00708 }
00709
00710 label savedPointI = -savedFace[fp]-1;
00711
00712 localPointsSet.insert(savedPointI);
00713 }
00714 }
00715 }
00716 }
00717 }
00718
00719 localPoints = localPointsSet.toc();
00720
00721
00722
00723
00724
00725 labelHashSet localFacesSet(2*undoFaces.size());
00726
00727 forAll(savedFaces_, saveI)
00728 {
00729 const face& savedFace = savedFaces_[saveI];
00730
00731 forAll(savedFace, fp)
00732 {
00733 if (savedFace[fp] < 0)
00734 {
00735 label savedPointI = -savedFace[fp]-1;
00736
00737 if (localPointsSet.found(savedPointI))
00738 {
00739 localFacesSet.insert(saveI);
00740 }
00741 }
00742 }
00743 }
00744 localFaces = localFacesSet.toc();
00745
00746
00747
00748
00749
00750
00751 }
00752
00753
00754 void Foam::removePoints::setUnrefinement
00755 (
00756 const labelList& localFaces,
00757 const labelList& localPoints,
00758 polyTopoChange& meshMod
00759 )
00760 {
00761 if (!undoable_)
00762 {
00763 FatalErrorIn
00764 (
00765 "removePoints::setUnrefinement(const labelList&"
00766 ", labelList&, polyTopoChange&)"
00767 ) << "removePoints not constructed with"
00768 << " unrefinement capability."
00769 << abort(FatalError);
00770 }
00771
00772
00773
00774 labelList addedPoints(savedPoints_.size(), -1);
00775
00776 forAll(localPoints, i)
00777 {
00778 label localI = localPoints[i];
00779
00780 if (savedPoints_[localI] == wallPoint::greatPoint)
00781 {
00782 FatalErrorIn
00783 (
00784 "removePoints::setUnrefinement(const labelList&"
00785 ", labelList&, polyTopoChange&)"
00786 ) << "Saved point " << localI << " already restored!"
00787 << abort(FatalError);
00788 }
00789
00790 addedPoints[localI] = meshMod.setAction
00791 (
00792 polyAddPoint
00793 (
00794 savedPoints_[localI],
00795 -1,
00796 -1,
00797 true
00798 )
00799 );
00800
00801
00802 savedPoints_[localI] = wallPoint::greatPoint;
00803 }
00804
00805 forAll(localFaces, i)
00806 {
00807 label saveI = localFaces[i];
00808
00809
00810
00811 face& savedFace = savedFaces_[saveI];
00812
00813 face newFace(savedFace.size());
00814 label newFp = 0;
00815
00816 bool hasSavedPoints = false;
00817
00818 forAll(savedFace, fp)
00819 {
00820 if (savedFace[fp] < 0)
00821 {
00822 label addedPointI = addedPoints[-savedFace[fp]-1];
00823
00824 if (addedPointI != -1)
00825 {
00826 savedFace[fp] = addedPointI;
00827 newFace[newFp++] = addedPointI;
00828 }
00829 else
00830 {
00831 hasSavedPoints = true;
00832 }
00833 }
00834 else
00835 {
00836 newFace[newFp++] = savedFace[fp];
00837 }
00838 }
00839 newFace.setSize(newFp);
00840
00841 modifyFace(savedFaceLabels_[saveI], newFace, meshMod);
00842
00843 if (!hasSavedPoints)
00844 {
00845
00846 savedFaceLabels_[saveI] = -1;
00847 savedFaces_[saveI].clear();
00848 }
00849 }
00850
00851
00852
00853 label newSaveI = 0;
00854
00855 forAll(savedFaceLabels_, saveI)
00856 {
00857 if (savedFaceLabels_[saveI] != -1)
00858 {
00859 if (newSaveI != saveI)
00860 {
00861 savedFaceLabels_[newSaveI] = savedFaceLabels_[saveI];
00862 savedFaces_[newSaveI].transfer(savedFaces_[saveI]);
00863 }
00864 newSaveI++;
00865 }
00866 }
00867
00868 savedFaceLabels_.setSize(newSaveI);
00869 savedFaces_.setSize(newSaveI);
00870
00871
00872
00873 if (debug)
00874 {
00875 forAll(savedFaceLabels_, saveI)
00876 {
00877 const face& savedFace = savedFaces_[saveI];
00878
00879 forAll(savedFace, fp)
00880 {
00881 if (savedFace[fp] < 0)
00882 {
00883 label addedPointI = addedPoints[-savedFace[fp]-1];
00884
00885 if (addedPointI != -1)
00886 {
00887 FatalErrorIn("setUnrefinement")
00888 << "Face:" << savedFaceLabels_[saveI]
00889 << " savedVerts:" << savedFace
00890 << " uses restored point:" << -savedFace[fp]-1
00891 << " with new pointlabel:" << addedPointI
00892 << abort(FatalError);
00893 }
00894 }
00895 }
00896 }
00897 }
00898 }
00899
00900
00901